]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/naming/AuthPassword.java
d8792729f3a4248455a00b1b736f7cf5d88d5684
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / naming / AuthPassword.java
1 package org.argeo.util.naming;
2
3 import java.io.IOException;
4 import java.util.Arrays;
5 import java.util.StringTokenizer;
6
7 import javax.naming.NamingEnumeration;
8 import javax.naming.NamingException;
9 import javax.naming.directory.Attribute;
10 import javax.naming.directory.Attributes;
11 import javax.security.auth.callback.Callback;
12 import javax.security.auth.callback.CallbackHandler;
13 import javax.security.auth.callback.NameCallback;
14 import javax.security.auth.callback.PasswordCallback;
15 import javax.security.auth.callback.UnsupportedCallbackException;
16
17 /** LDAP authPassword field according to RFC 3112 */
18 public class AuthPassword implements CallbackHandler {
19 private final String authScheme;
20 private final String authInfo;
21 private final String authValue;
22
23 public AuthPassword(String value) {
24 StringTokenizer st = new StringTokenizer(value, "$");
25 // TODO make it more robust, deal with bad formatting
26 this.authScheme = st.nextToken().trim();
27 this.authInfo = st.nextToken().trim();
28 this.authValue = st.nextToken().trim();
29
30 String expectedAuthScheme = getExpectedAuthScheme();
31 if (expectedAuthScheme != null && !authScheme.equals(expectedAuthScheme))
32 throw new IllegalArgumentException(
33 "Auth scheme " + authScheme + " is not compatible with " + expectedAuthScheme);
34 }
35
36 protected AuthPassword(String authInfo, String authValue) {
37 this.authScheme = getExpectedAuthScheme();
38 if (authScheme == null)
39 throw new IllegalArgumentException("Expected auth scheme cannot be null");
40 this.authInfo = authInfo;
41 this.authValue = authValue;
42 }
43
44 protected AuthPassword(AuthPassword authPassword) {
45 this.authScheme = authPassword.getAuthScheme();
46 this.authInfo = authPassword.getAuthInfo();
47 this.authValue = authPassword.getAuthValue();
48 }
49
50 protected String getExpectedAuthScheme() {
51 return null;
52 }
53
54 protected boolean matchAuthValue(Object object) {
55 return authValue.equals(object.toString());
56 }
57
58 @Override
59 public boolean equals(Object obj) {
60 if (!(obj instanceof AuthPassword))
61 return false;
62 AuthPassword authPassword = (AuthPassword) obj;
63 return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo)
64 && authValue.equals(authValue);
65 }
66
67 public boolean keyEquals(AuthPassword authPassword) {
68 return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo);
69 }
70
71 @Override
72 public int hashCode() {
73 return authValue.hashCode();
74 }
75
76 @Override
77 public String toString() {
78 return toAuthPassword();
79 }
80
81 public final String toAuthPassword() {
82 return getAuthScheme() + '$' + authInfo + '$' + authValue;
83 }
84
85 public String getAuthScheme() {
86 return authScheme;
87 }
88
89 public String getAuthInfo() {
90 return authInfo;
91 }
92
93 public String getAuthValue() {
94 return authValue;
95 }
96
97 public static AuthPassword matchAuthValue(Attributes attributes, char[] value) {
98 try {
99 Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
100 if (authPassword != null) {
101 NamingEnumeration<?> values = authPassword.getAll();
102 while (values.hasMore()) {
103 Object val = values.next();
104 AuthPassword token = new AuthPassword(val.toString());
105 String auth;
106 if (Arrays.binarySearch(value, '$') >= 0) {
107 auth = token.authInfo + '$' + token.authValue;
108 } else {
109 auth = token.authValue;
110 }
111 if (Arrays.equals(auth.toCharArray(), value))
112 return token;
113 // if (token.matchAuthValue(value))
114 // return token;
115 }
116 }
117 return null;
118 } catch (NamingException e) {
119 throw new IllegalStateException("Cannot check attribute", e);
120 }
121 }
122
123 public static boolean remove(Attributes attributes, AuthPassword value) {
124 Attribute authPassword = attributes.get(LdapAttrs.authPassword.name());
125 return authPassword.remove(value.toAuthPassword());
126 }
127
128 @Override
129 public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
130 for (Callback callback : callbacks) {
131 if (callback instanceof NameCallback)
132 ((NameCallback) callback).setName(toAuthPassword());
133 else if (callback instanceof PasswordCallback)
134 ((PasswordCallback) callback).setPassword(getAuthValue().toCharArray());
135 }
136 }
137
138 }