Exemple #1
0
 private RpcHeaderProtos.RpcSaslProto.Builder CreateSaslReply(RpcHeaderProtos.RpcSaslProto.SaslState
                                                              state, byte[] responseToken)
 {
     RpcHeaderProtos.RpcSaslProto.Builder response = RpcHeaderProtos.RpcSaslProto.NewBuilder
                                                         ();
     response.SetState(state);
     if (responseToken != null)
     {
         response.SetToken(ByteString.CopyFrom(responseToken));
     }
     return(response);
 }
Exemple #2
0
            // all messages must be RPC SASL wrapped, else an exception is thrown
            /// <exception cref="System.IO.IOException"/>
            private void ReadNextRpcPacket()
            {
                SaslRpcClient.Log.Debug("reading next wrapped RPC packet");
                DataInputStream dis    = new DataInputStream(this.@in);
                int             rpcLen = dis.ReadInt();

                byte[] rpcBuf = new byte[rpcLen];
                dis.ReadFully(rpcBuf);
                // decode the RPC header
                ByteArrayInputStream bis = new ByteArrayInputStream(rpcBuf);

                RpcHeaderProtos.RpcResponseHeaderProto.Builder headerBuilder = RpcHeaderProtos.RpcResponseHeaderProto
                                                                               .NewBuilder();
                headerBuilder.MergeDelimitedFrom(bis);
                bool isWrapped = false;

                // Must be SASL wrapped, verify and decode.
                if (headerBuilder.GetCallId() == Server.AuthProtocol.Sasl.callId)
                {
                    RpcHeaderProtos.RpcSaslProto.Builder saslMessage = RpcHeaderProtos.RpcSaslProto.NewBuilder
                                                                           ();
                    saslMessage.MergeDelimitedFrom(bis);
                    if (saslMessage.GetState() == RpcHeaderProtos.RpcSaslProto.SaslState.Wrap)
                    {
                        isWrapped = true;
                        byte[] token = saslMessage.GetToken().ToByteArray();
                        if (SaslRpcClient.Log.IsDebugEnabled())
                        {
                            SaslRpcClient.Log.Debug("unwrapping token of length:" + token.Length);
                        }
                        token = this._enclosing.saslClient.Unwrap(token, 0, token.Length);
                        this.unwrappedRpcBuffer = ByteBuffer.Wrap(token);
                    }
                }
                if (!isWrapped)
                {
                    throw new SaslException("Server sent non-wrapped response");
                }
            }
Exemple #3
0
        /// <summary>
        /// Do client side SASL authentication with server via the given InputStream
        /// and OutputStream
        /// </summary>
        /// <param name="inS">InputStream to use</param>
        /// <param name="outS">OutputStream to use</param>
        /// <returns>AuthMethod used to negotiate the connection</returns>
        /// <exception cref="System.IO.IOException"/>
        public virtual SaslRpcServer.AuthMethod SaslConnect(InputStream inS, OutputStream
                                                            outS)
        {
            DataInputStream  inStream  = new DataInputStream(new BufferedInputStream(inS));
            DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(outS));

            // redefined if/when a SASL negotiation starts, can be queried if the
            // negotiation fails
            authMethod = SaslRpcServer.AuthMethod.Simple;
            SendSaslMessage(outStream, negotiateRequest);
            // loop until sasl is complete or a rpc error occurs
            bool done = false;

            do
            {
                int totalLen = inStream.ReadInt();
                ProtobufRpcEngine.RpcResponseMessageWrapper responseWrapper = new ProtobufRpcEngine.RpcResponseMessageWrapper
                                                                                  ();
                responseWrapper.ReadFields(inStream);
                RpcHeaderProtos.RpcResponseHeaderProto header = responseWrapper.GetMessageHeader(
                    );
                switch (header.GetStatus())
                {
                case RpcHeaderProtos.RpcResponseHeaderProto.RpcStatusProto.Error:
                case RpcHeaderProtos.RpcResponseHeaderProto.RpcStatusProto.Fatal:
                {
                    // might get a RPC error during
                    throw new RemoteException(header.GetExceptionClassName(), header.GetErrorMsg());
                }

                default:
                {
                    break;
                }
                }
                if (totalLen != responseWrapper.GetLength())
                {
                    throw new SaslException("Received malformed response length");
                }
                if (header.GetCallId() != Server.AuthProtocol.Sasl.callId)
                {
                    throw new SaslException("Non-SASL response during negotiation");
                }
                RpcHeaderProtos.RpcSaslProto saslMessage = RpcHeaderProtos.RpcSaslProto.ParseFrom
                                                               (responseWrapper.GetMessageBytes());
                if (Log.IsDebugEnabled())
                {
                    Log.Debug("Received SASL message " + saslMessage);
                }
                // handle sasl negotiation process
                RpcHeaderProtos.RpcSaslProto.Builder response = null;
                switch (saslMessage.GetState())
                {
                case RpcHeaderProtos.RpcSaslProto.SaslState.Negotiate:
                {
                    // create a compatible SASL client, throws if no supported auths
                    RpcHeaderProtos.RpcSaslProto.SaslAuth saslAuthType = SelectSaslClient(saslMessage
                                                                                          .GetAuthsList());
                    // define auth being attempted, caller can query if connect fails
                    authMethod = SaslRpcServer.AuthMethod.ValueOf(saslAuthType.GetMethod());
                    byte[] responseToken = null;
                    if (authMethod == SaslRpcServer.AuthMethod.Simple)
                    {
                        // switching to SIMPLE
                        done = true;
                    }
                    else
                    {
                        // not going to wait for success ack
                        byte[] challengeToken = null;
                        if (saslAuthType.HasChallenge())
                        {
                            // server provided the first challenge
                            challengeToken = saslAuthType.GetChallenge().ToByteArray();
                            saslAuthType   = ((RpcHeaderProtos.RpcSaslProto.SaslAuth)RpcHeaderProtos.RpcSaslProto.SaslAuth
                                              .NewBuilder(saslAuthType).ClearChallenge().Build());
                        }
                        else
                        {
                            if (saslClient.HasInitialResponse())
                            {
                                challengeToken = new byte[0];
                            }
                        }
                        responseToken = (challengeToken != null) ? saslClient.EvaluateChallenge(challengeToken
                                                                                                ) : new byte[0];
                    }
                    response = CreateSaslReply(RpcHeaderProtos.RpcSaslProto.SaslState.Initiate, responseToken
                                               );
                    response.AddAuths(saslAuthType);
                    break;
                }

                case RpcHeaderProtos.RpcSaslProto.SaslState.Challenge:
                {
                    if (saslClient == null)
                    {
                        // should probably instantiate a client to allow a server to
                        // demand a specific negotiation
                        throw new SaslException("Server sent unsolicited challenge");
                    }
                    byte[] responseToken = SaslEvaluateToken(saslMessage, false);
                    response = CreateSaslReply(RpcHeaderProtos.RpcSaslProto.SaslState.Response, responseToken
                                               );
                    break;
                }

                case RpcHeaderProtos.RpcSaslProto.SaslState.Success:
                {
                    // simple server sends immediate success to a SASL client for
                    // switch to simple
                    if (saslClient == null)
                    {
                        authMethod = SaslRpcServer.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(outStream, ((RpcHeaderProtos.RpcSaslProto)response.Build()));
                }
            }while (!done);
            return(authMethod);
        }