This project has retired. For details please refer to its
Attic page.
SaslNettyServer xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.giraph.comm.netty;
19
20 import org.apache.commons.net.util.Base64;
21 import org.apache.hadoop.classification.InterfaceStability;
22
23 import org.apache.hadoop.conf.Configuration;
24
25
26
27 import org.apache.hadoop.ipc.StandbyException;
28
29 import org.apache.hadoop.mapreduce.security.token.JobTokenIdentifier;
30 import org.apache.hadoop.mapreduce.security.token.JobTokenSecretManager;
31
32 import org.apache.hadoop.security.SaslPropertiesResolver;
33
34 import org.apache.hadoop.security.SaslRpcServer;
35 import org.apache.log4j.Logger;
36
37 import javax.security.auth.callback.Callback;
38 import javax.security.auth.callback.CallbackHandler;
39 import javax.security.auth.callback.NameCallback;
40 import javax.security.auth.callback.PasswordCallback;
41 import javax.security.auth.callback.UnsupportedCallbackException;
42 import javax.security.sasl.AuthorizeCallback;
43 import javax.security.sasl.RealmCallback;
44 import javax.security.sasl.Sasl;
45 import javax.security.sasl.SaslException;
46 import javax.security.sasl.SaslServer;
47 import java.io.IOException;
48 import java.nio.charset.Charset;
49 import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
50
51
52
53
54 public class SaslNettyServer extends SaslRpcServer {
55
56 public static final Logger LOG = Logger.getLogger(SaslNettyServer.class);
57
58
59
60
61
62 private SaslServer saslServer;
63
64
65
66
67
68
69 public SaslNettyServer(JobTokenSecretManager secretManager)
70 throws IOException {
71 this(secretManager, AuthMethod.SIMPLE);
72 }
73
74
75
76
77
78
79
80 public SaslNettyServer(JobTokenSecretManager secretManager,
81 AuthMethod authMethod) throws IOException {
82
83
84 super(authMethod);
85
86 if (LOG.isDebugEnabled()) {
87 LOG.debug("SaslNettyServer: Secret manager is: " + secretManager +
88 " with authmethod " + authMethod);
89 }
90
91
92 try {
93 secretManager.checkAvailableForRead();
94 } catch (StandbyException e) {
95 LOG.error("SaslNettyServer: Could not read secret manager: " + e);
96 }
97
98 try {
99 SaslDigestCallbackHandler ch =
100 new SaslNettyServer.SaslDigestCallbackHandler(secretManager);
101
102
103
104
105
106
107 SaslPropertiesResolver saslPropsResolver =
108 SaslPropertiesResolver.getInstance(new Configuration());
109 saslServer =
110 Sasl.createSaslServer(
111 SaslNettyServer.AuthMethod.DIGEST.getMechanismName(), null,
112 SaslRpcServer.SASL_DEFAULT_REALM,
113 saslPropsResolver.getDefaultProperties(), ch);
114
115 } catch (SaslException e) {
116 LOG.error("SaslNettyServer: Could not create SaslServer: " + e);
117 }
118 }
119
120 public boolean isComplete() {
121 return saslServer.isComplete();
122 }
123
124 public String getUserName() {
125 return saslServer.getAuthorizationID();
126 }
127
128
129
130
131
132
133
134 public byte[] response(byte[] token) {
135 try {
136 if (LOG.isDebugEnabled()) {
137 LOG.debug("response: Responding to input token of length: " +
138 token.length);
139 }
140 byte[] retval = saslServer.evaluateResponse(token);
141 if (LOG.isDebugEnabled()) {
142 LOG.debug("response: Response token length: " + retval.length);
143 }
144 return retval;
145 } catch (SaslException e) {
146 LOG.error("response: Failed to evaluate client token of length: " +
147 token.length + " : " + e);
148 return null;
149 }
150 }
151
152
153
154
155
156
157
158 static String encodeIdentifier(byte[] identifier) {
159 return new String(Base64.encodeBase64(identifier),
160 Charset.defaultCharset());
161 }
162
163
164
165
166
167
168 static char[] encodePassword(byte[] password) {
169 return new String(Base64.encodeBase64(password),
170 Charset.defaultCharset()).toCharArray();
171 }
172
173
174 @InterfaceStability.Evolving
175 public static class SaslDigestCallbackHandler implements CallbackHandler {
176
177 private JobTokenSecretManager secretManager;
178
179
180
181
182
183
184 public SaslDigestCallbackHandler(
185 JobTokenSecretManager secretManager) {
186 if (LOG.isDebugEnabled()) {
187 LOG.debug("SaslDigestCallback: Creating SaslDigestCallback handler " +
188 "with secret manager: " + secretManager);
189 }
190 this.secretManager = secretManager;
191 }
192
193
194 @Override
195 public void handle(Callback[] callbacks) throws IOException,
196 UnsupportedCallbackException {
197 NameCallback nc = null;
198 PasswordCallback pc = null;
199 AuthorizeCallback ac = null;
200 for (Callback callback : callbacks) {
201 if (callback instanceof AuthorizeCallback) {
202 ac = (AuthorizeCallback) callback;
203 } else if (callback instanceof NameCallback) {
204 nc = (NameCallback) callback;
205 } else if (callback instanceof PasswordCallback) {
206 pc = (PasswordCallback) callback;
207 } else if (callback instanceof RealmCallback) {
208 continue;
209 } else {
210 throw new UnsupportedCallbackException(callback,
211 "handle: Unrecognized SASL DIGEST-MD5 Callback");
212 }
213 }
214 if (pc != null) {
215 JobTokenIdentifier tokenIdentifier = getIdentifier(nc.getDefaultName(),
216 secretManager);
217 char[] password =
218 encodePassword(secretManager.retrievePassword(tokenIdentifier));
219
220 if (LOG.isDebugEnabled()) {
221 LOG.debug("handle: SASL server DIGEST-MD5 callback: setting " +
222 "password for client: " + tokenIdentifier.getUser());
223 }
224 pc.setPassword(password);
225 }
226 if (ac != null) {
227 String authid = ac.getAuthenticationID();
228 String authzid = ac.getAuthorizationID();
229 if (authid.equals(authzid)) {
230 ac.setAuthorized(true);
231 } else {
232 ac.setAuthorized(false);
233 }
234 if (ac.isAuthorized()) {
235 if (LOG.isDebugEnabled()) {
236 String username =
237 getIdentifier(authzid, secretManager).getUser().getUserName();
238 if (LOG.isDebugEnabled()) {
239 LOG.debug("handle: SASL server DIGEST-MD5 callback: setting " +
240 "canonicalized client ID: " + username);
241 }
242 }
243 ac.setAuthorizedID(authzid);
244 }
245 }
246 }
247 }
248 }