Example #1
0
        private async Task AuthenticateAsync(HandshakePacket handshake, CancellationToken cancellationToken = default)
        {
            byte sequenceNumber = 1;

            bool useSsl = false;

            if (_options.SslMode != SslMode.DISABLED)
            {
                bool sslAvailable = (handshake.ServerCapabilities & (long)CapabilityFlags.SSL) != 0;

                if (!sslAvailable && _options.SslMode >= SslMode.REQUIRE)
                {
                    throw new InvalidOperationException("The server doesn't support SSL encryption");
                }

                if (sslAvailable)
                {
                    var command = new SslRequestCommand(PacketConstants.Utf8Mb4GeneralCi);
                    await _channel.WriteCommandAsync(command, sequenceNumber ++, cancellationToken);

                    _channel.UpgradeToSsl();
                    useSsl = true;
                }
            }

            var authenticateCommand = new AuthenticateCommand(_options, PacketConstants.Utf8Mb4GeneralCi, handshake.Scramble, handshake.AuthPluginName);
            await _channel.WriteCommandAsync(authenticateCommand, sequenceNumber, cancellationToken);

            var packet = await _channel.ReadPacketSlowAsync(cancellationToken);

            sequenceNumber += 2;

            ThrowIfErrorPacket(packet, "Authentication error.");

            if (packet[0] == (byte)ResponseType.Ok)
            {
                return;
            }

            if (packet[0] == (byte)ResponseType.AuthPluginSwitch)
            {
                var body          = new ReadOnlySequence <byte>(packet, 1, packet.Length - 1);
                var switchRequest = new AuthPluginSwitchPacket(body);
                await HandleAuthPluginSwitch(switchRequest, sequenceNumber, useSsl, cancellationToken);
            }
            else
            {
                await AuthenticateSha256Async(packet, handshake.Scramble, sequenceNumber, useSsl, cancellationToken);
            }
        }
Example #2
0
        private async Task HandleAuthPluginSwitch(AuthPluginSwitchPacket switchRequest, byte sequenceNumber, bool useSsl, CancellationToken cancellationToken = default)
        {
            if (!_allowedAuthPlugins.Contains(switchRequest.AuthPluginName))
            {
                throw new InvalidOperationException($"Authentication plugin {switchRequest.AuthPluginName} is not supported.");
            }

            var switchCommand = new AuthPluginSwitchCommand(_options.Password, switchRequest.AuthPluginData, switchRequest.AuthPluginName);
            await _channel.WriteCommandAsync(switchCommand, sequenceNumber, cancellationToken);

            var packet = await _channel.ReadPacketSlowAsync(cancellationToken);

            sequenceNumber += 2;
            ThrowIfErrorPacket(packet, "Authentication switch error.");

            if (switchRequest.AuthPluginName == AuthPluginNames.CachingSha2Password)
            {
                await AuthenticateSha256Async(packet, switchRequest.AuthPluginData, sequenceNumber, useSsl, cancellationToken);
            }
        }
Example #3
0
        private async Task AuthenticateAsync(HandshakePacket handshake, CancellationToken cancellationToken = default)
        {
            byte sequenceNumber = 1;

            if (_options.UseSsl)
            {
                var command = new SslRequestCommand(PacketConstants.Utf8Mb4GeneralCi);
                await _channel.WriteCommandAsync(command, sequenceNumber, cancellationToken);

                sequenceNumber += 1;
                _channel.UpgradeToSsl();
            }

            var authenticateCommand = new AuthenticateCommand(_options, PacketConstants.Utf8Mb4GeneralCi, handshake.Scramble, handshake.AuthPluginName);
            await _channel.WriteCommandAsync(authenticateCommand, sequenceNumber, cancellationToken);

            var packet = await _channel.ReadPacketSlowAsync(cancellationToken);

            sequenceNumber += 2;

            ThrowIfErrorPacket(packet, "Authentication error.");

            if (packet[0] == (byte)ResponseType.Ok)
            {
                return;
            }

            if (packet[0] == (byte)ResponseType.AuthPluginSwitch)
            {
                var body          = new ReadOnlySequence <byte>(packet, 1, packet.Length - 1);
                var switchRequest = new AuthPluginSwitchPacket(body);
                await HandleAuthPluginSwitch(switchRequest, sequenceNumber, cancellationToken);
            }
            else
            {
                await AuthenticateSha256Async(packet, handshake.Scramble, sequenceNumber, cancellationToken);
            }
        }