1 package org
.argeo
.naming
;
3 import java
.io
.IOException
;
4 import java
.util
.Arrays
;
5 import java
.util
.StringTokenizer
;
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
;
17 import org
.argeo
.osgi
.useradmin
.UserDirectoryException
;
19 /** LDAP authPassword field according to RFC 3112 */
20 public class AuthPassword
implements CallbackHandler
{
21 private final String authScheme
;
22 private final String authInfo
;
23 private final String authValue
;
25 public AuthPassword(String value
) {
26 StringTokenizer st
= new StringTokenizer(value
, "$");
27 // TODO make it more robust, deal with bad formatting
28 this.authScheme
= st
.nextToken().trim();
29 this.authInfo
= st
.nextToken().trim();
30 this.authValue
= st
.nextToken().trim();
32 String expectedAuthScheme
= getExpectedAuthScheme();
33 if (expectedAuthScheme
!= null && !authScheme
.equals(expectedAuthScheme
))
34 throw new IllegalArgumentException(
35 "Auth scheme " + authScheme
+ " is not compatible with " + expectedAuthScheme
);
38 protected AuthPassword(String authInfo
, String authValue
) {
39 this.authScheme
= getExpectedAuthScheme();
40 if (authScheme
== null)
41 throw new IllegalArgumentException("Expected auth scheme cannot be null");
42 this.authInfo
= authInfo
;
43 this.authValue
= authValue
;
46 protected AuthPassword(AuthPassword authPassword
) {
47 this.authScheme
= authPassword
.getAuthScheme();
48 this.authInfo
= authPassword
.getAuthInfo();
49 this.authValue
= authPassword
.getAuthValue();
52 protected String
getExpectedAuthScheme() {
56 protected boolean matchAuthValue(Object object
) {
57 return authValue
.equals(object
.toString());
61 public boolean equals(Object obj
) {
62 if (!(obj
instanceof AuthPassword
))
64 AuthPassword authPassword
= (AuthPassword
) obj
;
65 return authScheme
.equals(authPassword
.authScheme
) && authInfo
.equals(authPassword
.authInfo
)
66 && authValue
.equals(authValue
);
69 public boolean keyEquals(AuthPassword authPassword
) {
70 return authScheme
.equals(authPassword
.authScheme
) && authInfo
.equals(authPassword
.authInfo
);
74 public int hashCode() {
75 return authValue
.hashCode();
79 public String
toString() {
80 return toAuthPassword();
83 public final String
toAuthPassword() {
84 return getAuthScheme() + '$' + authInfo
+ '$' + authValue
;
87 public String
getAuthScheme() {
91 public String
getAuthInfo() {
95 public String
getAuthValue() {
99 public static AuthPassword
matchAuthValue(Attributes attributes
, char[] value
) {
101 Attribute authPassword
= attributes
.get(LdapAttrs
.authPassword
.name());
102 if (authPassword
!= null) {
103 NamingEnumeration
<?
> values
= authPassword
.getAll();
104 while (values
.hasMore()) {
105 Object val
= values
.next();
106 AuthPassword token
= new AuthPassword(val
.toString());
108 if (Arrays
.binarySearch(value
, '$') >= 0) {
109 auth
= token
.authInfo
+ '$' + token
.authValue
;
111 auth
= token
.authValue
;
113 if (Arrays
.equals(auth
.toCharArray(), value
))
115 // if (token.matchAuthValue(value))
120 } catch (NamingException e
) {
121 throw new UserDirectoryException("Cannot check attribute", e
);
125 public static boolean remove(Attributes attributes
, AuthPassword value
) {
126 Attribute authPassword
= attributes
.get(LdapAttrs
.authPassword
.name());
127 return authPassword
.remove(value
.toAuthPassword());
131 public void handle(Callback
[] callbacks
) throws IOException
, UnsupportedCallbackException
{
132 for (Callback callback
: callbacks
) {
133 if (callback
instanceof NameCallback
)
134 ((NameCallback
) callback
).setName(toAuthPassword());
135 else if (callback
instanceof PasswordCallback
)
136 ((PasswordCallback
) callback
).setPassword(getAuthValue().toCharArray());