Skip to content

Commit 41cdc28

Browse files
committed
Handle mysql_old_password consistently.
A NotSupportedException will still be thrown, but with a more helpful exception message. An old-style Authentication Method Switch Request (single byte packet) will be implicitly converted to a request for 'mysql_old_password'.
1 parent 5663b8c commit 41cdc28

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/MySqlConnector/Serialization/AuthenticationMethodSwitchRequestPayload.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Text;
1+
using System.Text;
22

33
namespace MySql.Data.Serialization
44
{
@@ -13,8 +13,20 @@ public static AuthenticationMethodSwitchRequestPayload Create(PayloadData payloa
1313
{
1414
var reader = new ByteArrayReader(payload.ArraySegment);
1515
reader.ReadByte(Signature);
16-
var name = Encoding.UTF8.GetString(reader.ReadNullTerminatedByteString());
17-
var data = reader.ReadByteString(reader.BytesRemaining);
16+
string name;
17+
byte[] data;
18+
if (payload.ArraySegment.Count == 1)
19+
{
20+
// if the packet is just the header byte (0xFE), it's an "Old Authentication Method Switch Request Packet"
21+
// (possibly sent by a server that doesn't support CLIENT_PLUGIN_AUTH)
22+
name = "mysql_old_password";
23+
data = new byte[0];
24+
}
25+
else
26+
{
27+
name = Encoding.UTF8.GetString(reader.ReadNullTerminatedByteString());
28+
data = reader.ReadByteString(reader.BytesRemaining);
29+
}
1830
return new AuthenticationMethodSwitchRequestPayload(name, data);
1931
}
2032

src/MySqlConnector/Serialization/MySqlSession.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Diagnostics;
33
using System.Globalization;
44
using System.IO;
@@ -242,18 +242,8 @@ public async Task ConnectAsync(ConnectionSettings cs, IOBehavior ioBehavior, Can
242242
// if server doesn't support the authentication fast path, it will send a new challenge
243243
if (payload.HeaderByte == AuthenticationMethodSwitchRequestPayload.Signature)
244244
{
245-
if (payload.ArraySegment.Count == 1)
246-
{
247-
// Single 0xfe byte of the payload means it's an Old Authentication Method Switch Request Packet.
248-
// See http://imysql.com/mysql-internal-manual/connection-phase-packets.html
249-
// It's old protocol so MySqlConnector doesn't support it.
250-
throw new NotSupportedException("Old Authentication Method Switch is not supported. Use new password hash format of 41-byte in MySQL server, not old format of 16-byte.");
251-
}
252-
else
253-
{
254-
await SwitchAuthenticationAsync(cs, payload, ioBehavior, cancellationToken).ConfigureAwait(false);
255-
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
256-
}
245+
await SwitchAuthenticationAsync(cs, payload, ioBehavior, cancellationToken).ConfigureAwait(false);
246+
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
257247
}
258248

259249
OkPayload.Create(payload);
@@ -381,6 +371,9 @@ private async Task SwitchAuthenticationAsync(ConnectionSettings cs, PayloadData
381371
}
382372
break;
383373

374+
case "mysql_old_password":
375+
throw new NotSupportedException("'MySQL Server is requesting the insecure pre-4.1 auth mechanism (mysql_old_password). The user password must be upgraded; see https://dev.mysql.com/doc/refman/5.7/en/account-upgrades.html.");
376+
384377
default:
385378
throw new NotSupportedException("Authentication method '{0}' is not supported.".FormatInvariant(switchRequest.Name));
386379
}

0 commit comments

Comments
 (0)