Ejemplo n.º 1
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.º 2
0
        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;
            }
        }
Ejemplo n.º 3
0
 private bool ReceiveAuthenticationResult()
 {
     DataFragment packet = ReceivePacket();
     SSH1DataReader r = new SSH1DataReader(packet);
     SSH1PacketType type = (SSH1PacketType) r.ReadByte();
     TraceReceptionEvent(type, "user authentication response");
     if (type == SSH1PacketType.SSH_MSG_DEBUG) {
         //Debug.WriteLine("receivedd debug message:"+Encoding.ASCII.GetString(r.ReadString()));
         return ReceiveAuthenticationResult();
     }
     else if (type == SSH1PacketType.SSH_SMSG_SUCCESS)
         return true;
     else if (type == SSH1PacketType.SSH_SMSG_FAILURE)
         return false;
     else
         throw new SSHException("unexpected type: " + type);
 }
Ejemplo n.º 4
0
        //RSA authentication
        private void DoRSAChallengeResponse()
        {
            //read key
            SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password);
            Transmit(
                new SSH1Packet(SSH1PacketType.SSH_CMSG_AUTH_RSA)
                    .WriteBigInteger(key.PublicModulus)
            );
            TraceTransmissionEvent(SSH1PacketType.SSH_CMSG_AUTH_RSA, "RSA challenge-reponse");

            DataFragment response = ReceivePacket();
            SSH1DataReader reader = new SSH1DataReader(response);
            SSH1PacketType pt = (SSH1PacketType) reader.ReadByte();
            if (pt == SSH1PacketType.SSH_SMSG_FAILURE)
                throw new SSHException(Strings.GetString("ServerRefusedRSA"));
            else if (pt != SSH1PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE)
                throw new SSHException(String.Format(Strings.GetString("UnexpectedResponse"), pt));
            TraceReceptionEvent(SSH1PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE, "received challenge");

            //creating challenge
            BigInteger challenge = key.decryptChallenge(reader.ReadMPInt());
            byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).GetBytes();

            //building response
            byte[] hash;
            using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) {
                md5.TransformBlock(rawchallenge, 0, rawchallenge.Length, rawchallenge, 0);
                md5.TransformFinalBlock(_sessionID, 0, _sessionID.Length);
                hash = md5.Hash;
            }
            Transmit(
                new SSH1Packet(SSH1PacketType.SSH_CMSG_AUTH_RSA_RESPONSE)
                    .Write(hash)
            );
            TraceReceptionEvent(SSH1PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, "received response");
        }
Ejemplo n.º 5
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.º 6
0
        /// <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;
            }
        }