From b2b3223d1d26e607736f1c1fe7350b38f77a4419 Mon Sep 17 00:00:00 2001 From: dingxiaobo Date: Thu, 29 Aug 2024 12:42:31 +0800 Subject: [PATCH] fix mysql 5.1 negotiate NPE. (#5255) --- .../parse/driver/mysql/MysqlConnector.java | 23 +++++++++++++------ .../mysql/socket/BioSocketChannelPool.java | 2 +- 2 files changed, 17 insertions(+), 8 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 1f443bcf..3df6e85f 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 @@ -200,14 +200,18 @@ public class MysqlConnector { } HandshakeInitializationPacket handshakePacket = new HandshakeInitializationPacket(); handshakePacket.fromBytes(body); + byte serverCharsetNumber + = (handshakePacket.serverCharsetNumber != 0) + ? handshakePacket.serverCharsetNumber + : 33; SslMode sslMode = sslInfo != null ? sslInfo.getSslMode() : SslMode.DISABLED; if (sslMode != SslMode.DISABLED) { boolean serverSupportSsl = (handshakePacket.serverCapabilities & CLIENT_SSL) > 0; if (!serverSupportSsl) { - throw new IOException("MySQL Server does not support SSL: " + address + " serverCapabilities: " - + handshakePacket.serverCapabilities); + throw new IOException("MySQL Server does not support SSL: " + address + + " serverCapabilities: " + handshakePacket.serverCapabilities); } - byte[] sslPacket = new SslRequestCommandPacket(handshakePacket.serverCharsetNumber).toBytes(); + byte[] sslPacket = new SslRequestCommandPacket(serverCharsetNumber).toBytes(); HeaderPacket sslHeader = new HeaderPacket(); sslHeader.setPacketBodyLength(sslPacket.length); sslHeader.setPacketSequenceNumber((byte) (header.getPacketSequenceNumber() + 1)); @@ -225,23 +229,28 @@ public class MysqlConnector { connectionId = handshakePacket.threadId; // 记录一下connection serverVersion = handshakePacket.serverVersion; // 记录serverVersion logger.info("handshake initialization packet received, prepare the client authentication packet to send"); - logger.info("auth plugin: {}", new String(handshakePacket.authPluginName)); + // 某些老协议的 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); boolean isSha2Password = false; ClientAuthenticationPacket clientAuth; - if ("caching_sha2_password".equals(new String(handshakePacket.authPluginName))) { + if ("caching_sha2_password".equals(authPluginName)) { clientAuth = new ClientAuthenticationSHA2Packet(); isSha2Password = true; } else { clientAuth = new ClientAuthenticationPacket(); } - clientAuth.setCharsetNumber(handshakePacket.serverCharsetNumber); + clientAuth.setCharsetNumber(serverCharsetNumber); clientAuth.setUsername(username); clientAuth.setPassword(password); clientAuth.setServerCapabilities(handshakePacket.serverCapabilities); clientAuth.setDatabaseName(defaultSchema); clientAuth.setScrumbleBuff(joinAndCreateScrumbleBuff(handshakePacket)); - clientAuth.setAuthPluginName(handshakePacket.authPluginName); + clientAuth.setAuthPluginName(authPluginName.getBytes()); byte[] clientAuthPkgBody = clientAuth.toBytes(); HeaderPacket h = new HeaderPacket(); diff --git a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java index 6081afe9..f3a65cae 100644 --- a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java +++ b/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java @@ -109,7 +109,7 @@ public abstract class BioSocketChannelPool { } logger.info("SSL protocol: {}", StringUtils.join(protocolArr, ",")); sslSocket.setEnabledProtocols(protocolArr); - // sslSocket.setEnabledCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA".split(",")); + sslSocket.setSoTimeout(BioSocketChannel.SO_TIMEOUT); sslSocket.startHandshake(); logger.info("SSL socket handshake success."); return sslSocket;