X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.enterprise%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fuseradmin%2FLdifUser.java;h=90b8daa0eff0603c3f50e1398586a505e9dee192;hb=2111a76162534100967eb0e7733632e80d9ddc5f;hp=4eab8cd87023a0cd5b3f791979af0b1e70ef52ce;hpb=9c1e0062044a1dcf34d34c7cda840334e56a289c;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUser.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUser.java index 4eab8cd87..90b8daa0e 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUser.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUser.java @@ -1,11 +1,8 @@ package org.argeo.osgi.useradmin; -import java.net.URI; -import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.StandardCharsets; -import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -15,9 +12,7 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.StringTokenizer; import javax.naming.NamingEnumeration; import javax.naming.NamingException; @@ -26,8 +21,9 @@ import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.ldap.LdapName; +import org.argeo.naming.AuthPassword; import org.argeo.naming.LdapAttrs; -import org.argeo.naming.NamingUtils; +import org.argeo.naming.SharedSecret; /** Directory user implementation */ class LdifUser implements DirectoryUser { @@ -78,47 +74,73 @@ class LdifUser implements DirectoryUser { public boolean hasCredential(String key, Object value) { if (key == null) { // TODO check other sources (like PKCS12) - String pwd = new String((char[]) value); + // String pwd = new String((char[]) value); + // authPassword (RFC 312 https://tools.ietf.org/html/rfc3112) char[] password = toChars(value); + AuthPassword authPassword = AuthPassword.matchAuthValue(getAttributes(), password); + if (authPassword != null) { + if (authPassword.getAuthScheme().equals(SharedSecret.X_SHARED_SECRET)) { + SharedSecret onceToken = new SharedSecret(authPassword); + if (onceToken.isExpired()) { + // AuthPassword.remove(getAttributes(), onceToken); + return false; + } else { + // boolean wasRemoved = AuthPassword.remove(getAttributes(), onceToken); + return true; + } + // TODO delete expired tokens? + } else { + // TODO implement SHA + throw new UnsupportedOperationException( + "Unsupported authPassword scheme " + authPassword.getAuthScheme()); + } + } + + // Regular password byte[] hashedPassword = hash(password); if (hasCredential(LdapAttrs.userPassword.name(), hashedPassword)) return true; - if (hasCredential(LdapAttrs.authPassword.name(), pwd)) - return true; + // if (hasCredential(LdapAttrs.authPassword.name(), pwd)) + // return true; return false; } - Object storedValue = getCredentials().get(key); - - // authPassword (RFC 312 https://tools.ietf.org/html/rfc3112) - if (LdapAttrs.authPassword.name().equals(key)) { - StringTokenizer st = new StringTokenizer((String) storedValue, "$ "); - // TODO make it more robust, deal with bad formatting - String authScheme = st.nextToken(); - String authInfo = st.nextToken(); - String authValue = st.nextToken(); - if (authScheme.equals("X-Node-Token")) { - try { - URI uri = new URI(authInfo); - Map> query = NamingUtils.queryToMap(uri); - String expiryTimestamp = NamingUtils.getQueryValue(query, LdapAttrs.modifyTimestamp.name()); - if (expiryTimestamp != null) { - Instant expiryOdt = NamingUtils.ldapDateToInstant(expiryTimestamp); - if (expiryOdt.isBefore(Instant.now())) - return false; - } else { - throw new UnsupportedOperationException("An expiry timestamp " - + LdapAttrs.modifyTimestamp.name() + " must be set in the URI query"); - } - byte[] hash = Base64.getDecoder().decode(authValue); - byte[] hashedInput = DigestUtils.sha1((authInfo + value).getBytes(StandardCharsets.US_ASCII)); - return Arrays.equals(hash, hashedInput); - } catch (URISyntaxException e) { - throw new UserDirectoryException("Badly formatted " + authInfo, e); - } - } - } + // authPassword (RFC 3112 https://tools.ietf.org/html/rfc3112) + // if (key.startsWith(ClientToken.X_CLIENT_TOKEN)) { + // return ClientToken.checkAttribute(getAttributes(), key, value); + // } else if (key.startsWith(OnceToken.X_ONCE_TOKEN)) { + // return OnceToken.checkAttribute(getAttributes(), key, value); + // } + // StringTokenizer st = new StringTokenizer((String) storedValue, "$ "); + // // TODO make it more robust, deal with bad formatting + // String authScheme = st.nextToken(); + // String authInfo = st.nextToken(); + // String authValue = st.nextToken(); + // if (authScheme.equals(UriToken.X_URI_TOKEN)) { + // UriToken token = new UriToken((String)storedValue); + // try { + // URI uri = new URI(authInfo); + // Map> query = NamingUtils.queryToMap(uri); + // String expiryTimestamp = NamingUtils.getQueryValue(query, + // LdapAttrs.modifyTimestamp.name()); + // if (expiryTimestamp != null) { + // Instant expiryOdt = NamingUtils.ldapDateToInstant(expiryTimestamp); + // if (expiryOdt.isBefore(Instant.now())) + // return false; + // } else { + // throw new UnsupportedOperationException("An expiry timestamp " + // + LdapAttrs.modifyTimestamp.name() + " must be set in the URI query"); + // } + // byte[] hash = Base64.getDecoder().decode(authValue); + // byte[] hashedInput = DigestUtils.sha1((authInfo + + // value).getBytes(StandardCharsets.US_ASCII)); + // return Arrays.equals(hash, hashedInput); + // } catch (URISyntaxException e) { + // throw new UserDirectoryException("Badly formatted " + authInfo, e); + // } + // } + Object storedValue = getCredentials().get(key); if (storedValue == null || value == null) return false; if (!(value instanceof String || value instanceof byte[])) @@ -328,6 +350,9 @@ class LdifUser implements DirectoryUser { byte[] hashedPassword = hash(password); return put(LdapAttrs.userPassword.name(), hashedPassword); } + if (key.startsWith("X-")) { + return put(LdapAttrs.authPassword.name(), value); + } userAdmin.checkEdit(); if (!isEditing()) @@ -343,7 +368,8 @@ class LdifUser implements DirectoryUser { try { Attribute attribute = getModifiedAttributes().get(key.toString()); - attribute = new BasicAttribute(key.toString()); + if (attribute == null) + attribute = new BasicAttribute(key.toString()); if (value instanceof String && !isAsciiPrintable(((String) value))) attribute.add(((String) value).getBytes(StandardCharsets.UTF_8)); else