use of org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto in project hadoop by apache.
the class SaslRpcClient method saslConnect.
/**
* Do client side SASL authentication with server via the given InputStream
* and OutputStream
*
* @param inS
* InputStream to use
* @param outS
* OutputStream to use
* @return AuthMethod used to negotiate the connection
* @throws IOException
*/
public AuthMethod saslConnect(IpcStreams ipcStreams) throws IOException {
// redefined if/when a SASL negotiation starts, can be queried if the
// negotiation fails
authMethod = AuthMethod.SIMPLE;
sendSaslMessage(ipcStreams.out, negotiateRequest);
// loop until sasl is complete or a rpc error occurs
boolean done = false;
do {
ByteBuffer bb = ipcStreams.readResponse();
RpcWritable.Buffer saslPacket = RpcWritable.Buffer.wrap(bb);
RpcResponseHeaderProto header = saslPacket.getValue(RpcResponseHeaderProto.getDefaultInstance());
switch(header.getStatus()) {
// might get a RPC error during
case ERROR:
case FATAL:
throw new RemoteException(header.getExceptionClassName(), header.getErrorMsg());
default:
break;
}
if (header.getCallId() != AuthProtocol.SASL.callId) {
throw new SaslException("Non-SASL response during negotiation");
}
RpcSaslProto saslMessage = saslPacket.getValue(RpcSaslProto.getDefaultInstance());
if (saslPacket.remaining() > 0) {
throw new SaslException("Received malformed response length");
}
// handle sasl negotiation process
RpcSaslProto.Builder response = null;
switch(saslMessage.getState()) {
case NEGOTIATE:
{
// create a compatible SASL client, throws if no supported auths
SaslAuth saslAuthType = selectSaslClient(saslMessage.getAuthsList());
// define auth being attempted, caller can query if connect fails
authMethod = AuthMethod.valueOf(saslAuthType.getMethod());
byte[] responseToken = null;
if (authMethod == AuthMethod.SIMPLE) {
// switching to SIMPLE
// not going to wait for success ack
done = true;
} else {
byte[] challengeToken = null;
if (saslAuthType.hasChallenge()) {
// server provided the first challenge
challengeToken = saslAuthType.getChallenge().toByteArray();
saslAuthType = SaslAuth.newBuilder(saslAuthType).clearChallenge().build();
} else if (saslClient.hasInitialResponse()) {
challengeToken = new byte[0];
}
responseToken = (challengeToken != null) ? saslClient.evaluateChallenge(challengeToken) : new byte[0];
}
response = createSaslReply(SaslState.INITIATE, responseToken);
response.addAuths(saslAuthType);
break;
}
case CHALLENGE:
{
if (saslClient == null) {
// demand a specific negotiation
throw new SaslException("Server sent unsolicited challenge");
}
byte[] responseToken = saslEvaluateToken(saslMessage, false);
response = createSaslReply(SaslState.RESPONSE, responseToken);
break;
}
case SUCCESS:
{
// switch to simple
if (saslClient == null) {
authMethod = AuthMethod.SIMPLE;
} else {
saslEvaluateToken(saslMessage, true);
}
done = true;
break;
}
default:
{
throw new SaslException("RPC client doesn't support SASL " + saslMessage.getState());
}
}
if (response != null) {
sendSaslMessage(ipcStreams.out, response.build());
}
} while (!done);
return authMethod;
}
use of org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto in project hadoop by apache.
the class Server method buildNegotiateResponse.
private RpcSaslProto buildNegotiateResponse(List<AuthMethod> authMethods) throws IOException {
RpcSaslProto.Builder negotiateBuilder = RpcSaslProto.newBuilder();
if (authMethods.contains(AuthMethod.SIMPLE) && authMethods.size() == 1) {
// SIMPLE-only servers return success in response to negotiate
negotiateBuilder.setState(SaslState.SUCCESS);
} else {
negotiateBuilder.setState(SaslState.NEGOTIATE);
for (AuthMethod authMethod : authMethods) {
SaslRpcServer saslRpcServer = new SaslRpcServer(authMethod);
SaslAuth.Builder builder = negotiateBuilder.addAuthsBuilder().setMethod(authMethod.toString()).setMechanism(saslRpcServer.mechanism);
if (saslRpcServer.protocol != null) {
builder.setProtocol(saslRpcServer.protocol);
}
if (saslRpcServer.serverId != null) {
builder.setServerId(saslRpcServer.serverId);
}
}
}
return negotiateBuilder.build();
}
use of org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto in project hadoop by apache.
the class Server method wrapWithSasl.
private void wrapWithSasl(RpcCall call) throws IOException {
if (call.connection.saslServer != null) {
byte[] token = call.rpcResponse.array();
// threads using saslServer to wrap responses.
synchronized (call.connection.saslServer) {
token = call.connection.saslServer.wrap(token, 0, token.length);
}
if (LOG.isDebugEnabled())
LOG.debug("Adding saslServer wrapped token of size " + token.length + " as call response.");
// rebuild with sasl header and payload
RpcResponseHeaderProto saslHeader = RpcResponseHeaderProto.newBuilder().setCallId(AuthProtocol.SASL.callId).setStatus(RpcStatusProto.SUCCESS).build();
RpcSaslProto saslMessage = RpcSaslProto.newBuilder().setState(SaslState.WRAP).setToken(ByteString.copyFrom(token)).build();
setupResponse(call, saslHeader, RpcWritable.wrap(saslMessage));
}
}
Aggregations