/// <summary>Prepares user name for usage DES algorithm according to RFC2877 5.1. step 4</summary> /// <param name="userName">User name in ASCII</param> /// <returns>User name as EBCDIC byte stream</returns> private static byte[] PrepareUserNameDES(string userName) { byte[] usernameEBCDIC = new byte[8]; if (userName.Length <= 8) { usernameEBCDIC = Converters.AsciiToEbcdic(userName.ToUpper().PadRight(8)); } else { usernameEBCDIC = Converters.AsciiToEbcdic(userName.ToUpper().Substring(0, 8)); byte usernameEBCDIC_9 = Converters.AsciiToEbcdic(userName.ToUpper().PadRight(10).Substring(8, 1))[0]; byte usernameEBCDIC_10 = Converters.AsciiToEbcdic(userName.ToUpper().PadRight(10).Substring(9, 1))[0]; usernameEBCDIC[0] ^= (byte)(usernameEBCDIC_9 & 0xC0); usernameEBCDIC[1] ^= (byte)(((usernameEBCDIC_9 & 0x30) << 2) & 0xFF); usernameEBCDIC[2] ^= (byte)(((usernameEBCDIC_9 & 0x0C) << 4) & 0xFF); usernameEBCDIC[3] ^= (byte)((usernameEBCDIC_9 << 6) & 0xFF); usernameEBCDIC[4] ^= (byte)(usernameEBCDIC_10 & 0xC0); usernameEBCDIC[5] ^= (byte)(((usernameEBCDIC_10 & 0x30) << 2) & 0xFF); usernameEBCDIC[6] ^= (byte)(((usernameEBCDIC_10 & 0x0C) << 4) & 0xFF); usernameEBCDIC[7] ^= (byte)((usernameEBCDIC_10 << 6) & 0xFF); } return(usernameEBCDIC); }
/// <summary>Encrypts password using IBM's flavor of DES algorithm as defined in RFC2877</summary> /// <param name="userName">User name in ASCII</param> /// <param name="password">Password in ASCII</param> /// <param name="serverSeed">Server's seed</param> /// <param name="clientSeed">Client's seed</param> /// <returns>Encrypted password as EBCDIC byte stream</returns> public static byte[] EncryptPasswordDES(string userName, string password, ulong serverSeed, ulong clientSeed) { byte[] passwordToken = new byte[8]; if (password.Length > 8) { byte[] passwordTokenA = GenerateToken(userName, password.Substring(0, 8)); byte[] passwordTokenB = GenerateToken(userName, password.Substring(8)); passwordToken = Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(passwordTokenA) ^ Converters.BigEndianToUInt64(passwordTokenB)); } else { passwordToken = GenerateToken(userName, password); } byte[] usernameEBCDIC_A; byte[] usernameEBCDIC_B; if (userName.Length <= 8) { usernameEBCDIC_A = Converters.AsciiToEbcdic(userName.ToUpper().PadRight(8)); usernameEBCDIC_B = Converters.UInt64ToBigEndian(0x4040404040404040); } else { usernameEBCDIC_A = Converters.AsciiToEbcdic(userName.Substring(0, 8).ToUpper().PadRight(8)); usernameEBCDIC_B = Converters.AsciiToEbcdic(userName.Substring(8).ToUpper().PadRight(8)); } byte[] firstEncryptionRound = EncryptDES(Converters.UInt64ToBigEndian(serverSeed + 1), passwordToken); byte[] secondEncryptionRound = EncryptDES(Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(firstEncryptionRound) ^ clientSeed), passwordToken); byte[] thirdEncryptionRound = EncryptDES(Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(usernameEBCDIC_A) ^ (serverSeed + 1) ^ Converters.BigEndianToUInt64(secondEncryptionRound)), passwordToken); byte[] fourthEncryptionRound = EncryptDES(Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(usernameEBCDIC_B) ^ (serverSeed + 1) ^ Converters.BigEndianToUInt64(thirdEncryptionRound)), passwordToken); return(EncryptDES(Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(fourthEncryptionRound) ^ 0x0000000000000001), passwordToken)); }
/// <summary>Sets user's password to a specified value</summary> /// <param name="userName">User name</param> /// <param name="newPassword">New password to be set</param> /// <param name="currentPassword">User's current password (optional if user is *SECADM and has at least *USE authority to the profile)</param> public void ChangeUserPassword(string userName, string newPassword, string currentPassword = "******") { /* * https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/apis/QSYCHGPW.htm * * Required Parameter Group: * * 1 User ID Input Char(10) * 2 Current password Input Char(*) * 3 New password Input Char(*) * 4 Error code I/O Char(*) * 5 Length of current password Input Bin(4) * 6 CCSID of current password Input Bin(4) -> 0 * 7 Length of new password Input Bin(4) * 8 CCSID of new password Input Bin(4) -> 0 */ ProgramCallParameters qsychgpwCallParameters = new ProgramCallParameters(8) { [0] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic(userName.ToUpper().PadRight(10))), [1] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic(currentPassword)), [2] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic(newPassword)), [3] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInputOutput, null, 500), [4] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian((uint)currentPassword.Length)), [5] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(0)), [6] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian((uint)newPassword.Length)), [7] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(0)) }; CallMessages qsychgpwCallMessages = new CallMessages(); if (CallProgram("qsychgpw", "QSYS", ref qsychgpwCallParameters, ref qsychgpwCallMessages) != 0) { foreach (CallMessage outputMessage in qsychgpwCallMessages) { Debug.WriteLine(outputMessage.MessageText); } throw new System.InvalidOperationException("The method ChangeUserPassword failed. Check debug information."); } }
public UserProfile GetUserInfo(string userName) { /* * https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/apis/qsyrusri.htm * * Required Parameter Group: * * 1 Receiver variable Output Char(*) - 120000B * 2 Length of receiver variable Input Binary(4) - 120000 * 3 Format name Input Char(8) - "USRI0300" * 4 User profile name Input Char(10) - userName * 5 Error code I/O Char(*) */ ProgramCallParameters qsyrusriCallParameters = new ProgramCallParameters(5) { [0] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeOutput, null, 120000), [1] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(120000)), [2] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic("USRI0300")), [3] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic(userName.ToUpper().PadRight(10))), [4] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInputOutput, null, 500) }; CallMessages qsyrusriCallMessages = new CallMessages(); if (CallProgram("qsyrusri", "QSYS", ref qsyrusriCallParameters, ref qsyrusriCallMessages) != 0) { foreach (CallMessage outputMessage in qsyrusriCallMessages) { Debug.WriteLine(outputMessage.MessageText); } throw new System.InvalidOperationException("The method GetUserInfo failed. Check debug information."); } return(new UserProfile(qsyrusriCallParameters[0].ParameterValue)); }
/// <summary>Creates an intermediary password token using DES algorithm</summary> /// <param name="userName">User name in ASCII</param> /// <param name="password">Password in ASCII</param> /// <returns>Encrypted password token as EBCDIC byte stream</returns> private static byte[] GenerateToken(string userName, string password) { if (password.Length > 8) { throw new System.InvalidOperationException("Wrong method invocation: password cannot be longer than 8"); } if (userName.Length > 10) { throw new System.InvalidOperationException("Wrong method invocation: user name cannot be longer than 10"); } byte[] passwordEBCDIC = Converters.AsciiToEbcdic(password.ToUpper().PadRight(8)); byte[] encryptionKey = Converters.UInt64ToBigEndian((Converters.BigEndianToUInt64(passwordEBCDIC) ^ 0x5555555555555555) << 1); byte[] usernameEBCDIC = PrepareUserNameDES(userName); return(EncryptDES(usernameEBCDIC, encryptionKey)); }
/// <summary>Authenticates the user to the remote command server</summary> private void AuthenticateToRemoteCommandServer() { // Establish command channel if (this.socketConnectorRemoteCommand == null) { throw new System.InvalidOperationException("Operation failed, connection not established."); } BigEndianMemoryStream outputStream = new BigEndianMemoryStream(); byte[] encryptedPassword; byte[] userID = Converters.AsciiToEbcdic(this.userName.ToUpper().PadRight(10)); encryptedPassword = this.passwordLevel < 2 ? Encryption.EncryptPasswordDES(this.userName, this.password, this.serverSeed, this.clientSeed) : Encryption.EncryptPasswordSHA1(this.userName, this.password, this.serverSeed, this.clientSeed); outputStream.WriteByte(2); // Client attributes (2: return job information) outputStream.WriteByte(0); // Server attributes outputStream.WriteShort(ServerIDRemoteCommand); // Server ID outputStream.WriteInt(0); // CS instance outputStream.WriteInt(0); // Correlation ID outputStream.WriteShort(2); // Template length outputStream.WriteShort(0x7002); // ReqReP ID outputStream.WriteByte((byte)(this.passwordLevel < 2 ? 1 : 3)); // Password encryption type outputStream.WriteByte(1); // Send reply outputStream.WriteInt(6 + (uint)encryptedPassword.Length); // Password LL outputStream.WriteShort(0x1105); // Password CP. 0x1115 is other. outputStream.Write(encryptedPassword, 0, encryptedPassword.Length); // Password outputStream.WriteInt(16); // User ID LL outputStream.WriteShort(0x1104); // User ID CP outputStream.Write(userID, 0, userID.Length); // UserID this.socketConnectorRemoteCommand.Write(outputStream.ToArray()); // Retrieve server response byte[] response = this.socketConnectorRemoteCommand.Read(); BigEndianMemoryStream inputStream = new BigEndianMemoryStream(); inputStream.Write(response, 0, response.Length); /* * The response comes in the following format: * * Offset (byte) Information Length (byte) * ----------------------------------------------------------- * Fixed header * ----------------------------------------------------------- * 0 Response length 4 * 4 (Reserved) 16 * 20 Result code 4 * 24 (Dynamic fields) see below * ----------------------------------------------------------- * Dynamic fields (Offset is dynamic) * ----------------------------------------------------------- * 0 Field length 4 * 4 Field code 2 * 6 Field data (Field length - 6) */ // Read fixed header inputStream.Position = 0; uint responseLength = inputStream.ReadInt(); if (responseLength < 20) { throw new System.InvalidOperationException("Authentication failed. Bad response length."); } inputStream.Position += 16; uint resultCode = inputStream.ReadInt(); if (resultCode != 0) { if ((resultCode & 0xFFFF0000) == 0x00010000) { throw new System.InvalidOperationException("Authentication failed. Error on request data."); } if ((resultCode & 0xFFFF0000) == 0x00040000) { throw new System.InvalidOperationException("Authentication failed. General security error, function not performed."); } if ((resultCode & 0xFFFF0000) == 0x00060000) { throw new System.InvalidOperationException("Authentication failed. Authentication token error."); } switch (resultCode) { case 0x00020001: throw new System.InvalidOperationException("Authentication failed. User ID unknown."); case 0x00020002: throw new System.InvalidOperationException("Authentication failed. User ID locked."); case 0x00020003: throw new System.InvalidOperationException("Authentication failed. User ID doesn't match the authentication token."); case 0x0003000B: throw new System.InvalidOperationException("Authentication failed. Password incorrect."); case 0x0003000C: throw new System.InvalidOperationException("Authentication failed. Password incorrect. User profile will be revoked on next invalid password or passphrase."); case 0x0003000D: throw new System.InvalidOperationException("Authentication failed. Password is expired."); case 0x0003000E: throw new System.InvalidOperationException("Authentication failed. Pre-V2R2 encrypted password."); case 0x00030010: throw new System.InvalidOperationException("Authentication failed. Password is *NONE."); default: throw new System.InvalidOperationException("Authentication failed. Return code 0x" + resultCode.ToString("X8")); } } while (inputStream.Position < responseLength) { uint dynamicFieldLength = inputStream.ReadInt(); ushort dynamicFieldCode = inputStream.ReadShort(); byte[] dynamicFieldData = new byte[dynamicFieldLength - 6]; inputStream.Read(dynamicFieldData, 0, (int)dynamicFieldLength - 6); switch (dynamicFieldCode) { case 0x111F: // Server Version this.jobName = Converters.EbcdicToAsciiString(dynamicFieldData, 4); break; default: break; } } Debug.WriteLine("User authenticated to remote command server."); }
/// <summary>Authenticates the user to the signon server</summary> private void AuthenticateToSignonVerifyServer() { BigEndianMemoryStream outputStream = new BigEndianMemoryStream(); byte[] encryptedPassword; byte[] userID = Converters.AsciiToEbcdic(this.userName.ToUpper().PadRight(10)); encryptedPassword = this.passwordLevel < 2 ? Encryption.EncryptPasswordDES(this.userName, this.password, this.serverSeed, this.clientSeed) : Encryption.EncryptPasswordSHA1(this.userName, this.password, this.serverSeed, this.clientSeed); if (this.serverLevel >= 5) { outputStream.WriteShort(0); // Header ID (0) } outputStream.WriteShort(ServerIDSignonVerify); // Server ID outputStream.WriteInt(0); // CS instance outputStream.WriteInt(0); // Correlation ID outputStream.WriteShort(0x0001); // Template length outputStream.WriteShort(0x7004); // ReqReP ID outputStream.WriteByte((byte)(this.passwordLevel < 2 ? 1 : 3)); // Password encryption type outputStream.WriteInt(10); // Client CCSID LL outputStream.WriteShort(0x1113); // Client CCSID CP outputStream.WriteInt(1200); // Client CCSID (big endian UTF-16) outputStream.WriteInt(6 + (uint)encryptedPassword.Length); // Password LL outputStream.WriteShort(0x1105); // Password CP. 0x1115 is other. outputStream.Write(encryptedPassword, 0, encryptedPassword.Length); // Password outputStream.WriteInt(16); // User ID LL outputStream.WriteShort(0x1104); // User ID CP outputStream.Write(userID, 0, userID.Length); // UserID if (this.serverLevel >= 5) { outputStream.WriteInt(7); // Return error messages LL outputStream.WriteShort(0x1128); // Return error messages CP outputStream.WriteByte(1); // Return error messages } this.socketConnectorSignonVerify.Write(outputStream.ToArray()); // Retrieve server response byte[] response = this.socketConnectorSignonVerify.Read(); BigEndianMemoryStream inputStream = new BigEndianMemoryStream(); inputStream.Write(response, 0, response.Length); /* * The response comes in the following format: * * Offset (byte) Information Length (byte) * ----------------------------------------------------------- * Fixed header * ----------------------------------------------------------- * 0 Response length 4 * 4 (Reserved) 16 * 20 Result code 4 * 24 (Dynamic fields) see below * ----------------------------------------------------------- * Dynamic fields (Offset is dynamic) * ----------------------------------------------------------- * 0 Field length 4 * 4 Field code 2 * 6 Field data (Field length - 6) */ // Read fixed header inputStream.Position = 0; uint responseLength = inputStream.ReadInt(); if (responseLength < 20) { throw new System.InvalidOperationException("Authentication failed. Bad response length."); } inputStream.Position += 16; uint resultCode = inputStream.ReadInt(); if (resultCode != 0) { switch (resultCode) { case 0x00020001: throw new System.InvalidOperationException("Authentication failed. Unknown username."); case 0x0003000B: throw new System.InvalidOperationException("Authentication failed. Wrong password."); case 0x0003000C: throw new System.InvalidOperationException("Authentication failed. Wrong password. Profile will be disabled on the next invalid password."); case 0x0003000D: throw new System.InvalidOperationException("Authentication failed. Password is expired."); case 0x00030010: throw new System.InvalidOperationException("Authentication failed. Password is *NONE."); default: throw new System.InvalidOperationException("Authentication failed. Return code 0x" + resultCode.ToString("X8")); } } while (inputStream.Position < responseLength) { uint dynamicFieldLength = inputStream.ReadInt(); ushort dynamicFieldCode = inputStream.ReadShort(); byte[] dynamicFieldData = new byte[dynamicFieldLength - 6]; inputStream.Read(dynamicFieldData, 0, (int)dynamicFieldLength - 6); switch (dynamicFieldCode) { case 0x1114: // Server Version this.serverCCSID = Converters.BigEndianToUInt32(dynamicFieldData); break; default: break; } } Debug.WriteLine("User authenticated to signon server."); }
/// <summary>Retrieves server information</summary> private void RetrieveRemoteCommandServerInformation() { // Establish command channel if (this.socketConnectorRemoteCommand == null) { throw new System.InvalidOperationException("Operation failed, connection not established."); } BigEndianMemoryStream outputStream = new BigEndianMemoryStream(); outputStream.WriteShort(0); // Header ID outputStream.WriteShort(ServerIDRemoteCommand); // Server ID outputStream.WriteInt(0); // CS instance outputStream.WriteInt(0); // Correlation ID outputStream.WriteShort(14); // Template length outputStream.WriteShort(0x1001); // ReqReP ID outputStream.WriteInt(1200); // Operation is CCSID outputStream.Write(Converters.AsciiToEbcdic("2924"), 0, 4); // NLV value (default = 2924 = English) outputStream.WriteInt(1); // Client version outputStream.WriteShort(0); // Client datastream level this.socketConnectorRemoteCommand.Write(outputStream.ToArray()); // Retrieve server response byte[] response = this.socketConnectorRemoteCommand.Read(); BigEndianMemoryStream inputStream = new BigEndianMemoryStream(); inputStream.Write(response, 0, response.Length); /* * The response comes in the following format: * * Offset (byte) Information Length (byte) * ----------------------------------------------------------- * Fixed header * ----------------------------------------------------------- * 0 Response length 4 * 4 (Reserved) 16 * 20 Result code 2 * 24 CCSID 4 * 28 NLV (in EBCDIC) 4 * 32 (reserved) 4 * 36 Datastream level 2 */ // Read fixed header inputStream.Position = 0; uint responseLength = inputStream.ReadInt(); if (responseLength < 20) { throw new System.InvalidOperationException("Seeds exchange failed. Bad response length."); } inputStream.Position += 16; uint resultCode = inputStream.ReadShort(); // We ignore the same return codes that JTOPEN/JT400 ignores if (resultCode != 0x0100 && // User with *LMTCPB = *YES resultCode != 0x0104 && // Invalid CCSID. resultCode != 0x0105 && // Invalid NLV, default to primary NLV: resultCode != 0x0106 && // NLV not installed, default to primary NLV: // The NLV may not be supported or it may not be installed on the system. resultCode != 0x0107 && // Error retrieving product information. Can't validate NLV. resultCode != 0x0108 && // Error trying to add NLV library to system library list: // One possible reason for failure is the user may not be authorized to CHGSYSLIBL command. resultCode != 0) { throw new System.InvalidOperationException("Invalid operation, failed to retrieve Remote Command server attributes."); } this.serverCCSID = inputStream.ReadInt(); byte[] nlv = new byte[4]; inputStream.Read(nlv, 0, 4); this.serverNLV = Converters.EbcdicToAsciiString(nlv); inputStream.Position += 4; this.serverDatastreamLevel = inputStream.ReadShort(); Debug.WriteLine("Remote Command server attributes retrieved, return code is 0x" + resultCode.ToString("X8")); }
//----------------------------------------------------------------------- // Class methods //----------------------------------------------------------------------- public string[] GetUsersList() { /* * https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/apis/qgyolaus.htm * * Required Parameter Group: * * 1 Receiver variable Output Char(*) - 120000B * 2 Length of receiver variable Input Binary(4) - 120000 * 3 List information Output Char(80) * 4 Number of records to return Input Binary(4) - "9999" * 5 Format name Input Char(8) - "AUTU0100" * 6 Selection criteria Input Char(10) - "*ALL" * 7 Group profile name Input Char(10) - "*NONE" * 8 Error code I/O Char(*) */ ProgramCallParameters qgyolausCallParameters = new ProgramCallParameters(8) { [0] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeOutput, null, 120000), [1] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(120000)), [2] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeOutput, null, 80), [3] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(9999)), [4] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic("AUTU0100")), [5] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic("*ALL ")), [6] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic("*NONE ")), [7] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInputOutput, null, 500) }; CallMessages qgyolausCallMessages = new CallMessages(); if (CallProgram("QGYOLAUS", "QSYS", ref qgyolausCallParameters, ref qgyolausCallMessages) != 0) { foreach (CallMessage outputMessage in qgyolausCallMessages) { Debug.WriteLine(outputMessage.MessageText); } throw new System.InvalidOperationException("The method GetUserList failed. Check debug information."); } uint numEntries = Converters.BigEndianToUInt32(qgyolausCallParameters[2].ParameterValue, 0, 4); if (numEntries <= 0) { return(null); } string[] userList = new string[numEntries]; for (int i = 0; i < numEntries; i++) { userList[i] = Converters.EbcdicToAsciiString(qgyolausCallParameters[0].ParameterValue, (uint)i * 12, 10); } return(userList); }
//----------------------------------------------------------------------- // Class methods //----------------------------------------------------------------------- /// <summary>Returns password hash of the specified user, in specified format</summary> /// <param name="system">System to be connected to</param> /// <param name="userName">User name</param> /// <param name="hashType">Predefined password hash type (see documentation for details)</param> /// <returns>Password hash as a hex string</returns> public string GetEncryptedPassword(string userName, int hashType) { /* * http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=%2Fapis%2Fqsyrupwd.htm * * Required Parameter Group: * * 1 Receiver variable Output Char(*) - 2000B * 2 Length of receiver variable Input Binary(4) * 3 Format Input Char(8) - "UPWD0100" * 4 User profile name Input Char(10) - userName * 5 Error code I/O Char(*) */ ProgramCallParameters qsyrupwdCallParameters = new ProgramCallParameters(5) { [0] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeOutput, null, 2000), [1] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.UInt32ToBigEndian(2000)), [2] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic("UPWD0100")), [3] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInput, Converters.AsciiToEbcdic(userName.ToUpper().PadRight(10))), [4] = new ProgramCallParameter( ProgramCallParameter.ParameterTypeInputOutput, null, 500) }; CallMessages qsyrupwdCallMessages = new CallMessages(); if (CallProgram("QSYRUPWD", "QSYS", ref qsyrupwdCallParameters, ref qsyrupwdCallMessages) != 0) { foreach (CallMessage outputMessage in qsyrupwdCallMessages) { Debug.WriteLine(outputMessage.MessageText); } throw new System.InvalidOperationException("The method GetEncryptedPassword failed. Check debug information."); } switch (hashType) { case PASSWORD_HASH_ALLDATA: // All data return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 1, 269)); case PASSWORD_HASH_UNKNOWNHASH: // Unknown (hash?) data return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 78, 192)); case PASSWORD_HASH_HMACSHA1MC: // HMAC-SHA1 password (mixed case) return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 35, 20)); case PASSWORD_HASH_HMACSHA1UC: // HMAC-SHA1 password (uppercase) return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 55, 20)); case PASSWORD_HASH_LMHASH: // LM hash return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 17, 16)); case PASSWORD_HASH_DES: // Composed DES hash (PW_TOKENa XOR PW_TOKENb): return(Converters.BigEndianToHexString(Converters.UInt64ToBigEndian(Converters.BigEndianToUInt64(qsyrupwdCallParameters[0].ParameterValue, 1, 8) ^ Converters.BigEndianToUInt64(qsyrupwdCallParameters[0].ParameterValue, 9, 8)))); case PASSWORD_HASH_SECONDDES: // Second DES password token (PW_TOKENb) return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 9, 8)); case PASSWORD_HASH_FIRSTDES: // First DES password (PW_TOKENa) default: return(Converters.BigEndianToHexString(qsyrupwdCallParameters[0].ParameterValue, 1, 8)); } }