|
46 | 46 | import com.github.shyiko.mysql.binlog.network.protocol.PacketChannel;
|
47 | 47 | import com.github.shyiko.mysql.binlog.network.protocol.ResultSetRowPacket;
|
48 | 48 | import com.github.shyiko.mysql.binlog.network.protocol.command.AuthenticateCommand;
|
| 49 | +import com.github.shyiko.mysql.binlog.network.protocol.command.AuthenticateNativePasswordCommand; |
49 | 50 | import com.github.shyiko.mysql.binlog.network.protocol.command.Command;
|
50 | 51 | import com.github.shyiko.mysql.binlog.network.protocol.command.DumpBinaryLogCommand;
|
51 | 52 | import com.github.shyiko.mysql.binlog.network.protocol.command.DumpBinaryLogGtidCommand;
|
@@ -722,8 +723,40 @@ private void authenticate(GreetingPacket greetingPacket) throws IOException {
|
722 | 723 | ErrorPacket errorPacket = new ErrorPacket(bytes);
|
723 | 724 | throw new AuthenticationException(errorPacket.getErrorMessage(), errorPacket.getErrorCode(),
|
724 | 725 | errorPacket.getSqlState());
|
| 726 | + } else if (authenticationResult[0] == (byte) 0xFE) { |
| 727 | + switchAuthentication(authenticationResult); |
| 728 | + } else { |
| 729 | + throw new AuthenticationException("Unexpected authentication result (" + authenticationResult[0] + ")"); |
| 730 | + } |
| 731 | + } |
| 732 | + } |
| 733 | + |
| 734 | + private void switchAuthentication(byte[] authenticationResult) throws IOException { |
| 735 | + /* |
| 736 | + Azure-MySQL likes to tell us to switch authentication methods, even though |
| 737 | + we haven't advertised that we support any. It uses this for some-odd |
| 738 | + reason to send the real password scramble. |
| 739 | + */ |
| 740 | + ByteArrayInputStream buffer = new ByteArrayInputStream(authenticationResult); |
| 741 | + buffer.read(1); |
| 742 | + |
| 743 | + String authName = buffer.readZeroTerminatedString(); |
| 744 | + if ("mysql_native_password".equals(authName)) { |
| 745 | + String scramble = buffer.readZeroTerminatedString(); |
| 746 | + |
| 747 | + Command switchCommand = new AuthenticateNativePasswordCommand(scramble, password); |
| 748 | + channel.writeBuffered(switchCommand, 3); |
| 749 | + byte[] authResult = channel.read(); |
| 750 | + |
| 751 | + if (authResult[0] != (byte) 0x00) { |
| 752 | + byte[] bytes = Arrays.copyOfRange(authResult, 1, authResult.length); |
| 753 | + ErrorPacket errorPacket = new ErrorPacket(bytes); |
| 754 | + throw new AuthenticationException(errorPacket.getErrorMessage(), errorPacket.getErrorCode(), |
| 755 | + errorPacket.getSqlState()); |
725 | 756 | }
|
726 |
| - throw new AuthenticationException("Unexpected authentication result (" + authenticationResult[0] + ")"); |
| 757 | + return; |
| 758 | + } else { |
| 759 | + throw new AuthenticationException("Unsupported authentication type: " + authName); |
727 | 760 | }
|
728 | 761 | }
|
729 | 762 |
|
|
0 commit comments