Ejemplo n.º 1
0
        /// <summary>
        /// Sends SSH_MSG_CHANNEL_REQUEST packet and wait response asynchronously.
        /// </summary>
        /// <param name="requestPacket">SSH_MSG_CHANNEL_REQUEST packet</param>
        /// <returns>asynchronous task that wait for the response</returns>
        protected Task<ChannelRequestResult> SendRequestAndWaitResponseAsync(SSH2Packet requestPacket)
        {
            lock (_channelRequestStatusSync) {
                SpinWait.SpinUntil(() => _channelRequestStatus == false);
                _channelRequestStatus = true;
            }

            try {
                _channelRequestResult.Clear();
                Transmit(0, requestPacket);
                return WaitResponseAsync();
            }
            finally {
                lock (_channelRequestStatusSync) {
                    _channelRequestStatus = false;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Sends a packet.
        /// </summary>
        /// <param name="consumedSize">consumed window size.</param>
        /// <param name="packet">packet object</param>
        protected void Transmit(int consumedSize, SSH2Packet packet)
        {
            if (_serverWindowSizeLeft < (uint)consumedSize) {
                // FIXME: currently, window size on the remote side is totally ignored...
                _serverWindowSizeLeft = 0;
            }
            else {
                _serverWindowSizeLeft -= (uint)consumedSize;
            }

            _packetSender.Send(packet);
        }
Ejemplo n.º 3
0
 internal DataFragment TransmitAndWaitResponse(SSH2Packet packet)
 {
     lock (_transmitSync) {
         var data = packet.GetImage(_cipher, _mac, _sequence++);
         return _packetReceiver.SendAndWaitResponse(data);
     }
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Sends SSH_MSG_CHANNEL_REQUEST packet (no response)
 /// </summary>
 /// <param name="requestPacket">SSH_MSG_CHANNEL_REQUEST packet</param>
 protected void SendRequest(SSH2Packet requestPacket)
 {
     lock (_channelRequestStatusSync) {
         SpinWait.SpinUntil(() => _channelRequestStatus == false);
         _channelRequestStatus = true;
     }
     try {
         Transmit(0, requestPacket);
     }
     finally {
         lock (_channelRequestStatusSync) {
             _channelRequestStatus = false;
         }
     }
 }
Ejemplo n.º 5
0
        public AuthenticationResult DoKeyboardInteractiveAuth(string[] input)
        {
            if (_param.AuthenticationType != AuthenticationType.KeyboardInteractive)
                throw new SSHException("DoKeyboardInteractiveAuth() must be called with keyboard-interactive authentication");

            bool sent = false;
            do {
                SSH2Packet packet = new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_INFO_RESPONSE);
                if (sent) {
                    packet.WriteInt32(0);
                }
                else {
                    packet.WriteInt32(input.Length);
                    foreach (string t in input) {
                        packet.WriteString(t);
                    }
                    sent = true;
                }
                Transmit(packet);

                _authenticationResult = ProcessAuthenticationResponse();

                //recent OpenSSH sends SSH_MSG_USERAUTH_INFO_REQUEST with 0-length prompt array after the first negotiation
            } while (_authenticationResult == AuthenticationResult.Prompt && _requiredResponseCount == 0);

            return _authenticationResult;
        }
Ejemplo n.º 6
0
 internal void Transmit(SSH2Packet packet)
 {
     lock (_transmitSync) {
         _stream.Write(packet.GetImage(_cipher, _mac, _sequence++));
     }
 }
Ejemplo n.º 7
0
 private void OpenScheme(string scheme)
 {
     //open shell / subsystem
     SSH2Packet packet =
         new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
             .WriteInt32(_remoteID)
             .WriteString(scheme)
             .WriteBool(true);
     if (_command != null) {
         packet.WriteString(_command);
     }
     Transmit(0, packet);
 }
Ejemplo n.º 8
0
 private void Transmit(int consumedSize, SSH2Packet packet)
 {
     if (_allowedDataSize < (uint)consumedSize) {
         // FIXME: currently, window size on the remote side is totally ignored...
         _allowedDataSize = 0;
     }
     else {
         _allowedDataSize -= (uint)consumedSize;
     }
     _connection.Transmit(packet);
 }
Ejemplo n.º 9
0
 private DataFragment TransmitAndWaitResponse(SSH2Packet packet)
 {
     return _connection.TransmitAndWaitResponse(packet);
 }
Ejemplo n.º 10
0
 private void Transmit(SSH2Packet packet)
 {
     _connection.Transmit(packet);
 }
Ejemplo n.º 11
0
        private void SendKEXINIT(Mode mode)
        {
            const string mac_algorithm = "hmac-sha1";

            _status = Status.WAIT_KEXINIT;

            SSH2Packet packet =
                new SSH2Packet(SSH2PacketType.SSH_MSG_KEXINIT)
                    .WriteSecureRandomBytes(16) // cookie
                    .WriteString(GetSupportedKexAlgorithms()) // kex_algorithms
                    .WriteString(FormatHostKeyAlgorithmDescription()) // server_host_key_algorithms
                    .WriteString(FormatCipherAlgorithmDescription()) // encryption_algorithms_client_to_server
                    .WriteString(FormatCipherAlgorithmDescription()) // encryption_algorithms_server_to_client
                    .WriteString(mac_algorithm) // mac_algorithms_client_to_server
                    .WriteString(mac_algorithm) // mac_algorithms_server_to_client
                    .WriteString("none") // compression_algorithms_client_to_server
                    .WriteString("none") // compression_algorithms_server_to_client
                    .WriteString("") // languages_client_to_server
                    .WriteString("") // languages_server_to_client
                    .WriteBool(false) // indicates whether a guessed key exchange packet follows
                    .WriteInt32(0); // reserved for future extension

            _clientKEXINITPayload = packet.GetPayloadBytes();

            Transmit(packet);

            if (_connection.IsEventTracerAvailable) {
                StringBuilder bld = new StringBuilder();
                bld.Append("kex_algorithm=");
                bld.Append(GetSupportedKexAlgorithms());
                bld.Append("; server_host_key_algorithms=");
                bld.Append(FormatHostKeyAlgorithmDescription());
                bld.Append("; encryption_algorithms_client_to_server=");
                bld.Append(FormatCipherAlgorithmDescription());
                bld.Append("; encryption_algorithms_server_to_client=");
                bld.Append(FormatCipherAlgorithmDescription());
                bld.Append("; mac_algorithms_client_to_server=");
                bld.Append(mac_algorithm);
                bld.Append("; mac_algorithms_server_to_client=");
                bld.Append(mac_algorithm);
                TraceTransmissionNegotiation(SSH2PacketType.SSH_MSG_KEXINIT, bld.ToString());
            }
        }
Ejemplo n.º 12
0
        private DataFragment SendKEXDHINIT(Mode mode)
        {
            //Round1 computes and sends [e]
            BigInteger p = GetDiffieHellmanPrime(_cInfo.KEXAlgorithm.Value);
            //Generate x : 1 < x < (p-1)/2
            int xBytes = (p.BitCount() - 2) / 8;
            Rng rng = RngManager.GetSecureRng();
            do {
                byte[] sx = new byte[xBytes];
                rng.GetBytes(sx);
                _x = new BigInteger(sx);
            } while (_x <= 1);
            _e = new BigInteger(2).ModPow(_x, p);

            SSH2Packet packet =
                new SSH2Packet(SSH2PacketType.SSH_MSG_KEXDH_INIT)
                    .WriteBigInteger(_e);

            _status = Status.WAIT_KEXDH_REPLY;
            TraceTransmissionNegotiation(SSH2PacketType.SSH_MSG_KEXDH_INIT, "");

            if (mode == Mode.Synchronized) {
                return TransmitAndWaitResponse(packet);
            }
            else {
                Transmit(packet);
                return null;
            }
        }
Ejemplo n.º 13
0
        private AuthenticationResult UserAuth()
        {
            const string sn = "ssh-connection";
            if (_param.AuthenticationType == AuthenticationType.KeyboardInteractive) {
                Transmit(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST)
                        .WriteUTF8String(_param.UserName)
                        .WriteString(sn)
                        .WriteString("keyboard-interactive")
                        .WriteString("") //lang
                        .WriteString("") //submethod
                );
                TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting keyboard-interactive authentication");
                _authenticationResult = ProcessAuthenticationResponse();
            }
            else {
                if (_param.AuthenticationType == AuthenticationType.Password) {
                    //Password authentication
                    Transmit(
                        new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST)
                            .WriteUTF8String(_param.UserName)
                            .WriteString(sn)
                            .WriteString("password")
                            .WriteBool(false)
                            .WriteUTF8String(_param.Password)
                    );
                    TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting password authentication");
                }
                else {
                    //public key authentication
                    SSH2UserAuthKey kp = SSH2UserAuthKey.FromSECSHStyleFile(_param.IdentityFile, _param.Password);
                    string algorithmName = SSH2Util.PublicKeyAlgorithmName(kp.Algorithm);

                    // construct a packet except signature
                    SSH2Packet packet =
                        new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST)
                            .WriteUTF8String(_param.UserName)
                            .WriteString(sn)
                            .WriteString("publickey")
                            .WriteBool(true)
                            .WriteString(algorithmName)
                            .WriteAsString(kp.GetPublicKeyBlob());

                    // take payload image for the signature
                    byte[] payloadImage = packet.GetPayloadBytes();

                    // construct the signature source
                    SSH2PayloadImageBuilder workPayload =
                        new SSH2PayloadImageBuilder()
                            .WriteAsString(_sessionID)
                            .Write(payloadImage);

                    // take a signature blob
                    byte[] signatureBlob = kp.Sign(workPayload.GetBytes());

                    // encode signature (RFC4253)
                    workPayload.Clear();
                    byte[] signature =
                        workPayload
                            .WriteString(algorithmName)
                            .WriteAsString(signatureBlob)
                            .GetBytes();

                    // append signature to the packet
                    packet.WriteAsString(signature);

                    Transmit(packet);
                    TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting public key authentication");
                }

                _authenticationResult = ProcessAuthenticationResponse();
                if (_authenticationResult == AuthenticationResult.Failure)
                    throw new SSHException(Strings.GetString("AuthenticationFailed"));
            }
            return _authenticationResult;
        }