This project has retired. For details please refer to its
Attic page.
SaslNettyClient xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.giraph.comm.netty;
20
21 import org.apache.giraph.comm.requests.SaslTokenMessageRequest;
22 import org.apache.hadoop.conf.Configuration;
23 import org.apache.hadoop.mapred.JobConf;
24 import org.apache.hadoop.mapreduce.security.TokenCache;
25 import org.apache.hadoop.mapreduce.security.token.JobTokenIdentifier;
26 import org.apache.hadoop.security.Credentials;
27
28 import org.apache.hadoop.security.SaslPropertiesResolver;
29
30 import org.apache.hadoop.security.SaslRpcServer;
31 import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
32 import org.apache.hadoop.security.token.Token;
33 import org.apache.hadoop.security.token.TokenIdentifier;
34 import org.apache.hadoop.security.UserGroupInformation;
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.RealmCallback;
43 import javax.security.sasl.RealmChoiceCallback;
44 import javax.security.sasl.Sasl;
45 import javax.security.sasl.SaslClient;
46 import javax.security.sasl.SaslException;
47 import java.io.IOException;
48
49
50
51
52 public class SaslNettyClient {
53
54 public static final Logger LOG = Logger.getLogger(SaslNettyClient.class);
55
56
57
58
59
60 private Object authenticated = new Object();
61
62
63
64
65
66 private SaslClient saslClient;
67
68
69
70
71 public SaslNettyClient() {
72 try {
73 Token<? extends TokenIdentifier> token =
74 createJobToken(new Configuration());
75 if (LOG.isDebugEnabled()) {
76 LOG.debug("SaslNettyClient: Creating SASL " +
77 AuthMethod.DIGEST.getMechanismName() +
78 " client to authenticate to service at " + token.getService());
79 }
80
81
82
83
84
85
86
87 SaslPropertiesResolver saslPropsResolver =
88 SaslPropertiesResolver.getInstance(new Configuration());
89 saslClient =
90 Sasl.createSaslClient(
91 new String[] { AuthMethod.DIGEST.getMechanismName() }, null,
92 null, SaslRpcServer.SASL_DEFAULT_REALM,
93 saslPropsResolver.getDefaultProperties(),
94 new SaslClientCallbackHandler(token));
95
96 } catch (IOException e) {
97 LOG.error("SaslNettyClient: Could not obtain job token for Netty " +
98 "Client to use to authenticate with a Netty Server.");
99 saslClient = null;
100 }
101 }
102
103 public Object getAuthenticated() {
104 return authenticated;
105 }
106
107
108
109
110
111
112
113
114
115 private Token<JobTokenIdentifier> createJobToken(Configuration conf)
116 throws IOException {
117 String localJobTokenFile = System.getenv().get(
118 UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION);
119 if (localJobTokenFile != null) {
120 JobConf jobConf = new JobConf(conf);
121 Credentials credentials =
122 TokenCache.loadTokens(localJobTokenFile, jobConf);
123 return TokenCache.getJobToken(credentials);
124 } else {
125 throw new IOException("createJobToken: Cannot obtain authentication " +
126 "credentials for job: file: '" +
127 UserGroupInformation.HADOOP_TOKEN_FILE_LOCATION + "' not found");
128 }
129 }
130
131
132
133
134
135
136 public SaslTokenMessageRequest firstToken()
137 throws IOException {
138 byte[] saslToken = new byte[0];
139 if (saslClient.hasInitialResponse()) {
140 saslToken = saslClient.evaluateChallenge(saslToken);
141 }
142 SaslTokenMessageRequest saslTokenMessage =
143 new SaslTokenMessageRequest();
144 saslTokenMessage.setSaslToken(saslToken);
145 return saslTokenMessage;
146 }
147
148 public boolean isComplete() {
149 return saslClient.isComplete();
150 }
151
152
153
154
155
156
157 public byte[] saslResponse(SaslTokenMessageRequest saslTokenMessage) {
158 try {
159 byte[] retval =
160 saslClient.evaluateChallenge(saslTokenMessage.getSaslToken());
161 return retval;
162 } catch (SaslException e) {
163 LOG.error("saslResponse: Failed to respond to SASL server's token:", e);
164 return null;
165 }
166 }
167
168
169
170
171
172 private static class SaslClientCallbackHandler implements CallbackHandler {
173
174 private final String userName;
175
176 private final char[] userPassword;
177
178
179
180
181
182 public SaslClientCallbackHandler(Token<? extends TokenIdentifier> token) {
183 this.userName = SaslNettyServer.encodeIdentifier(token.getIdentifier());
184 this.userPassword = SaslNettyServer.encodePassword(token.getPassword());
185 }
186
187
188
189
190
191
192
193
194 public void handle(Callback[] callbacks)
195 throws UnsupportedCallbackException {
196 NameCallback nc = null;
197 PasswordCallback pc = null;
198 RealmCallback rc = null;
199 for (Callback callback : callbacks) {
200 if (callback instanceof RealmChoiceCallback) {
201 continue;
202 } else if (callback instanceof NameCallback) {
203 nc = (NameCallback) callback;
204 } else if (callback instanceof PasswordCallback) {
205 pc = (PasswordCallback) callback;
206 } else if (callback instanceof RealmCallback) {
207 rc = (RealmCallback) callback;
208 } else {
209 throw new UnsupportedCallbackException(callback,
210 "handle: Unrecognized SASL client callback");
211 }
212 }
213 if (nc != null) {
214 if (LOG.isDebugEnabled()) {
215 LOG.debug("handle: SASL client callback: setting username: " +
216 userName);
217 }
218 nc.setName(userName);
219 }
220 if (pc != null) {
221 if (LOG.isDebugEnabled()) {
222 LOG.debug("handle: SASL client callback: setting userPassword");
223 }
224 pc.setPassword(userPassword);
225 }
226 if (rc != null) {
227 if (LOG.isDebugEnabled()) {
228 LOG.debug("handle: SASL client callback: setting realm: " +
229 rc.getDefaultText());
230 }
231 rc.setText(rc.getDefaultText());
232 }
233 }
234 }
235 }