public override object GetPassword() { _authStage = AuthStage.GENERATE_SCRAMBLE; // If we have no password then we just return 1 zero byte. if (Settings.Password.Length == 0) { return(new byte[1]); } SHA256 sha = SHA256.Create(); byte[] firstHash = sha.ComputeHash(AliasText.Encoding.Default.GetBytes(Settings.Password)); byte[] secondHash = sha.ComputeHash(firstHash); byte[] input = new byte[AuthenticationData.Length + secondHash.Length]; Array.Copy(secondHash, 0, input, 0, secondHash.Length); Array.Copy(AuthenticationData, 0, input, secondHash.Length, AuthenticationData.Length); byte[] thirdHash = sha.ComputeHash(input); byte[] finalHash = new byte[thirdHash.Length]; for (int i = 0; i < firstHash.Length; i++) { finalHash[i] = (byte)(firstHash[i] ^ thirdHash[i]); } byte[] buffer = new byte[finalHash.Length + 1]; Array.Copy(finalHash, 0, buffer, 1, finalHash.Length); buffer[0] = 0x20; return(buffer); }
/// <summary> /// Generates a byte array set with the password of the user in the expected format based on the /// SSL settings of the current connection. /// </summary> /// <returns>A byte array that contains the password of the user in the expected format.</returns> protected byte[] GeneratePassword() { // If connection is secure perform full authentication. if (Settings.SslMode != MySqlSslMode.None) { _authStage = AuthStage.FULL_AUTH; // Send as clear text since the channel is already encrypted. byte[] passBytes = Encoding.GetBytes(Settings.Password); byte[] buffer = new byte[passBytes.Length + 1]; Array.Copy(passBytes, 0, buffer, 0, passBytes.Length); buffer[passBytes.Length] = 0; return(buffer); } else { // Request RSA key from server. if (rawPubkey != null && rawPubkey[0] == 4) { _authStage = AuthStage.REQUEST_RSA_KEY; return(new byte[] { 0x02 }); } else if (!Settings.AllowPublicKeyRetrieval) { throw new MySqlException(Resources.RSAPublicKeyRetrievalNotEnabled); } // Full authentication. else { _authStage = AuthStage.FULL_AUTH; byte[] bytes = GetRsaPassword(Settings.Password, AuthenticationData, rawPubkey); if (bytes != null && bytes.Length == 1 && bytes[0] == 0) { return(null); } return(bytes); } } }
protected override byte[] MoreData(byte[] data) { rawPubkey = data; // Generate scramble. if (data == null) { byte[] scramble = GetPassword() as byte[]; byte[] buffer = new byte[scramble.Length - 1]; Array.Copy(scramble, 1, buffer, 0, scramble.Length - 1); return(buffer); } // Fast authentication. else if (data[0] == 3) { _authStage = AuthStage.FAST_AUTH; return(null); } else { return(GeneratePassword() as byte[]); } }