Exemple #1
0
 public void Append(DataFragment data) {
     Append(data.Data, data.Offset, data.Length);
 }
Exemple #2
0
        private bool ProcessKEXDHREPLY(DataFragment packet) {
            //Round2 receives response
            SSH2DataReader re = null;
            PacketType h;
            do {
                re = new SSH2DataReader(packet);
                h = re.ReadPacketType();
                if (h == PacketType.SSH_MSG_KEXDH_REPLY)
                    break; //successfully exit
                else if (h == PacketType.SSH_MSG_IGNORE || h == PacketType.SSH_MSG_DEBUG) { //continue
                    packet = _connection.ReceivePacket();
                }
                else
                    throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h));
            } while (true);

            byte[] key_and_cert = re.ReadString();
            BigInteger f = re.ReadMPInt();
            byte[] signature = re.ReadString();
            Debug.Assert(re.Rest == 0);

            //Round3 calc hash H
            SSH2DataWriter wr = new SSH2DataWriter();
            _k = f.modPow(_x, GetDiffieHellmanPrime(_cInfo._kexAlgorithm));
            wr = new SSH2DataWriter();
            wr.WriteString(_cInfo._clientVersionString);
            wr.WriteString(_cInfo._serverVersionString);
            wr.WriteAsString(_clientKEXINITPayload);
            wr.WriteAsString(_serverKEXINITPayload);
            wr.WriteAsString(key_and_cert);
            wr.WriteBigInteger(_e);
            wr.WriteBigInteger(f);
            wr.WriteBigInteger(_k);
            _hash = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());

            _connection.TraceReceptionEvent(h, "verifying host key");
            if (!VerifyHostKey(key_and_cert, signature, _hash))
                return false;

            //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash));
            if (_sessionID == null)
                _sessionID = _hash;
            return true;
        }
Exemple #3
0
        protected override void OnDataInLock(DataFragment data) {
            try {
                //the specification claims the version string ends with CRLF, however some servers send LF only
                if (data.Length <= 2 || data.Data[data.Offset + data.Length - 1] != 0x0A)
                    throw new SSHException(Strings.GetString("NotSSHServer"));
                //Debug.WriteLine(String.Format("receiveServerVersion len={0}",len));

                //this Trim() is necessary for computing hash in the host key authentication stage
                string sv = Encoding.ASCII.GetString(data.Data, data.Offset, data.Length).Trim();

                //check compatibility
                int a = sv.IndexOf('-');
                if (a == -1)
                    ThrowUnexpectedFormatException(sv);
                int b = sv.IndexOf('-', a + 1);
                if (b == -1)
                    ThrowUnexpectedFormatException(sv);
                int comma = sv.IndexOf('.', a, b - a);
                if (comma == -1)
                    ThrowUnexpectedFormatException(sv);

                int major = Int32.Parse(sv.Substring(a + 1, comma - a - 1));
                int minor = Int32.Parse(sv.Substring(comma + 1, b - comma - 1));

                if (_param.Protocol == SSHProtocol.SSH1) {
                    if (major != 1)
                        ThrowVersionMismatchException(sv, SSHProtocol.SSH1);
                }
                else {
                    if (major >= 3 || major <= 0 || (major == 1 && minor != 99))
                        ThrowVersionMismatchException(sv, SSHProtocol.SSH2);
                }

                _serverVersion = sv;
                this.SetSuccessfulResult(data);
            }
            catch (Exception ex) {
                this.SetFailureResult(ex);
            }
        }
Exemple #4
0
        internal PlainSocket(Socket s, IDataHandler h) : base(h) 
        {
            _socket = s;
            Debug.Assert(_socket.Connected);
            _socketStatus = SocketStatus.Ready;

            _data = new DataFragment(0x1000);
            _callback = new AsyncCallback(RepeatCallback);
        }
Exemple #5
0
 public void OnData(DataFragment data) {
     lock (_socket) {
         OnDataInLock(data);
     }
 }
Exemple #6
0
 //Set the response
 protected void SetSuccessfulResult(DataFragment data) {
     _results.Enqueue(data.Isolate());
     _event.Set();
 }
Exemple #7
0
 public SSH2MsgNewKeys(DataFragment data, Handler onDequeued)
     : base(data.Data, data.Offset, data.Length) {
     _onDequeued = onDequeued;
 }
Exemple #8
0
        private bool ProcessPacket(DataFragment packet) {
            if (_readerForProcessPacket == null)
                _readerForProcessPacket = new SSH2DataReader(packet);
            else
                _readerForProcessPacket.Recycle(packet); //avoid 'new'

            SSH2DataReader r = _readerForProcessPacket; //rename for frequently use
            PacketType pt = r.ReadPacketType();

            if (pt == PacketType.SSH_MSG_DISCONNECT) {
                int errorcode = r.ReadInt32();
                _eventReceiver.OnConnectionClosed();
                return false;
            }
            else if (_waitingForPortForwardingResponse) {
                if (pt != PacketType.SSH_MSG_REQUEST_SUCCESS)
                    _eventReceiver.OnUnknownMessage((byte)pt, r.Image);
                _waitingForPortForwardingResponse = false;
                return true;
            }
            else if (pt == PacketType.SSH_MSG_CHANNEL_OPEN) {
                string method = Encoding.ASCII.GetString(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.WritePacketType(PacketType.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 >= PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt <= PacketType.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, 5 + r.Rest, r);
                else
                    ;//Debug.WriteLine("unexpected channel pt=" + pt + " local_channel=" + local_channel.ToString());
                return true;
            }
            else if (pt == PacketType.SSH_MSG_IGNORE) {
                _eventReceiver.OnIgnoreMessage(r.ReadString());
                return true;
            }
            else if (_asyncKeyExchanger != null) {
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else if (pt == PacketType.SSH_MSG_KEXINIT) {
                //Debug.WriteLine("Host sent KEXINIT");
                _asyncKeyExchanger = new KeyExchanger(this, _sessionID);
                _asyncKeyExchanger.AsyncProcessPacket(packet);
                return true;
            }
            else if (pt == PacketType.SSH_MSG_GLOBAL_REQUEST)
            {
                SSH2DataWriter wr = new SSH2DataWriter();
                wr.WritePacketType(PacketType.SSH_MSG_REQUEST_SUCCESS);
                wr.WriteBool(true);
                TransmitRawPayload(wr.ToByteArray());
                return true;
            }
            else {
                _eventReceiver.OnUnknownMessage((byte)pt, r.Image);
                return false;
            }
        }
Exemple #9
0
 private void Init(DataFragment data) {
     _data = data.Data;
     _offset = data.Offset;
     _limit = _offset + data.Length;
 }
Exemple #10
0
 public void OnData(DataFragment data) {
     _connection.AsyncReceivePacket(data);
 }
Exemple #11
0
 public void Recycle(DataFragment data) {
     Init(data);
 }
Exemple #12
0
 public SSHDataReader(DataFragment data) {
     Init(data);
 }
Exemple #13
0
 public virtual DataFragment Isolate() {
     int newcapacity = RoundUp(_length);
     byte[] t = new byte[newcapacity];
     Buffer.BlockCopy(_data, _offset, t, 0, _length);
     DataFragment f = new DataFragment(t, 0, _length);
     return f;
 }
Exemple #14
0
        private void ProcessNEWKEYS(DataFragment packet) {
            //confirms new key
            if (packet.Length != 1 || packet.ByteAt(0) != (byte)PacketType.SSH_MSG_NEWKEYS) {
                Monitor.Exit(_connection);
                throw new SSHException("SSH_MSG_NEWKEYS failed");
            }

            _connection.RefreshKeys(_sessionID, _tc, _rc, _tm, _rm);
            Monitor.Exit(_connection);
            TraceReceptionNegotiation(PacketType.SSH_MSG_NEWKEYS, "the keys are refreshed");
            _status = Status.FINISHED;
        }
Exemple #15
0
 public SSH2PacketBuilder(IDataHandler handler)
     : base(handler) {
     _buffer = new DataFragment(0x1000);
     _packet = new DataFragment(_buffer.Capacity);
     _sequence = 0;
     _cipher = null;
     _mac = null;
     _head = null;
 }
Exemple #16
0
 internal void AsyncReceivePacket(DataFragment packet) {
     try {
         ProcessPacket(packet);
     }
     catch (Exception ex) {
         _eventReceiver.OnError(ex);
     }
 }
Exemple #17
0
        public override void OnData(DataFragment data) {
            lock (_cipherSync) {
                try {
                    if (!_keyError) {
                        // key error detection
                        if (_pending && DateTime.UtcNow > _keyErrorDetectionTimeout) {
                            _keyError = true;   // disable accepting data any more
                            return;
                        }

                        _buffer.Append(data);

                        if (!_pending) {
                            ProcessBuffer();
                        }
                    }
                } catch (Exception ex) {
                    OnError(ex);
                }
            }
        }
Exemple #18
0
 public abstract void OnData(DataFragment data);
Exemple #19
0
 private bool IsMsgNewKeys(DataFragment packet) {
     return packet.Length >= 1 && packet.ByteAt(0) == (byte)PacketType.SSH_MSG_NEWKEYS;
 }
Exemple #20
0
 protected abstract void OnDataInLock(DataFragment data);
Exemple #21
0
 public SSH2TransmissionPacket() {
     _writer = new SSH2DataWriter();
     _dataFragment = new DataFragment(null, 0, 0);
     _isOpen = false;
 }
Exemple #22
0
        //Send request and wait response
        public DataFragment SendAndWaitResponse(DataFragment data) {
            //this lock is important
            lock (_socket) {
                Debug.Assert(_results.Count == 0);
                _event.Reset();
                if (data.Length > 0)
                    _socket.Write(data.Data, data.Offset, data.Length);
            }

            _event.WaitOne();
            Debug.Assert(_results.Count > 0);
            return Dequeue();
        }
Exemple #23
0
 public void AsyncProcessPacket(DataFragment packet) {
     Mode m = Mode.Asynchronized;
     switch (_status) {
         case Status.INITIAL:
             _startedByHost = true;
             ProcessKEXINIT(packet);
             SendKEXINIT(m);
             SendKEXDHINIT(m);
             break;
         case Status.WAIT_KEXINIT:
             ProcessKEXINIT(packet);
             SendKEXDHINIT(m);
             break;
         case Status.WAIT_KEXDH_REPLY:
             ProcessKEXDHREPLY(packet);
             SendNEWKEYS(m);
             break;
         case Status.WAIT_NEWKEYS:
             ProcessNEWKEYS(packet);
             Debug.Assert(_status == Status.FINISHED);
             break;
     }
 }
Exemple #24
0
 protected override void OnDataInLock(DataFragment data) {
     this.SetSuccessfulResult(data);
 }
Exemple #25
0
        private void ProcessKEXINIT(DataFragment packet) {
            SSH2DataReader re = null;
            do {
                _serverKEXINITPayload = packet.ToNewArray();
                re = new SSH2DataReader(_serverKEXINITPayload);
                byte[] head = re.Read(17); //Type and cookie
                PacketType pt = (PacketType)head[0];

                if (pt == PacketType.SSH_MSG_KEXINIT)
                    break; //successfully exit
                else if (pt == PacketType.SSH_MSG_IGNORE || pt == PacketType.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);

            Encoding enc = Encoding.ASCII;

            string kex = enc.GetString(re.ReadString());
            _cInfo._supportedKEXAlgorithms = kex;
            _cInfo._kexAlgorithm = DecideKexAlgorithm(kex);

            string host_key = enc.GetString(re.ReadString());
            _cInfo._supportedHostKeyAlgorithms = host_key;
            _cInfo._algorithmForHostKeyVerification = DecideHostKeyAlgorithm(host_key);

            string enc_cs = enc.GetString(re.ReadString());
            _cInfo._supportedCipherAlgorithms = enc_cs;
            _cInfo._algorithmForTransmittion = DecideCipherAlgorithm(enc_cs);

            string enc_sc = enc.GetString(re.ReadString());
            _cInfo._algorithmForReception = DecideCipherAlgorithm(enc_sc);

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

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

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

            string lang_cs = enc.GetString(re.ReadString());
            string lang_sc = enc.GetString(re.ReadString());
            bool flag = re.ReadBool();
            int reserved = re.ReadInt32();
            Debug.Assert(re.Rest == 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(PacketType.SSH_MSG_KEXINIT, bld.ToString());
            }

            if (flag)
                throw new SSHException("Algorithm negotiation failed");
        }
Exemple #26
0
        public void OnData(byte[] data, int offset, int length) {
            if (_fragment == null)
                _fragment = new DataFragment(data, offset, length);
            else
                _fragment.Init(data, offset, length);

            _handler.OnData(_fragment);
        }
Exemple #27
0
 public void Write(DataFragment data) {
     Write(data.Data, data.Offset, data.Length);
 }