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); } }
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); } }
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); } }