From 209fb1eb12453452aaa69e3313e72f50724c9b0e Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Sun, 3 Jan 2021 13:42:28 +0900 Subject: [PATCH 1/3] Remove old_password support --- pymysql/_auth.py | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/pymysql/_auth.py b/pymysql/_auth.py index d16a0895..389fd445 100644 --- a/pymysql/_auth.py +++ b/pymysql/_auth.py @@ -2,7 +2,7 @@ Implements auth methods """ from .err import OperationalError -from .util import byte2int, int2byte +from .util import byte2int try: @@ -16,9 +16,7 @@ from functools import partial import hashlib -import io import struct -import warnings DEBUG = False @@ -53,49 +51,6 @@ def _my_crypt(message1, message2): return bytes(result) -# old_passwords support ported from libmysql/password.c -# https://dev.mysql.com/doc/internals/en/old-password-authentication.html - -SCRAMBLE_LENGTH_323 = 8 - - -class RandStruct_323: - def __init__(self, seed1, seed2): - self.max_value = 0x3FFFFFFF - self.seed1 = seed1 % self.max_value - self.seed2 = seed2 % self.max_value - - def my_rnd(self): - self.seed1 = (self.seed1 * 3 + self.seed2) % self.max_value - self.seed2 = (self.seed1 + self.seed2 + 33) % self.max_value - return float(self.seed1) / float(self.max_value) - - -def scramble_old_password(password, message): - """Scramble for old_password""" - warnings.warn( - "old password (for MySQL <4.1) is used. Upgrade your password with newer auth method.\n" - "old password support will be removed in future PyMySQL version" - ) - hash_pass = _hash_password_323(password) - hash_message = _hash_password_323(message[:SCRAMBLE_LENGTH_323]) - hash_pass_n = struct.unpack(">LL", hash_pass) - hash_message_n = struct.unpack(">LL", hash_message) - - rand_st = RandStruct_323( - hash_pass_n[0] ^ hash_message_n[0], hash_pass_n[1] ^ hash_message_n[1] - ) - outbuf = io.BytesIO() - for _ in range(min(SCRAMBLE_LENGTH_323, len(message))): - outbuf.write(int2byte(int(rand_st.my_rnd() * 31) + 64)) - extra = int2byte(int(rand_st.my_rnd() * 31)) - out = outbuf.getvalue() - outbuf = io.BytesIO() - for c in out: - outbuf.write(int2byte(byte2int(c) ^ byte2int(extra))) - return outbuf.getvalue() - - def _hash_password_323(password): nr = 1345345333 add = 7 From 2aacb6b510231bc934d5c5d2a8900d56c785f225 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Sun, 3 Jan 2021 13:45:22 +0900 Subject: [PATCH 2/3] remove more --- pymysql/_auth.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/pymysql/_auth.py b/pymysql/_auth.py index 389fd445..33fd9df8 100644 --- a/pymysql/_auth.py +++ b/pymysql/_auth.py @@ -2,7 +2,6 @@ Implements auth methods """ from .err import OperationalError -from .util import byte2int try: @@ -16,7 +15,6 @@ from functools import partial import hashlib -import struct DEBUG = False @@ -51,22 +49,6 @@ def _my_crypt(message1, message2): return bytes(result) -def _hash_password_323(password): - nr = 1345345333 - add = 7 - nr2 = 0x12345671 - - # x in py3 is numbers, p27 is chars - for c in [byte2int(x) for x in password if x not in (" ", "\t", 32, 9)]: - nr ^= (((nr & 63) + add) * c) + (nr << 8) & 0xFFFFFFFF - nr2 = (nr2 + ((nr2 << 8) ^ nr)) & 0xFFFFFFFF - add = (add + c) & 0xFFFFFFFF - - r1 = nr & ((1 << 31) - 1) # kill sign bits - r2 = nr2 & ((1 << 31) - 1) - return struct.pack(">LL", r1, r2) - - # MariaDB's client_ed25519-plugin # https://mariadb.com/kb/en/library/connection/#client_ed25519-plugin From d67a99b8f81e3c23f73b68a06faad69ef1321cbf Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Sun, 3 Jan 2021 13:47:04 +0900 Subject: [PATCH 3/3] remove more --- pymysql/connections.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/pymysql/connections.py b/pymysql/connections.py index dc69868b..bdeddbef 100644 --- a/pymysql/connections.py +++ b/pymysql/connections.py @@ -926,16 +926,7 @@ def _request_authentication(self): # https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest auth_packet.read_uint8() # 0xfe packet identifier plugin_name = auth_packet.read_string() - if ( - self.server_capabilities & CLIENT.PLUGIN_AUTH - and plugin_name is not None - ): - auth_packet = self._process_auth(plugin_name, auth_packet) - else: - # send legacy handshake - data = _auth.scramble_old_password(self.password, self.salt) + b"\0" - self.write_packet(data) - auth_packet = self._read_packet() + auth_packet = self._process_auth(plugin_name, auth_packet) elif auth_packet.is_extra_auth_data(): if DEBUG: print("received extra data") @@ -973,11 +964,6 @@ def _process_auth(self, plugin_name, auth_packet): data = _auth.scramble_native_password(self.password, auth_packet.read_all()) elif plugin_name == b"client_ed25519": data = _auth.ed25519_password(self.password, auth_packet.read_all()) - elif plugin_name == b"mysql_old_password": - data = ( - _auth.scramble_old_password(self.password, auth_packet.read_all()) - + b"\0" - ) elif plugin_name == b"mysql_clear_password": # https://dev.mysql.com/doc/internals/en/clear-text-authentication.html data = self.password + b"\0"