+
+ // 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<String, List<String>> 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);
+ }
+ }
+ }
+