fixed issue #5301, fixed caching_sha2_password full auth

This commit is contained in:
jianghang.loujh
2024-12-24 16:33:41 +08:00
parent 923675aa49
commit 7ee551cbf7

View File

@@ -196,6 +196,7 @@ public class MysqlConnector {
} }
HandshakeInitializationPacket handshakePacket = new HandshakeInitializationPacket(); HandshakeInitializationPacket handshakePacket = new HandshakeInitializationPacket();
handshakePacket.fromBytes(body); handshakePacket.fromBytes(body);
// default utf8(33)
byte serverCharsetNumber = (handshakePacket.serverCharsetNumber != 0) ? handshakePacket.serverCharsetNumber : 33; byte serverCharsetNumber = (handshakePacket.serverCharsetNumber != 0) ? handshakePacket.serverCharsetNumber : 33;
SslMode sslMode = sslInfo != null ? sslInfo.getSslMode() : SslMode.DISABLED; SslMode sslMode = sslInfo != null ? sslInfo.getSslMode() : SslMode.DISABLED;
if (sslMode != SslMode.DISABLED) { if (sslMode != SslMode.DISABLED) {
@@ -223,10 +224,11 @@ public class MysqlConnector {
serverVersion = handshakePacket.serverVersion; // 记录serverVersion serverVersion = handshakePacket.serverVersion; // 记录serverVersion
logger.info("handshake initialization packet received, prepare the client authentication packet to send"); logger.info("handshake initialization packet received, prepare the client authentication packet to send");
// 某些老协议的 server 默认不返回 auth plugin,需要使用默认的 mysql_native_password // 某些老协议的 server 默认不返回 auth plugin,需要使用默认的 mysql_native_password
String authPluginName = (handshakePacket.authPluginName != null String authPluginName = "mysql_native_password";
&& handshakePacket.authPluginName.length > 0) ? new String( if (handshakePacket.authPluginName != null && handshakePacket.authPluginName.length > 0) {
handshakePacket.authPluginName) : "mysql_native_password"; authPluginName = new String(handshakePacket.authPluginName);
logger.info("auth plugin: {}", authPluginName); }
logger.info("auth ClientAuthenticationSHA2Packet: {}", authPluginName);
boolean isSha2Password = false; boolean isSha2Password = false;
ClientAuthenticationPacket clientAuth; ClientAuthenticationPacket clientAuth;
if ("caching_sha2_password".equals(authPluginName)) { if ("caching_sha2_password".equals(authPluginName)) {
@@ -295,22 +297,29 @@ public class MysqlConnector {
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout); body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
} else if ("caching_sha2_password".equals(pluginName)) { } else if ("caching_sha2_password".equals(pluginName)) {
byte[] scramble = authData; byte[] scramble = authData;
try {
encryptedPassword = MySQLPasswordEncrypter.scrambleCachingSha2(getPassword().getBytes(),
scramble);
} catch (DigestException e) {
throw new RuntimeException("can't encrypt password that will be sent to MySQL server.", e);
}
header = authSwitchAfterAuth(encryptedPassword, header);
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
assert body != null;
if (body[0] == 0x01 && body[1] == 0x04) { if (body[0] == 0x01 && body[1] == 0x04) {
// fixed issue https://github.com/alibaba/canal/pull/4767, support mysql 8.0.30+ // support full auth
// clientAuth提前采用了sha2编码,会减少一次auth交互
header = cachingSha2PasswordFullAuth(channel, header, getPassword().getBytes(), scramble); header = cachingSha2PasswordFullAuth(channel, header, getPassword().getBytes(), scramble);
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout); body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
} else { } else {
header = PacketManager.readHeader(channel, 4); try {
encryptedPassword = MySQLPasswordEncrypter.scrambleCachingSha2(getPassword().getBytes(),
scramble);
} catch (DigestException e) {
throw new RuntimeException("can't encrypt password that will be sent to MySQL server.", e);
}
header = authSwitchAfterAuth(encryptedPassword, header);
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout); body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
assert body != null;
if (body[0] == 0x01 && body[1] == 0x04) {
// fixed issue https://github.com/alibaba/canal/pull/4767, support mysql 8.0.30+
header = cachingSha2PasswordFullAuth(channel, header, getPassword().getBytes(), scramble);
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
} else {
header = PacketManager.readHeader(channel, 4);
body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout);
}
} }
} else { } else {
header = authSwitchAfterAuth(encryptedPassword, header); header = authSwitchAfterAuth(encryptedPassword, header);