/// <summary>Ends connection with an IBM i system.</summary> public void Disconnect() { // TODO - code this.socketConnectorSignonVerify?.Disconnect(); this.socketConnectorSignonVerify = null; this.socketConnectorRemoteCommand?.Disconnect(); this.socketConnectorRemoteCommand = null; this.jobName = string.Empty; Debug.WriteLine("Connection with " + this.serverName + " was closed."); }
//----------------------------------------------------------------------- // Private methods //----------------------------------------------------------------------- /// <summary>Connects to the Sign-on Verify server</summary> private void ConnectToSignonVerifyServer() { // Establish authentication channel this.socketConnectorSignonVerify = new SocketConnector(this.serverName, this.useSSL ? TcpPortSignonVerifySSL : TcpPortSignonVerify, this.useSSL, this.ignoreSelfSignedCertificates); // Default current seed information this.clientSeed = 0; this.serverSeed = 0; // Exchange random seeds ulong clientSeed = (ulong)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; BigEndianMemoryStream outputStream = new BigEndianMemoryStream(); //// outputStream.WriteInt(52); // length outputStream.WriteShort(0); // Header ID (0) outputStream.WriteShort(ServerIDSignonVerify); // Server ID outputStream.WriteInt(0); // CS instance outputStream.WriteInt(0); // Correlation ID outputStream.WriteShort(0); // Template length outputStream.WriteShort(0x7003); // ReqReP ID outputStream.WriteInt(10); // Client version LL outputStream.WriteShort(0x1101); // Client version CP outputStream.WriteInt(1); // Client version outputStream.WriteInt(8); // Client data stream level LL outputStream.WriteShort(0x1102); // Client datastream level CP outputStream.WriteShort(2); // Client datastream level outputStream.WriteInt(14); // Client seed LL outputStream.WriteShort(0x1103); // Client seed CP outputStream.WriteLong(clientSeed); // Client seed 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("Seeds exchange failed. Bad response length."); } inputStream.Position += 16; uint resultCode = inputStream.ReadInt(); if (resultCode != 0) { throw new System.InvalidOperationException("Seeds exchange failed. Bad return code."); } 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 0x1101: // Server Version this.serverVersion = Converters.BigEndianToUInt32(dynamicFieldData); break; case 0x1102: // Server Level this.serverLevel = Converters.BigEndianToUInt16(dynamicFieldData); break; case 0x1103: // Server Seed this.serverSeed = Converters.BigEndianToUInt64(dynamicFieldData); break; case 0x1119: // Password Level this.passwordLevel = Converters.BigEndianToUInt8(dynamicFieldData); break; case 0x111F: // Job Name this.jobName = Converters.EbcdicToAsciiString(dynamicFieldData, 4); break; default: break; } } Debug.WriteLine("Seeds were exchanged, return code is 0x" + resultCode.ToString("X8")); this.clientSeed = clientSeed; }
/// <summary>Connects to the Remote Command server</summary> private void ConnectToRemoteCommandServer() { // Establish command channel this.socketConnectorRemoteCommand = new SocketConnector(this.serverName, this.useSSL ? TcpPortRemoteCommandSSL : TcpPortRemoteCommand, this.useSSL, this.ignoreSelfSignedCertificates); // Default current seed information this.clientSeed = 0; this.serverSeed = 0; // Exchange random seeds ulong clientSeed = (ulong)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds; BigEndianMemoryStream outputStream = new BigEndianMemoryStream(); outputStream.WriteByte(1); // Client attributes (1 = SHA-1 capability enabled) outputStream.WriteByte(0); // Server attributes outputStream.WriteShort(ServerIDRemoteCommand); // Server ID outputStream.WriteInt(0); // CS instance outputStream.WriteInt(0); // Correlation ID outputStream.WriteShort(8); // Template length outputStream.WriteShort(0x7001); // ReqReP ID outputStream.WriteLong(clientSeed); // Client seed 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 Server seed 8 */ // 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.ReadInt(); if (resultCode != 0) { throw new System.InvalidOperationException("Seeds exchange failed. Bad return code."); } this.serverSeed = inputStream.ReadLong(); this.clientSeed = clientSeed; Debug.WriteLine("Seeds were exchanged, return code is 0x" + resultCode.ToString("X8")); }