1 package org
.argeo
.util
.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 /** 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
;
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();
30 String expectedAuthScheme
= getExpectedAuthScheme();
31 if (expectedAuthScheme
!= null && !authScheme
.equals(expectedAuthScheme
))
32 throw new IllegalArgumentException(
33 "Auth scheme " + authScheme
+ " is not compatible with " + expectedAuthScheme
);
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
;
44 protected AuthPassword(AuthPassword authPassword
) {
45 this.authScheme
= authPassword
.getAuthScheme();
46 this.authInfo
= authPassword
.getAuthInfo();
47 this.authValue
= authPassword
.getAuthValue();
50 protected String
getExpectedAuthScheme() {
54 protected boolean matchAuthValue(Object object
) {
55 return authValue
.equals(object
.toString());
59 public boolean equals(Object obj
) {
60 if (!(obj
instanceof AuthPassword
))
62 AuthPassword authPassword
= (AuthPassword
) obj
;
63 return authScheme
.equals(authPassword
.authScheme
) && authInfo
.equals(authPassword
.authInfo
)
64 && authValue
.equals(authValue
);
67 public boolean keyEquals(AuthPassword authPassword
) {
68 return authScheme
.equals(authPassword
.authScheme
) && authInfo
.equals(authPassword
.authInfo
);
72 public int hashCode() {
73 return authValue
.hashCode();
77 public String
toString() {
78 return toAuthPassword();
81 public final String
toAuthPassword() {
82 return getAuthScheme() + '$' + authInfo
+ '$' + authValue
;
85 public String
getAuthScheme() {
89 public String
getAuthInfo() {
93 public String
getAuthValue() {
97 public static AuthPassword
matchAuthValue(Attributes attributes
, char[] value
) {
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());
106 if (Arrays
.binarySearch(value
, '$') >= 0) {
107 auth
= token
.authInfo
+ '$' + token
.authValue
;
109 auth
= token
.authValue
;
111 if (Arrays
.equals(auth
.toCharArray(), value
))
113 // if (token.matchAuthValue(value))
118 } catch (NamingException e
) {
119 throw new IllegalStateException("Cannot check attribute", e
);
123 public static boolean remove(Attributes attributes
, AuthPassword value
) {
124 Attribute authPassword
= attributes
.get(LdapAttrs
.authPassword
.name());
125 return authPassword
.remove(value
.toAuthPassword());
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());