Example #1
0
        private void ReceiveHandShake()
        {
            var request = new HandshakeResponse41Packet();
            ReceivePacket(request);
            MySqlPacket response = null;
            if (VerifyChallenge(request.UserName, request.AuthResponse))
            {
                response = new OKPacket()
              {
                  AffectedRows = 0,
                  LastInsertId = 0,
                  Status = StatusFlags.SERVER_STATUS_AUTOCOMMIT,
                  Capabilities = CapabilityFlags.CLIENT_PROTOCOL_41,
                  Info = string.Empty
              };
            }
            else { }

            SendPacket(response);
        }
Example #2
0
        public ResultPacket Login()
        {
            var greeting  = ReceiveGreeting();
            var challenge = greeting.AuthPluginDataPart1.Concat(greeting.AuthPluginDataPart2).ToArray();
            var sign      = CalcChallenge(this.userName, this.password, challenge);

            var request = new HandshakeResponse41Packet()
            {
                MaxPacketSize  = 0x40000000,
                Capabilities   = (CapabilityFlags)0x000fa285,
                UserName       = userName,
                Database       = database,
                AuthResponse   = sign,
                CharacterSet   = CharacterSet.UTF8_GENERAL_CI,
                AuthPluginName = "mysql_native_password",
                Sequence       = 1
            };

            request.Write(this.socket);

            return(MySqlPacketFactory.GetResultPacket(this.socket));
        }
Example #3
0
        private void ReceiveHandShake()
        {
            var request = new HandshakeResponse41Packet();

            ReceivePacket(request);
            MySqlPacket response = null;

            if (VerifyChallenge(request.UserName, request.AuthResponse))
            {
                response = new OKPacket()
                {
                    AffectedRows = 0,
                    LastInsertId = 0,
                    Status       = StatusFlags.SERVER_STATUS_AUTOCOMMIT,
                    Capabilities = CapabilityFlags.CLIENT_PROTOCOL_41,
                    Info         = string.Empty
                };
            }
            else
            {
            }

            SendPacket(response);
        }
        public override async Task OpenAsync(CancellationToken cancellationToken)
        {
            VerifyNotDisposed();
            if (State != ConnectionState.Closed)
            {
                throw new InvalidOperationException("Cannot Open when State is {0}.".FormatInvariant(State));
            }
#if !NETSTANDARD1_3
            if (System.Transactions.Transaction.Current != null)
            {
                throw new NotSupportedException("Ambient transactions are not supported. Use BeginTransaction instead.");
            }
#endif

            SetState(ConnectionState.Connecting);

            bool success = false;
            try
            {
                // get existing session from the pool if possible
                var pool = ConnectionPool.GetPool(m_connectionStringBuilder);
                m_session = pool == null ? null : await pool.TryGetSessionAsync(cancellationToken).ConfigureAwait(false);

                if (m_session != null)
                {
                    // test that session is still valid and (optionally) reset it
                    if (!await TryPingAsync(m_session, cancellationToken).ConfigureAwait(false))
                    {
                        Utility.Dispose(ref m_session);
                    }
                    else if (m_connectionStringBuilder.ConnectionReset)
                    {
                        await ResetConnectionAsync(cancellationToken).ConfigureAwait(false);
                    }
                }

                if (m_session == null)
                {
                    m_session = new MySqlSession(pool);
                    var connected = await m_session.ConnectAsync(m_connectionStringBuilder.Server.Split(','), (int)m_connectionStringBuilder.Port).ConfigureAwait(false);

                    if (!connected)
                    {
                        SetState(ConnectionState.Closed);
                        throw new MySqlException("Unable to connect to any of the specified MySQL hosts.");
                    }

                    var payload = await m_session.ReceiveAsync(cancellationToken).ConfigureAwait(false);

                    var reader           = new ByteArrayReader(payload.ArraySegment.Array, payload.ArraySegment.Offset, payload.ArraySegment.Count);
                    var initialHandshake = new InitialHandshakePacket(reader);
                    if (initialHandshake.AuthPluginName != "mysql_native_password")
                    {
                        throw new NotSupportedException("Only 'mysql_native_password' authentication method is supported.");
                    }
                    m_session.ServerVersion  = new ServerVersion(Encoding.ASCII.GetString(initialHandshake.ServerVersion));
                    m_session.AuthPluginData = initialHandshake.AuthPluginData;

                    var response = HandshakeResponse41Packet.Create(initialHandshake, m_connectionStringBuilder.UserID, m_connectionStringBuilder.Password, m_database);
                    payload = new PayloadData(new ArraySegment <byte>(response));
                    await m_session.SendReplyAsync(payload, cancellationToken).ConfigureAwait(false);

                    await m_session.ReceiveReplyAsync(cancellationToken).ConfigureAwait(false);

                    // TODO: Check success
                }

                m_hasBeenOpened = true;
                SetState(ConnectionState.Open);
                success = true;
            }
            catch (MySqlException)
            {
                SetState(ConnectionState.Closed);
                throw;
            }
            catch (SocketException ex)
            {
                SetState(ConnectionState.Closed);
                throw new MySqlException("Unable to connect to any of the specified MySQL hosts.", ex);
            }
            finally
            {
                if (!success)
                {
                    Utility.Dispose(ref m_session);
                }
            }
        }
Example #5
0
        public ResultPacket Login()
        {
            var greeting = ReceiveGreeting();
            var challenge = greeting.AuthPluginDataPart1.Concat(greeting.AuthPluginDataPart2).ToArray();
            var sign = CalcChallenge(this.userName, this.password, challenge);

            var request = new HandshakeResponse41Packet()
            {
                MaxPacketSize = 0x40000000,
                Capabilities = (CapabilityFlags)0x000fa285,
                UserName = userName,
                Database = database,
                AuthResponse = sign,
                CharacterSet = CharacterSet.UTF8_GENERAL_CI,
                AuthPluginName = "mysql_native_password",
                Sequence = 1
            };
            request.Write(this.socket);

            return MySqlPacketFactory.GetResultPacket(this.socket);
        }
Example #6
0
        public override async Task OpenAsync(CancellationToken cancellationToken)
        {
            VerifyNotDisposed();
            if (State != ConnectionState.Closed)
            {
                throw new InvalidOperationException("Cannot Open when State is {0}.".FormatInvariant(State));
            }
#if !NETSTANDARD1_3
            if (System.Transactions.Transaction.Current != null)
            {
                throw new NotSupportedException("Ambient transactions are not supported. Use BeginTransaction instead.");
            }
#endif

            if (m_connectionStringBuilder.UseCompression)
            {
                throw new NotSupportedException("Compression not supported.");
            }

            SetState(ConnectionState.Connecting);

            bool success = false;
            try
            {
                var pool = ConnectionPool.GetPool(m_connectionStringBuilder);
                m_session = pool?.TryGetSession();
                if (m_session == null)
                {
                    m_session = new MySqlSession(pool);
                    var connected = await m_session.ConnectAsync(m_connectionStringBuilder.Server.Split(','), (int)m_connectionStringBuilder.Port).ConfigureAwait(false);

                    if (!connected)
                    {
                        SetState(ConnectionState.Closed);
                        throw new MySqlException("Unable to connect to any of the specified MySQL hosts.");
                    }

                    var payload = await m_session.ReceiveAsync(cancellationToken).ConfigureAwait(false);

                    var reader           = new ByteArrayReader(payload.ArraySegment.Array, payload.ArraySegment.Offset, payload.ArraySegment.Count);
                    var initialHandshake = new InitialHandshakePacket(reader);
                    if (initialHandshake.AuthPluginName != "mysql_native_password")
                    {
                        throw new NotSupportedException("Only 'mysql_native_password' authentication method is supported.");
                    }
                    m_session.ServerVersion = new ServerVersion(Encoding.ASCII.GetString(initialHandshake.ServerVersion));

                    var response = HandshakeResponse41Packet.Create(initialHandshake, m_connectionStringBuilder.UserID, m_connectionStringBuilder.Password, m_database);
                    payload = new PayloadData(new ArraySegment <byte>(response));
                    await m_session.SendReplyAsync(payload, cancellationToken).ConfigureAwait(false);

                    await m_session.ReceiveReplyAsync(cancellationToken).ConfigureAwait(false);

                    // TODO: Check success
                }
                else if (m_connectionStringBuilder.ConnectionReset)
                {
                    if (m_session.ServerVersion.Version.CompareTo(ServerVersions.SupportsResetConnection) >= 0)
                    {
                        await m_session.SendAsync(ResetConnectionPayload.Create(), cancellationToken).ConfigureAwait(false);

                        var payload = await m_session.ReceiveReplyAsync(cancellationToken);

                        OkPayload.Create(payload);
                    }
                    else
                    {
                        // MySQL doesn't appear to accept a replayed hashed password (using the challenge from the initial handshake), so just send zeroes
                        // and expect to get a new challenge
                        var payload = ChangeUserPayload.Create(m_connectionStringBuilder.UserID, new byte[20], m_database);
                        await m_session.SendAsync(payload, cancellationToken).ConfigureAwait(false);

                        payload = await m_session.ReceiveReplyAsync(cancellationToken).ConfigureAwait(false);

                        var switchRequest = AuthenticationMethodSwitchRequestPayload.Create(payload);
                        if (switchRequest.Name != "mysql_native_password")
                        {
                            throw new NotSupportedException("Only 'mysql_native_password' authentication method is supported.");
                        }
                        var hashedPassword = AuthenticationUtility.HashPassword(switchRequest.Data, 0, m_connectionStringBuilder.Password);
                        payload = new PayloadData(new ArraySegment <byte>(hashedPassword));
                        await m_session.SendReplyAsync(payload, cancellationToken).ConfigureAwait(false);

                        payload = await m_session.ReceiveReplyAsync(cancellationToken).ConfigureAwait(false);

                        OkPayload.Create(payload);
                    }
                }

                m_hasBeenOpened = true;
                SetState(ConnectionState.Open);
                success = true;
            }
            catch (MySqlException)
            {
                SetState(ConnectionState.Closed);
                throw;
            }
            catch (SocketException ex)
            {
                SetState(ConnectionState.Closed);
                throw new MySqlException("Unable to connect to any of the specified MySQL hosts.", ex);
            }
            finally
            {
                if (!success)
                {
                    Utility.Dispose(ref m_session);
                }
            }
        }