From 7ee551cbf76aff5ecfd255776ca6a9e216ac5325 Mon Sep 17 00:00:00 2001 From: "jianghang.loujh" Date: Tue, 24 Dec 2024 16:33:41 +0800 Subject: [PATCH] fixed issue #5301, fixed caching_sha2_password full auth --- .../parse/driver/mysql/MysqlConnector.java | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java index c6aeb6f2..c54ba327 100644 --- a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java +++ b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/MysqlConnector.java @@ -196,6 +196,7 @@ public class MysqlConnector { } HandshakeInitializationPacket handshakePacket = new HandshakeInitializationPacket(); handshakePacket.fromBytes(body); + // default utf8(33) byte serverCharsetNumber = (handshakePacket.serverCharsetNumber != 0) ? handshakePacket.serverCharsetNumber : 33; SslMode sslMode = sslInfo != null ? sslInfo.getSslMode() : SslMode.DISABLED; if (sslMode != SslMode.DISABLED) { @@ -223,10 +224,11 @@ public class MysqlConnector { serverVersion = handshakePacket.serverVersion; // 记录serverVersion logger.info("handshake initialization packet received, prepare the client authentication packet to send"); // 某些老协议的 server 默认不返回 auth plugin,需要使用默认的 mysql_native_password - String authPluginName = (handshakePacket.authPluginName != null - && handshakePacket.authPluginName.length > 0) ? new String( - handshakePacket.authPluginName) : "mysql_native_password"; - logger.info("auth plugin: {}", authPluginName); + String authPluginName = "mysql_native_password"; + if (handshakePacket.authPluginName != null && handshakePacket.authPluginName.length > 0) { + authPluginName = new String(handshakePacket.authPluginName); + } + logger.info("auth ClientAuthenticationSHA2Packet: {}", authPluginName); boolean isSha2Password = false; ClientAuthenticationPacket clientAuth; if ("caching_sha2_password".equals(authPluginName)) { @@ -295,22 +297,29 @@ public class MysqlConnector { body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout); } else if ("caching_sha2_password".equals(pluginName)) { 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) { - // 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); body = PacketManager.readBytes(channel, header.getPacketBodyLength(), timeout); } 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); + 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 { header = authSwitchAfterAuth(encryptedPassword, header);