private DataFragment ReceivePacket() { while (true) { DataFragment data = _packetReceiver.WaitResponse(); SSH1PacketType pt = (SSH1PacketType)data[0]; //shortcut if (pt == SSH1PacketType.SSH_MSG_IGNORE) { SSH1DataReader r = new SSH1DataReader(data); r.ReadByte(); if (_eventReceiver != null) _eventReceiver.OnIgnoreMessage(r.ReadByteString()); } else if (pt == SSH1PacketType.SSH_MSG_DEBUG) { SSH1DataReader r = new SSH1DataReader(data); r.ReadByte(); if (_eventReceiver != null) _eventReceiver.OnDebugMessage(false, r.ReadByteString()); } else return data; } }
/// <summary> /// Process forwarded message. /// </summary> /// <param name="message">a forwarded message</param> private void ProcessMessage(DataFragment message) { if (_authKeyProvider == null || !_authKeyProvider.IsAuthKeyProviderEnabled) { SendFailure(); return; } SSH1DataReader reader = new SSH1DataReader(message); OpenSSHAgentForwardingMessageType messageType = (OpenSSHAgentForwardingMessageType)reader.ReadByte(); switch (messageType) { // for SSH1 keys case OpenSSHAgentForwardingMessageType.SSH_AGENTC_REQUEST_RSA_IDENTITIES: SSH1Identities(); break; case OpenSSHAgentForwardingMessageType.SSH_AGENTC_RSA_CHALLENGE: { reader.ReadUInt32(); // ignored BigInteger e = reader.ReadMPInt(); BigInteger n = reader.ReadMPInt(); BigInteger encryptedChallenge = reader.ReadMPInt(); byte[] sessionId = reader.Read(16); uint responseType = reader.ReadUInt32(); SSH1IRSAChallenge(e, n, encryptedChallenge, sessionId, responseType); } break; // for SSH2 keys case OpenSSHAgentForwardingMessageType.SSH2_AGENTC_REQUEST_IDENTITIES: SSH2Identities(); break; case OpenSSHAgentForwardingMessageType.SSH2_AGENTC_SIGN_REQUEST: { byte[] blob = reader.ReadByteString(); byte[] data = reader.ReadByteString(); uint flags = reader.ReadUInt32(); SSH2Sign(blob, data, flags); } break; default: SendFailure(); break; } }
internal void AsyncReceivePacket(DataFragment data) { try { SSH1DataReader re = new SSH1DataReader(data); SSH1PacketType pt = (SSH1PacketType)re.ReadByte(); switch (pt) { case SSH1PacketType.SSH_SMSG_STDOUT_DATA: { int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(_shellID).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_SMSG_STDERR_DATA: { _channel_collection.FindChannelEntry(_shellID).Receiver.OnExtendedData((int)SSH1PacketType.SSH_SMSG_STDERR_DATA, re.ReadByteString()); } break; case SSH1PacketType.SSH_MSG_CHANNEL_DATA: { int channel = re.ReadInt32(); int len = re.ReadInt32(); DataFragment frag = re.GetRemainingDataView(len); _channel_collection.FindChannelEntry(channel).Receiver.OnData(frag.Data, frag.Offset, frag.Length); } break; case SSH1PacketType.SSH_MSG_PORT_OPEN: ProcessPortforwardingRequest(_eventReceiver, re); break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE: { int channel = re.ReadInt32(); ISSHChannelEventReceiver r = _channel_collection.FindChannelEntry(channel).Receiver; _channel_collection.UnregisterChannelEventReceiver(channel); r.OnChannelClosed(); } break; case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: { int channel = re.ReadInt32(); } break; case SSH1PacketType.SSH_MSG_DISCONNECT: _eventReceiver.OnConnectionClosed(); break; case SSH1PacketType.SSH_SMSG_EXITSTATUS: _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelClosed(); break; case SSH1PacketType.SSH_MSG_DEBUG: _eventReceiver.OnDebugMessage(false, re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_IGNORE: _eventReceiver.OnIgnoreMessage(re.ReadByteString()); break; case SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: { int local = re.ReadInt32(); int remote = re.ReadInt32(); _channel_collection.FindChannelEntry(local).Receiver.OnChannelReady(); } break; case SSH1PacketType.SSH_SMSG_SUCCESS: if (_executingShell) { ExecShell(); _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelReady(); _executingShell = false; } break; default: _eventReceiver.OnUnknownMessage((byte)pt, data.GetBytes()); break; } } catch (Exception ex) { _eventReceiver.OnError(ex); } }
/// <summary> /// Read SSH1 private key parameters. /// </summary> /// <param name="passphrase">passphrase for decrypt the key file</param> /// <param name="modulus">private key parameter</param> /// <param name="publicExponent">private key parameter</param> /// <param name="privateExponent">private key parameter</param> /// <param name="primeP">private key parameter</param> /// <param name="primeQ">private key parameter</param> /// <param name="crtCoefficient">private key parameter</param> /// <exception cref="SSHException">failed to parse</exception> public void Load( string passphrase, out BigInteger modulus, out BigInteger publicExponent, out BigInteger privateExponent, out BigInteger primeP, out BigInteger primeQ, out BigInteger crtCoefficient) { if (keyFile == null) throw new SSHException("A key file is not loaded yet"); byte[] hdr = Encoding.ASCII.GetBytes(PrivateKeyFileHeader.SSH1_HEADER); if (!ByteArrayUtil.ByteArrayStartsWith(keyFile, hdr)) throw new SSHException(Strings.GetString("NotValidPrivateKeyFile")); SSH1DataReader reader = new SSH1DataReader(keyFile); reader.Read(hdr.Length); byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space reader.Read(8); modulus = reader.ReadMPInt(); publicExponent = reader.ReadMPInt(); byte[] comment = reader.ReadByteString(); byte[] prvt = reader.GetRemainingDataView().GetBytes(); //必要なら復号 CipherAlgorithm algo = (CipherAlgorithm)cipher[1]; if (algo != 0) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, SSH1PassphraseToKey(passphrase)); c.Decrypt(prvt, 0, prvt.Length, prvt, 0); } SSH1DataReader prvtreader = new SSH1DataReader(prvt); byte[] mark = prvtreader.Read(4); if (mark[0] != mark[2] || mark[1] != mark[3]) throw new SSHException(Strings.GetString("WrongPassphrase")); privateExponent = prvtreader.ReadMPInt(); crtCoefficient = prvtreader.ReadMPInt(); primeP = prvtreader.ReadMPInt(); primeQ = prvtreader.ReadMPInt(); }