Ejemplo n.º 1
0
        private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1DataReader reader)
        {
            int server_channel = reader.ReadInt32();
            string host = reader.ReadString();
            int port = reader.ReadInt32();

            PortForwardingCheckResult result = receiver.CheckPortForwardingRequest(host, port, "", 0);
            if (result.allowed) {
                int local_id = _channel_collection.RegisterChannelEventReceiver(null, result.channel).LocalID;
                _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel));

                Transmit(
                    new SSH1Packet(SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION)
                        .WriteInt32(server_channel)
                        .WriteInt32(local_id)
                );
            }
            else {
                Transmit(
                    new SSH1Packet(SSH1PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE)
                        .WriteInt32(server_channel)
                );
            }
        }
Ejemplo n.º 2
0
        private void ReceiveServerKeys()
        {
            DataFragment packet = ReceivePacket();
            SSH1DataReader reader = new SSH1DataReader(packet);
            SSH1PacketType pt = (SSH1PacketType) reader.ReadByte();

            if (pt != SSH1PacketType.SSH_SMSG_PUBLIC_KEY)
                throw new SSHException("unexpected SSH SSH1Packet type " + pt, packet.GetBytes());

            _cInfo.AntiSpoofingCookie = reader.Read(8);
            _cInfo.ServerKeyBits = reader.ReadInt32();
            BigInteger serverKeyExponent = reader.ReadMPInt();
            BigInteger serverKeyModulus = reader.ReadMPInt();
            _cInfo.ServerKey = new RSAPublicKey(serverKeyExponent, serverKeyModulus);
            _cInfo.HostKeyBits = reader.ReadInt32();
            BigInteger hostKeyExponent = reader.ReadMPInt();
            BigInteger hostKeyModulus = reader.ReadMPInt();
            _cInfo.HostKey = new RSAPublicKey(hostKeyExponent, hostKeyModulus);

            //read protocol support parameters
            int protocol_flags = reader.ReadInt32();
            int supported_ciphers_mask = reader.ReadInt32();
            _cInfo.SupportedEncryptionAlgorithmsMask = supported_ciphers_mask;
            int supported_authentications_mask = reader.ReadInt32();
            //Debug.WriteLine(String.Format("ServerOptions {0} {1} {2}", protocol_flags, supported_ciphers_mask, supported_authentications_mask));

            if (reader.RemainingDataLength > 0)
                throw new SSHException("data length mismatch", packet.GetBytes());

            bool found = false;
            foreach (CipherAlgorithm a in _param.PreferableCipherAlgorithms) {
                if (a != CipherAlgorithm.Blowfish && a != CipherAlgorithm.TripleDES)
                    continue;
                else if (a == CipherAlgorithm.Blowfish && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.Blowfish)) == 0)
                    continue;
                else if (a == CipherAlgorithm.TripleDES && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.TripleDES)) == 0)
                    continue;

                _cInfo.IncomingPacketCipher = _cInfo.OutgoingPacketCipher = a;
                found = true;
                break;
            }

            if (!found)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedX"), "Blowfish/TripleDES"));

            if (_param.AuthenticationType == AuthenticationType.Password && (supported_authentications_mask & (1 << (int)AuthenticationType.Password)) == 0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedPassword")), packet.GetBytes());
            if (_param.AuthenticationType == AuthenticationType.PublicKey && (supported_authentications_mask & (1 << (int)AuthenticationType.PublicKey)) == 0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedRSA")), packet.GetBytes());

            TraceReceptionEvent(pt, "received server key");
        }
Ejemplo n.º 3
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);
     }
 }
Ejemplo n.º 4
0
        private void ReceiveServerKeys()
        {
            DataFragment packet = ReceivePacket();
            SSH1DataReader reader = new SSH1DataReader(packet);
            PacketType pt = reader.ReadPacketType();

            if (pt != PacketType.SSH_SMSG_PUBLIC_KEY)
                throw new SSHException("unexpected SSH SSH1Packet type " + pt, reader.ReadAll());

            _cInfo._serverinfo = new SSHServerInfo(reader);
            _cInfo._hostkey = new RSAPublicKey(_cInfo._serverinfo.host_key_public_exponent, _cInfo._serverinfo.host_key_public_modulus);

            //read protocol support parameters
            int protocol_flags = reader.ReadInt32();
            int supported_ciphers_mask = reader.ReadInt32();
            _cInfo.SetSupportedCipherAlgorithms(supported_ciphers_mask);
            int supported_authentications_mask = reader.ReadInt32();
            //Debug.WriteLine(String.Format("ServerOptions {0} {1} {2}", protocol_flags, supported_ciphers_mask, supported_authentications_mask));

            if (reader.Rest > 0)
                throw new SSHException("data length mismatch", reader.ReadAll());

            bool found = false;
            foreach (CipherAlgorithm a in _param.PreferableCipherAlgorithms) {
                if (a != CipherAlgorithm.Blowfish && a != CipherAlgorithm.TripleDES)
                    continue;
                else if (a == CipherAlgorithm.Blowfish && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.Blowfish)) == 0)
                    continue;
                else if (a == CipherAlgorithm.TripleDES && (supported_ciphers_mask & (1 << (int)CipherAlgorithm.TripleDES)) == 0)
                    continue;

                _cInfo._algorithmForReception = _cInfo._algorithmForTransmittion = a;
                found = true;
                break;
            }

            if (!found)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedX"), "Blowfish/TripleDES"));

            if (_param.AuthenticationType == AuthenticationType.Password && (supported_authentications_mask & (1 << (int)AuthenticationType.Password)) == 0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedPassword")), reader.ReadAll());
            if (_param.AuthenticationType == AuthenticationType.PublicKey && (supported_authentications_mask & (1 << (int)AuthenticationType.PublicKey)) == 0)
                throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedRSA")), reader.ReadAll());

            TraceReceptionEvent(pt, "received server key");
        }
Ejemplo n.º 5
0
        private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1DataReader reader)
        {
            int server_channel = reader.ReadInt32();
            string host = Encoding.ASCII.GetString(reader.ReadString());
            int port = reader.ReadInt32();

            SSH1DataWriter writer = new SSH1DataWriter();
            PortForwardingCheckResult result = receiver.CheckPortForwardingRequest(host, port, "", 0);
            if (result.allowed) {
                int local_id = _channel_collection.RegisterChannelEventReceiver(null, result.channel).LocalID;
                _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel));

                writer.WriteInt32(server_channel);
                writer.WriteInt32(local_id);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
            else {
                writer.WriteInt32(server_channel);
                SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE, writer.ToByteArray());
                p.WriteTo(_stream, _tCipher);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Process packet about this channel.
        /// </summary>
        /// <param name="packetType">a packet type (message number)</param>
        /// <param name="packetFragment">a packet image except message number and recipient channel.</param>
        public override void ProcessPacket(SSH1PacketType packetType, DataFragment packetFragment)
        {
            if (_state == State.Closed) {
                return; // ignore
            }

            DataFragment dataFragmentArg;

            lock (_stateSync) {
                switch (_state) {
                    case State.Initial:
                        break;
                    case State.WaitStartPTYResponse:
                        if (packetType == SSH1PacketType.SSH_SMSG_SUCCESS) {
                            _state = State.StartPTYSuccess;
                            Monitor.PulseAll(_stateSync);   // notifies state change
                            _receivedPacket.TrySet(packetFragment, PASSING_TIMEOUT);
                        }
                        else if (packetType == SSH1PacketType.SSH_SMSG_FAILURE) {
                            _state = State.StartPTYFailure;
                            Monitor.PulseAll(_stateSync);   // notifies state change
                            _receivedPacket.TrySet(packetFragment, PASSING_TIMEOUT);
                        }
                        break;
                    case State.Established:
                        break;
                    case State.Ready:
                        switch (packetType) {
                            case SSH1PacketType.SSH_SMSG_STDOUT_DATA: {
                                    SSH1DataReader reader = new SSH1DataReader(packetFragment);
                                    int len = reader.ReadInt32();
                                    dataFragmentArg = reader.GetRemainingDataView(len);
                                }
                                goto OnData;    // do it out of the lock block
                            case SSH1PacketType.SSH_SMSG_STDERR_DATA: {
                                    SSH1DataReader reader = new SSH1DataReader(packetFragment);
                                    int len = reader.ReadInt32();
                                    dataFragmentArg = reader.GetRemainingDataView(len);
                                }
                                goto OnData;    // do it out of the lock block
                            case SSH1PacketType.SSH_SMSG_EXITSTATUS:
                                Transmit(
                                    new SSH1Packet(SSH1PacketType.SSH_CMSG_EXIT_CONFIRMATION)
                                );
                                goto SetStateClosedByServer;    // do it out of the lock block
                        }
                        goto OnUnhandledPacket; // do it out of the lock block
                }
            }

            return;

            OnData:
            Handler.OnData(dataFragmentArg);
            return;

            SetStateClosedByServer:
            Trace("CH[{0}] closed by server", LocalChannel);
            SetStateClosed(true);
            return;

            OnUnhandledPacket:
            Handler.OnUnhandledPacket((byte)packetType, packetFragment);
            return;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Process packet about this channel.
        /// </summary>
        /// <param name="packetType">a packet type (message number)</param>
        /// <param name="packetFragment">a packet image except message number and recipient channel.</param>
        public override void ProcessPacket(SSH1PacketType packetType, DataFragment packetFragment)
        {
            if (_state == State.Closed) {
                return; // ignore
            }

            DataFragment dataFragmentArg;

            lock (_stateSync) {
                switch (_state) {
                    case State.InitiatedByServer:
                        break;
                    case State.InitiatedByClient:
                        if (packetType == SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
                            SSH1DataReader reader = new SSH1DataReader(packetFragment);
                            SetRemoteChannel(reader.ReadUInt32());
                            _state = State.Established;
                            Monitor.PulseAll(_stateSync);   // notifies state change
                            dataFragmentArg = new DataFragment(0);
                            goto OnEstablished; // do it out of the lock block
                        }
                        if (packetType == SSH1PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE) {
                            goto RequestFailed; // do it out of the lock block
                        }
                        break;
                    case State.Closing:
                        if (packetType == SSH1PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION) {
                            goto SetStateClosedByClient;    // do it out of the lock block
                        }
                        break;
                    case State.Established:
                    case State.Ready:
                        if (ProcessPacketSub(packetType, packetFragment) == SubPacketProcessResult.Consumed) {
                            return;
                        }
                        switch (packetType) {
                            case SSH1PacketType.SSH_MSG_CHANNEL_DATA: {
                                    SSH1DataReader reader = new SSH1DataReader(packetFragment);
                                    int len = reader.ReadInt32();
                                    dataFragmentArg = reader.GetRemainingDataView(len);
                                }
                                goto OnData;    // do it out of the lock block
                            case SSH1PacketType.SSH_MSG_CHANNEL_CLOSE:
                                Transmit(
                                    new SSH1Packet(SSH1PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION)
                                        .WriteUInt32(RemoteChannel)
                                );
                                goto SetStateClosedByServer;    // do it out of the lock block
                        }
                        goto OnUnhandledPacket; // do it out of the lock block
                }
            }

            return;

            OnEstablished:
            Trace("CH[{0}] channel opend : remoteChannel={1}", LocalChannel, RemoteChannel);
            Handler.OnEstablished(dataFragmentArg);
            OnChannelEstablished();
            return;

            RequestFailed:
            Trace("CH[{0}] request failed", LocalChannel);
            RequestFailed();
            return;

            SetStateClosedByClient:
            Trace("CH[{0}] closed by client", LocalChannel);
            SetStateClosed(false);
            return;

            SetStateClosedByServer:
            Trace("CH[{0}] closed by server", LocalChannel);
            SetStateClosed(true);
            return;

            OnData:
            Handler.OnData(dataFragmentArg);
            return;

            OnUnhandledPacket:
            Handler.OnUnhandledPacket((byte)packetType, packetFragment);
            return;
        }