Authenticate frame
Inheritance: Frame
Esempio n. 1
0
        /// <summary>
        ///   Reads a packet from a stream.
        /// </summary>
        /// <param name="stream"> The stream. </param>
        /// <returns> </returns>
        internal static async Task<Frame> FromStream(Stream stream)
        {
            //read header
            int read = 0;
            var header = new byte[8];
            while (read < 8)
                read += await stream.ReadAsync(header, read, 8 - read).ConfigureAwait(false);

            //get length
            if (BitConverter.IsLittleEndian) Array.Reverse(header, 4, 4);
            int length = BitConverter.ToInt32(header, 4);

            Frame frame;
            switch ((FrameOpcode)header[3])
            {
                case FrameOpcode.Error:
                    frame = new ErrorFrame();
                    break;
                case FrameOpcode.Ready:
                    frame = new ReadyFrame();
                    break;
                case FrameOpcode.Authenticate:
                    frame = new AuthenticateFrame();
                    break;
                case FrameOpcode.Supported:
                    frame = new SupportedFrame();
                    break;
                case FrameOpcode.Result:
                    frame = new ResultFrame();
                    break;
                case FrameOpcode.Event:
                    frame = new EventFrame();
                    break;
                default:
                    throw new ProtocolException(0, "Unexpected OpCode received.");
            }

            frame.Version = (FrameVersion)header[0];
            frame.Flags = (FrameFlags)header[1];
            frame.Stream = unchecked((sbyte)header[2]);
            frame.OpCode = (FrameOpcode)header[3];
            frame.Length = length;

            //wrap the stream in a window, that will be completely read when disposed
            var reader = new FrameReader(stream, length);
            frame.Reader = reader;

            //decompress the contents of the frame (implicity loads the entire frame body!)
            if (frame.Flags.HasFlag(FrameFlags.Compression))
                await reader.DecompressAsync();

            //read tracing id if set
            if (frame.Flags.HasFlag(FrameFlags.Tracing))
                frame.TracingId = await reader.ReadUuidAsync().ConfigureAwait(false);

            await frame.InitializeAsync().ConfigureAwait(false);

            return frame;
        }
Esempio n. 2
0
        /// <summary>
        /// Authenticates the connection.
        /// </summary>
        /// <param name="auth">The authentication request from the server.</param>
        /// <param name="logger">The logger.</param>
        /// <returns></returns>
        /// <exception cref="AuthenticationException">
        /// Unsupported Authenticator:  + auth.Authenticator;null
        /// or
        /// Authentication failed, SASL Challenge was rejected by client
        /// or
        /// Authentication failed, Authenticator rejected SASL result
        /// or
        /// Expected a Authentication Challenge from Server!
        /// or
        /// No credentials provided in configuration
        /// or
        /// Authentication failed: Ready frame not received
        /// </exception>
        private async Task AuthenticateAsync(AuthenticateFrame auth, Logger logger)
        {
            logger.LogVerbose("Authentication requested, attempting to provide credentials");

            //dispose AuthenticateFrame
            auth.Dispose();

            if (auth.ProtocolVersion >= 2)
            {
                //protocol version2: use SASL AuthResponse to authenticate

                //get an AuthenticatorFactory
                IAuthenticatorFactory factory =
                    Loader.Extensions.AuthenticationFactories.FirstOrDefault(
                        f => f.Name.Equals(auth.Authenticator, StringComparison.OrdinalIgnoreCase));

                if (factory == null)
                    throw new AuthenticationException(auth.ProtocolVersion, "Unsupported Authenticator: " + auth.Authenticator);

                logger.LogVerbose("Attempting authentication for scheme {0}", factory.Name);

                //grab an authenticator instance
                IAuthenticator authenticator = factory.CreateAuthenticator(_config);

                //start authentication loop
                byte[] saslChallenge = null;
                while (true)
                {
                    //check for challenge
                    byte[] saslResponse;
                    if (!authenticator.Authenticate(auth.ProtocolVersion, saslChallenge, out saslResponse))
                    {
                        throw new AuthenticationException(auth.ProtocolVersion, "Authentication failed, SASL Challenge was rejected by client");
                    }

                    //send response
                    var cred = new AuthResponseFrame(saslResponse);
                    var authResponse =
                        await
                            SendRequestAsyncInternal(cred, logger, 1, CancellationToken.None).AutoConfigureAwait();

                    //dispose authResponse (makes sure all is read)
                    authResponse.Dispose();

                    //check for success
                    var success = authResponse as AuthSuccessFrame;
                    if (success != null)
                    {
                        if (!authenticator.Authenticate(auth.ProtocolVersion, success.SaslResult))
                        {
                            throw new AuthenticationException(authResponse.ProtocolVersion, "Authentication failed, Authenticator rejected SASL result", authResponse.TracingId);
                        }

                        //yeah, authenticated, break from the authentication loop
                        break;
                    }

                    //no success yet, lets try next round
                    var challenge = authResponse as AuthChallengeFrame;
                    if (challenge == null)
                    {
                        throw new AuthenticationException(authResponse.ProtocolVersion, "Expected a Authentication Challenge from Server!", authResponse.TracingId);
                    }

                    saslChallenge = challenge.SaslChallenge;
                }
            }
            else
            {
                //protocol version1: use Credentials to authenticate

                //check if _username is actually set
                if (_config.Username == null || _config.Password == null)
                    throw new AuthenticationException(auth.ProtocolVersion, "No credentials provided in configuration");

                var cred = new CredentialsFrame(_config.Username, _config.Password);
                var authResponse =
                    await
                        SendRequestAsyncInternal(cred, logger, 1, CancellationToken.None).AutoConfigureAwait();

                //dispose authResponse (makes sure all is read)
                authResponse.Dispose();

                if (!(authResponse is ReadyFrame))
                {
                    throw new AuthenticationException(authResponse.ProtocolVersion, "Authentication failed: Ready frame not received", authResponse.TracingId);
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        ///   Reads a packet from a stream.
        /// </summary>
        /// <param name="stream"> The stream. </param>
        /// <returns> </returns>
        internal static async Task <Frame> FromStream(Stream stream)
        {
            //read header
            int read   = 0;
            var header = new byte[8];

            while (read < 8)
            {
                read += await stream.ReadAsync(header, read, 8 - read).ConfigureAwait(false);
            }

            //get length
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(header, 4, 4);
            }
            int length = BitConverter.ToInt32(header, 4);

            Frame frame;

            switch ((FrameOpcode)header[3])
            {
            case FrameOpcode.Error:
                frame = new ErrorFrame();
                break;

            case FrameOpcode.Ready:
                frame = new ReadyFrame();
                break;

            case FrameOpcode.Authenticate:
                frame = new AuthenticateFrame();
                break;

            case FrameOpcode.Supported:
                frame = new SupportedFrame();
                break;

            case FrameOpcode.Result:
                frame = new ResultFrame();
                break;

            case FrameOpcode.Event:
                frame = new EventFrame();
                break;

            default:
                throw new ProtocolException(0, "Unexpected OpCode received.");
            }

            frame.Version = (FrameVersion)header[0];
            frame.Flags   = (FrameFlags)header[1];
            frame.Stream  = unchecked ((sbyte)header[2]);
            frame.OpCode  = (FrameOpcode)header[3];
            frame.Length  = length;

            //wrap the stream in a window, that will be completely read when disposed
            var reader = new FrameReader(stream, length);

            frame.Reader = reader;

            //decompress the contents of the frame (implicity loads the entire frame body!)
            if (frame.Flags.HasFlag(FrameFlags.Compression))
            {
                await reader.DecompressAsync();
            }

            //read tracing id if set
            if (frame.Flags.HasFlag(FrameFlags.Tracing))
            {
                frame.TracingId = await reader.ReadUuidAsync().ConfigureAwait(false);
            }

            await frame.InitializeAsync().ConfigureAwait(false);

            return(frame);
        }
Esempio n. 4
0
 /// <summary>
 /// Gets the frame from opcode.
 /// </summary>
 /// <param name="protocolVersion">the version of the cql binary protocol in use</param>
 /// <param name="opcode">The opcode.</param>
 /// <returns></returns>
 /// <exception cref="ProtocolException">Unexpected OpCode received.</exception>
 private static Frame GetFrameFromOpcode(byte protocolVersion, FrameOpcode opcode)
 {
     Frame frame;
     switch(opcode)
     {
         case FrameOpcode.Error:
             frame = new ErrorFrame();
             break;
         case FrameOpcode.Ready:
             frame = new ReadyFrame();
             break;
         case FrameOpcode.Authenticate:
             frame = new AuthenticateFrame();
             break;
         case FrameOpcode.AuthChallenge:
             frame = new AuthChallengeFrame();
             break;
         case FrameOpcode.AuthSuccess:
             frame = new AuthSuccessFrame();
             break;
         case FrameOpcode.Supported:
             frame = new SupportedFrame();
             break;
         case FrameOpcode.Result:
             frame = new ResultFrame();
             break;
         case FrameOpcode.Event:
             frame = new EventFrame();
             break;
         default:
             throw new ProtocolException(protocolVersion, 0, string.Format("Unexpected OpCode {0:X} received.", opcode));
     }
     return frame;
 }