Search in sources :

Example 1 with RpcSaslProto

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;
}
Also used : RpcResponseHeaderProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto) SaslAuth(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto.SaslAuth) RpcWritable(org.apache.hadoop.ipc.RpcWritable) RemoteException(org.apache.hadoop.ipc.RemoteException) SaslException(javax.security.sasl.SaslException) ByteBuffer(java.nio.ByteBuffer) RpcSaslProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto)

Example 2 with RpcSaslProto

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();
}
Also used : SaslRpcServer(org.apache.hadoop.security.SaslRpcServer) SaslAuth(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto.SaslAuth) RpcSaslProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto) AuthMethod(org.apache.hadoop.security.SaslRpcServer.AuthMethod)

Example 3 with RpcSaslProto

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));
    }
}
Also used : RpcResponseHeaderProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto) RpcSaslProto(org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto)

Aggregations

RpcSaslProto (org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto)3 RpcResponseHeaderProto (org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto)2 SaslAuth (org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcSaslProto.SaslAuth)2 ByteBuffer (java.nio.ByteBuffer)1 SaslException (javax.security.sasl.SaslException)1 RemoteException (org.apache.hadoop.ipc.RemoteException)1 RpcWritable (org.apache.hadoop.ipc.RpcWritable)1 SaslRpcServer (org.apache.hadoop.security.SaslRpcServer)1 AuthMethod (org.apache.hadoop.security.SaslRpcServer.AuthMethod)1