/// <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));
        }
Beispiel #3
0
        /// <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));
        }
Beispiel #6
0
        /// <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.");
        }
Beispiel #7
0
        /// <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.");
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #10
0
        //-----------------------------------------------------------------------
        // 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));
            }
        }