66
77use  MySQLReplication \BinaryDataReader \BinaryDataReader ;
88use  MySQLReplication \Config \Config ;
9- use  MySQLReplication \Exception \MySQLReplicationException ;
109use  MySQLReplication \Gtid \GtidCollection ;
1110use  MySQLReplication \Repository \RepositoryInterface ;
1211use  MySQLReplication \Socket \SocketInterface ;
@@ -17,6 +16,7 @@ class BinLogSocketConnect
1716 private  const  COM_BINLOG_DUMP  = 0x12 ;
1817 private  const  COM_REGISTER_SLAVE  = 0x15 ;
1918 private  const  COM_BINLOG_DUMP_GTID  = 0x1e ;
19+  private  const  AUTH_SWITCH_PACKET  = 254 ;
2020 /** 
2121 * https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase.html 00 FE 
2222 */ 
@@ -47,7 +47,8 @@ public function __construct(
4747 'Server version name:  '  . $ this binLogServerInfo ->versionName  . ', revision:  '  . $ this binLogServerInfo ->versionRevision 
4848 );
4949
50-  $ this authenticate ();
50+ 
51+  $ this authenticate ($ this binLogServerInfo ->authPlugin );
5152 $ this getBinlogStream ();
5253 }
5354
@@ -110,56 +111,60 @@ private function isWriteSuccessful(string $data): void
110111 }
111112 }
112113
113-  private  function  authenticate (): void 
114+  private  function  authenticate (BinLogAuthPluginMode   $ authPlugin void 
114115 {
115-  if  ($ this binLogServerInfo ->authPlugin  === null ) {
116-  throw  new  MySQLReplicationException (
117-  MySQLReplicationException::BINLOG_AUTH_NOT_SUPPORTED ,
118-  MySQLReplicationException::BINLOG_AUTH_NOT_SUPPORTED_CODE 
119-  );
120-  }
121- 
122116 $ this logger ->info (
123-  'Trying to authenticate user:  '  . $ this config ->user  . ' using  '  . $ this -> binLogServerInfo -> authPlugin ->value  . ' plugin ' 
117+  'Trying to authenticate user:  '  . $ this config ->user  . ' using  '  . $ authPluginvalue  . ' default  plugin 
124118 );
125119
126120 $ datapack ('L ' , self ::getCapabilities ());
127121 $ datapack ('L ' , $ this binaryDataMaxLength );
128122 $ datachr (33 );
129123 $ datastr_repeat (chr (0 ), 23 );
130124 $ data$ this config ->user  . chr (0 );
131- 
132-  $ auth'' ;
133-  if  ($ this binLogServerInfo ->authPlugin  === BinLogAuthPluginMode::MysqlNativePassword) {
134-  $ auth$ this authenticateMysqlNativePasswordPlugin ();
135-  } elseif  ($ this binLogServerInfo ->authPlugin  === BinLogAuthPluginMode::CachingSha2Password) {
136-  $ auth$ this authenticateCachingSha2PasswordPlugin ();
137-  }
138- 
125+  $ auth$ this getAuthData ($ authPlugin$ this binLogServerInfo ->salt );
139126 $ datachr (strlen ($ auth$ auth
140-  $ data$ this -> binLogServerInfo -> authPlugin ->value  . chr (0 );
127+  $ data$ authPluginvalue  . chr (0 );
141128 $ strpack ('L ' , strlen ($ data
142129 $ s$ str0 ] . $ str1 ] . $ str2 ];
143130 $ data$ schr (1 ) . $ data
144131
145132 $ this socket ->writeToSocket ($ data
146-  $ this getResponse ();
133+  $ response$ this getResponse ();
134+ 
135+  // Check for AUTH_SWITCH_PACKET 
136+  if  (isset ($ response0 ]) && ord ($ response0 ]) === self ::AUTH_SWITCH_PACKET ) {
137+  $ this switchAuth ($ response
138+  }
147139
148140 $ this logger ->info ('User authenticated ' );
149141 }
150142
151-  private  function  authenticateCachingSha2PasswordPlugin (): string 
143+  private  function  getAuthData (?BinLogAuthPluginMode $ authPluginstring  $ saltstring 
144+  {
145+  if  ($ authPlugin
146+  return  $ this authenticateMysqlNativePasswordPlugin ($ salt
147+  }
148+ 
149+  if  ($ authPlugin
150+  return  $ this authenticateCachingSha2PasswordPlugin ($ salt
151+  }
152+ 
153+  return  '' ;
154+  }
155+ 
156+  private  function  authenticateCachingSha2PasswordPlugin (string  $ saltstring 
152157 {
153158 $ hash1hash ('sha256 ' , $ this config ->password , true );
154159 $ hash2hash ('sha256 ' , $ hash1true );
155-  $ hash3hash ('sha256 ' , $ hash2$ this -> binLogServerInfo -> salt , true );
160+  $ hash3hash ('sha256 ' , $ hash2$ salttrue );
156161 return  $ hash1$ hash3
157162 }
158163
159-  private  function  authenticateMysqlNativePasswordPlugin (): string 
164+  private  function  authenticateMysqlNativePasswordPlugin (string   $ salt string 
160165 {
161166 $ hash1sha1 ($ this config ->password , true );
162-  $ hash2sha1 ($ this -> binLogServerInfo -> salt  . sha1 (sha1 ($ this config ->password , true ), true ), true );
167+  $ hash2sha1 ($ saltsha1 (sha1 ($ this config ->password , true ), true ), true );
163168 return  $ hash1$ hash2
164169 }
165170
@@ -316,4 +321,17 @@ private function setBinLogDump(): void
316321
317322 $ this logger ->info ('Set binlog to start from:  '  . $ binFileName': '  . $ binFilePos
318323 }
324+ 
325+  private  function  switchAuth (string  $ responsevoid 
326+  {
327+  // skip AUTH_SWITCH_PACKET byte 
328+  $ offset1 ;
329+  $ authPluginSwitchedmake (BinaryDataReader::decodeNullLength ($ response$ offset
330+  $ saltdecodeNullLength ($ response$ offset
331+  $ auth$ this getAuthData ($ authPluginSwitched$ salt
332+ 
333+  $ this logger ->info ('Auth switch packet received, switching to  '  . $ authPluginSwitchedvalue );
334+ 
335+  $ this socket ->writeToSocket (pack ('L ' , (strlen ($ auth3  << 24 )) . $ auth
336+  }
319337}
0 commit comments