Skip to content

Commit bf4b436

Browse files
committed
Support authentication switch during login. Fixes #259
1 parent 3c04649 commit bf4b436

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

src/MySqlConnector/Serialization/MySqlSession.cs

+21-7
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,14 @@ public async Task ConnectAsync(ConnectionSettings cs, IOBehavior ioBehavior, Can
237237
payload = new PayloadData(new ArraySegment<byte>(response));
238238
await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false);
239239
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
240+
241+
// if server doesn't support the authentication fast path, it will send a new challenge
242+
if (payload.HeaderByte == AuthenticationMethodSwitchRequestPayload.Signature)
243+
{
244+
await SwitchAuthenticationAsync(payload, cs, ioBehavior, cancellationToken).ConfigureAwait(false);
245+
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
246+
}
247+
240248
OkPayload.Create(payload);
241249

242250
if (cs.UseCompression)
@@ -267,19 +275,25 @@ public async Task ResetConnectionAsync(ConnectionSettings cs, IOBehavior ioBehav
267275
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
268276
if (payload.HeaderByte == AuthenticationMethodSwitchRequestPayload.Signature)
269277
{
270-
// if the server didn't support the hashed password; rehash with the new challenge
271-
var switchRequest = AuthenticationMethodSwitchRequestPayload.Create(payload);
272-
if (switchRequest.Name != "mysql_native_password")
273-
throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(switchRequest.Name));
274-
hashedPassword = AuthenticationUtility.CreateAuthenticationResponse(switchRequest.Data, 0, cs.Password);
275-
payload = new PayloadData(new ArraySegment<byte>(hashedPassword));
276-
await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false);
278+
await SwitchAuthenticationAsync(payload, cs, ioBehavior, cancellationToken);
277279
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
278280
}
279281
OkPayload.Create(payload);
280282
}
281283
}
282284

285+
private async Task SwitchAuthenticationAsync(PayloadData payload, ConnectionSettings cs, IOBehavior ioBehavior, CancellationToken cancellationToken)
286+
{
287+
// if the server didn't support the hashed password; rehash with the new challenge
288+
var switchRequest = AuthenticationMethodSwitchRequestPayload.Create(payload);
289+
if (switchRequest.Name != "mysql_native_password")
290+
throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(switchRequest.Name));
291+
AuthPluginData = switchRequest.Data;
292+
var hashedPassword = AuthenticationUtility.CreateAuthenticationResponse(AuthPluginData, 0, cs.Password);
293+
payload = new PayloadData(new ArraySegment<byte>(hashedPassword));
294+
await SendReplyAsync(payload, ioBehavior, cancellationToken).ConfigureAwait(false);
295+
}
296+
283297
public async Task<bool> TryPingAsync(IOBehavior ioBehavior, CancellationToken cancellationToken)
284298
{
285299
VerifyState(State.Connected);

0 commit comments

Comments
 (0)