Beispiel #1
0
        private bool ProcessPacket(DataFragment packet)
        {
            SSH2DataReader r = new SSH2DataReader(packet);
            SSH2PacketType pt = (SSH2PacketType) r.ReadByte();

            if (pt == SSH2PacketType.SSH_MSG_DISCONNECT) {
                int errorcode = r.ReadInt32();
                _eventReceiver.OnConnectionClosed();
                return false;
            }
            else if (_waitingForPortForwardingResponse) {
                if (pt != SSH2PacketType.SSH_MSG_REQUEST_SUCCESS)
                    _eventReceiver.OnUnknownMessage((byte)pt, packet.GetBytes());
                _waitingForPortForwardingResponse = false;
                return true;
            }
            else if (pt == SSH2PacketType.SSH_MSG_CHANNEL_OPEN) {
                string method = r.ReadString();
                if (method == "forwarded-tcpip")
                    ProcessPortforwardingRequest(_eventReceiver, r);
                else if (method.StartsWith("auth-agent")) //in most cases, method is "*****@*****.**"
                    ProcessAgentForwardRequest(_eventReceiver, r);
                else {
                    SSH2DataWriter wr = new SSH2DataWriter();
                    wr.WriteByte((byte)SSH2PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE);
                    wr.WriteInt32(r.ReadInt32());
                    wr.WriteInt32(0);
                    wr.WriteString("unknown method");
                    wr.WriteString(""); //lang tag
                    TraceReceptionEvent("SSH_MSG_CHANNEL_OPEN rejected", "method={0}", method);
                }
                return true;
            }
            else if (pt >= SSH2PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt <= SSH2PacketType.SSH_MSG_CHANNEL_FAILURE) {
                int local_channel = r.ReadInt32();
                ChannelCollection.Entry e = this.ChannelCollection.FindChannelEntry(local_channel);
                if (e != null)
                    ((SSH2Channel)e.Channel).ProcessPacket(e.Receiver, pt, r);
                else
                    Debug.WriteLine("unexpected channel pt=" + pt + " local_channel=" + local_channel.ToString());
                return true;
            }
            else if (pt == SSH2PacketType.SSH_MSG_IGNORE) {
                _eventReceiver.OnIgnoreMessage(r.ReadByteString());
                return true;
            }
            else if (_asyncKeyExchanger != null) {
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else if (pt == SSH2PacketType.SSH_MSG_KEXINIT) {
                //Debug.WriteLine("Host sent KEXINIT");
                _asyncKeyExchanger = new KeyExchanger(this, _sessionID);
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else {
                _eventReceiver.OnUnknownMessage((byte)pt, packet.GetBytes());
                return false;
            }
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
        private void ProcessKEXINIT(DataFragment packet)
        {
            SSH2DataReader re = null;
            do {
                _serverKEXINITPayload = packet.GetBytes();
                re = new SSH2DataReader(_serverKEXINITPayload);
                byte[] head = re.Read(17); //Type and cookie
                SSH2PacketType pt = (SSH2PacketType)head[0];

                if (pt == SSH2PacketType.SSH_MSG_KEXINIT)
                    break; //successfully exit

                if (pt == SSH2PacketType.SSH_MSG_IGNORE || pt == SSH2PacketType.SSH_MSG_DEBUG) { //continue
                    packet = _connection.ReceivePacket();
                }
                else {
                    throw new SSHException(String.Format("Server response is not SSH_MSG_KEXINIT but {0}", head[0]));
                }
            } while (true);

            string kex = re.ReadString();
            _cInfo.SupportedKEXAlgorithms = kex;
            _cInfo.KEXAlgorithm = DecideKexAlgorithm(kex);

            string host_key = re.ReadString();
            _cInfo.SupportedHostKeyAlgorithms = host_key;
            _cInfo.HostKeyAlgorithm = DecideHostKeyAlgorithm(host_key);

            string enc_cs = re.ReadString();
            _cInfo.SupportedEncryptionAlgorithmsClientToServer = enc_cs;
            _cInfo.OutgoingPacketCipher = DecideCipherAlgorithm(enc_cs);

            string enc_sc = re.ReadString();
            _cInfo.SupportedEncryptionAlgorithmsServerToClient = enc_sc;
            _cInfo.IncomingPacketCipher = DecideCipherAlgorithm(enc_sc);

            string mac_cs = re.ReadString();
            CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1");

            string mac_sc = re.ReadString();
            CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1");

            string comp_cs = re.ReadString();
            CheckAlgorithmSupport("compression", comp_cs, "none");
            string comp_sc = re.ReadString();
            CheckAlgorithmSupport("compression", comp_sc, "none");

            string lang_cs = re.ReadString();
            string lang_sc = re.ReadString();
            bool flag = re.ReadBool();
            int reserved = re.ReadInt32();
            Debug.Assert(re.RemainingDataLength == 0);

            if (_connection.IsEventTracerAvailable) {
                StringBuilder bld = new StringBuilder();
                bld.Append("kex_algorithm=");
                bld.Append(kex);
                bld.Append("; server_host_key_algorithms=");
                bld.Append(host_key);
                bld.Append("; encryption_algorithms_client_to_server=");
                bld.Append(enc_cs);
                bld.Append("; encryption_algorithms_server_to_client=");
                bld.Append(enc_sc);
                bld.Append("; mac_algorithms_client_to_server=");
                bld.Append(mac_cs);
                bld.Append("; mac_algorithms_server_to_client=");
                bld.Append(mac_sc);
                bld.Append("; comression_algorithms_client_to_server=");
                bld.Append(comp_cs);
                bld.Append("; comression_algorithms_server_to_client=");
                bld.Append(comp_sc);
                TraceReceptionNegotiation(SSH2PacketType.SSH_MSG_KEXINIT, bld.ToString());
            }

            if (flag)
                throw new SSHException("Algorithm negotiation failed");
        }