1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.directory.ldap.client.api.callback;
22
23
24 import java.io.IOException;
25 import java.text.MessageFormat;
26
27 import javax.security.auth.callback.Callback;
28 import javax.security.auth.callback.CallbackHandler;
29 import javax.security.auth.callback.NameCallback;
30 import javax.security.auth.callback.PasswordCallback;
31 import javax.security.auth.callback.UnsupportedCallbackException;
32 import javax.security.sasl.RealmCallback;
33 import javax.security.sasl.RealmChoiceCallback;
34
35 import org.apache.directory.api.util.Strings;
36 import org.apache.directory.ldap.client.api.SaslRequest;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46 public class SaslCallbackHandler implements CallbackHandler
47 {
48
49 private SaslRequest saslReq;
50
51
52 private static final Logger LOG = LoggerFactory.getLogger( SaslCallbackHandler.class );
53
54
55
56
57
58
59
60 public SaslCallbackHandler( SaslRequest saslReq )
61 {
62 this.saslReq = saslReq;
63 }
64
65
66
67
68
69 public void handle( Callback[] callbacks ) throws IOException, UnsupportedCallbackException
70 {
71 for ( Callback cb : callbacks )
72 {
73 if ( cb instanceof NameCallback )
74 {
75 NameCallback ncb = ( NameCallback ) cb;
76
77 String name = saslReq.getUsername();
78 LOG.debug( "sending name {} in the NameCallback", name );
79 ncb.setName( name );
80 }
81 else if ( cb instanceof PasswordCallback )
82 {
83 PasswordCallback pcb = ( PasswordCallback ) cb;
84
85 LOG.debug( "sending credentials in the PasswordCallback" );
86 pcb.setPassword( Strings.utf8ToString( saslReq.getCredentials() ).toCharArray() );
87 }
88 else if ( cb instanceof RealmCallback )
89 {
90 RealmCallback rcb = ( RealmCallback ) cb;
91
92 if ( saslReq.getRealmName() != null )
93 {
94 LOG.debug( "sending the user specified realm value {} in the RealmCallback", saslReq.getRealmName() );
95 rcb.setText( saslReq.getRealmName() );
96 }
97 else
98 {
99 LOG.debug(
100 "No user specified relam value, sending the default realm value {} in the RealmCallback",
101 rcb.getDefaultText() );
102 rcb.setText( rcb.getDefaultText() );
103 }
104 }
105 else if ( cb instanceof RealmChoiceCallback )
106 {
107 RealmChoiceCallback rccb = ( RealmChoiceCallback ) cb;
108
109 boolean foundRealmName = false;
110
111 String[] realmNames = rccb.getChoices();
112 for ( int i = 0; i < realmNames.length; i++ )
113 {
114 String realmName = realmNames[i];
115 if ( realmName.equals( saslReq.getRealmName() ) )
116 {
117 foundRealmName = true;
118
119 LOG.debug( "sending the user specified realm value {} in the RealmChoiceCallback", realmName );
120 rccb.setSelectedIndex( i );
121 break;
122 }
123 }
124
125 if ( !foundRealmName )
126 {
127 throw new IOException(
128 MessageFormat
129 .format(
130 "Cannot match ''java.naming.security.sasl.realm'' property value ''{0}'' with choices ''{1}'' in RealmChoiceCallback.",
131 saslReq.getRealmName(), getRealmNamesAsString( realmNames ) ) );
132 }
133 }
134 }
135 }
136
137
138
139
140
141
142
143
144 private String getRealmNamesAsString( String[] realmNames )
145 {
146 StringBuilder sb = new StringBuilder();
147
148 if ( ( realmNames != null ) && ( realmNames.length > 0 ) )
149 {
150 for ( String realmName : realmNames )
151 {
152 sb.append( realmName );
153 sb.append( ',' );
154 }
155 sb.deleteCharAt( sb.length() - 1 );
156 }
157
158 return sb.toString();
159 }
160 }