public static byte[] Create(InitialHandshakePacket handshake, ConnectionSettings cs) { // TODO: verify server capabilities var writer = CreateCapabilitiesPayload(handshake.ProtocolCapabilities, cs); writer.WriteNullTerminatedString(cs.UserID); var authenticationResponse = AuthenticationUtility.CreateAuthenticationResponse(handshake.AuthPluginData, 0, cs.Password); writer.WriteByte((byte)authenticationResponse.Length); writer.Write(authenticationResponse); if (!string.IsNullOrWhiteSpace(cs.Database)) { writer.WriteNullTerminatedString(cs.Database); } if ((handshake.ProtocolCapabilities & ProtocolCapabilities.PluginAuth) != 0) { writer.WriteNullTerminatedString("mysql_native_password"); } return(writer.ToBytes()); }
public async Task ConnectAsync(ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken) { var connected = false; if (cs.ConnectionType == ConnectionType.Tcp) { connected = await OpenTcpSocketAsync(cs, ioBehavior, cancellationToken).ConfigureAwait(false); } else if (cs.ConnectionType == ConnectionType.Unix) { connected = await OpenUnixSocketAsync(cs, ioBehavior, cancellationToken).ConfigureAwait(false); } if (!connected) { throw new MyCatException("Unable to connect to any of the specified MySQL hosts."); } var socketByteHandler = new SocketByteHandler(m_socket); m_payloadHandler = new StandardPayloadHandler(socketByteHandler); var payload = await ReceiveAsync(ioBehavior, cancellationToken).ConfigureAwait(false); var reader = new ByteArrayReader(payload.ArraySegment.Array, payload.ArraySegment.Offset, payload.ArraySegment.Count); var initialHandshake = new InitialHandshakePacket(reader); // if PluginAuth is supported, then use the specified auth plugin; else, fall back to protocol capabilities to determine the auth type to use string authPluginName; if ((initialHandshake.ProtocolCapabilities & ProtocolCapabilities.PluginAuth) != 0) { authPluginName = initialHandshake.AuthPluginName; } else { authPluginName = (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.SecureConnection) == 0 ? "mysql_old_password" : "mysql_native_password"; } if (authPluginName != "mysql_native_password") { throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(initialHandshake.AuthPluginName)); } ServerVersion = new ServerVersion(Encoding.ASCII.GetString(initialHandshake.ServerVersion)); ConnectionId = initialHandshake.ConnectionId; AuthPluginData = initialHandshake.AuthPluginData; if (cs.UseCompression && (initialHandshake.ProtocolCapabilities & ProtocolCapabilities.Compress) == 0) { cs = cs.WithUseCompression(false); } if (cs.SslMode != MyCatSslMode.None) { await InitSslAsync(initialHandshake.ProtocolCapabilities, cs, ioBehavior, cancellationToken).ConfigureAwait(false); } var response = HandshakeResponse41Packet.Create(initialHandshake, cs); payload = new PayloadData(new ArraySegment <byte>(response)); await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false); payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false); OkPayload.Create(payload); if (cs.UseCompression) { m_payloadHandler = new CompressedPayloadHandler(m_payloadHandler.ByteHandler); } }