Beispiel #1
0
        // sending "exec" service for SCP protocol.
        private void ExecCommand(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader reader) {
            if (_negotiationStatus == NegotiationStatus.WaitingChannelConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
                    if (pt != PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE)
                        receiver.OnChannelError(new SSHException("opening channel failed; packet type=" + pt));
                    else {
                        int errcode = reader.ReadInt32();
                        string msg = Encoding.ASCII.GetString(reader.ReadString());
                        receiver.OnChannelError(new SSHException(msg));
                    }
                    Close();
                }
                else {
                    _remoteID = reader.ReadInt32();
                    _allowedDataSize = reader.ReadInt32();
                    _serverMaxPacketSize = reader.ReadInt32();

                    // exec command
                    SSH2DataWriter wr = new SSH2DataWriter();
                    SSHConnectionParameter param = _connection.Param;
                    wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
                    wr.WriteInt32(_remoteID);
                    wr.WriteString("exec");  // "exec"
                    wr.WriteBool(false);   // want confirm is disabled. (*)
                    wr.WriteString(_command);

                    if (_connection.IsEventTracerAvailable)
                        _connection.TraceTransmissionEvent("exec command", "cmd={0}", _command);
                    TransmitPayload(wr.ToByteArray());

                    //confirmation is omitted
                    receiver.OnChannelReady();
                    _negotiationStatus = NegotiationStatus.Ready; //goal!
                }
            }
            else if (_negotiationStatus == NegotiationStatus.WaitingExecCmdConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_DATA) {
                    receiver.OnChannelError(new SSHException("exec command failed"));
                    Close();
                }
                else {
                    receiver.OnChannelReady();
                    _negotiationStatus = NegotiationStatus.Ready; //goal!
                }
            }
            else
                throw new SSHException("internal state error");
        }
Beispiel #2
0
 private void OpenScheme(string scheme) {
     //open shell / subsystem
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
     wr.WriteInt32(_remoteID);
     wr.WriteString(scheme);
     wr.WriteBool(true);
     if (_command != null)
         wr.WriteString(_command);
     TransmitPayload(wr.ToByteArray());
 }
Beispiel #3
0
        private void SendKEXINIT(Mode mode) {
            const string kex_algorithm = "diffie-hellman-group1-sha1";
            const string mac_algorithm = "hmac-sha1";
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_KEXINIT);
            byte[] cookie = new byte[16];
            _param.Random.NextBytes(cookie);
            wr.Write(cookie);
            wr.WriteString(kex_algorithm); //    kex_algorithms
            wr.WriteString(FormatHostKeyAlgorithmDescription());            //    server_host_key_algorithms
            wr.WriteString(FormatCipherAlgorithmDescription());      //    encryption_algorithms_client_to_server
            wr.WriteString(FormatCipherAlgorithmDescription());      //    encryption_algorithms_server_to_client
            wr.WriteString(mac_algorithm);                  //    mac_algorithms_client_to_server
            wr.WriteString(mac_algorithm);                  //    mac_algorithms_server_to_client
            wr.WriteString("none");                       //    compression_algorithms_client_to_server
            wr.WriteString("none");                       //    compression_algorithms_server_to_client
            wr.WriteString("");                           //    languages_client_to_server
            wr.WriteString("");                           //    languages_server_to_client
            wr.WriteBool(false); //Indicates whether a guessed key exchange packet follows
            wr.WriteInt32(0);       //reserved for future extension

            _clientKEXINITPayload = wr.ToByteArray();
            _status = Status.WAIT_KEXINIT;
            if (_connection.IsEventTracerAvailable) {
                StringBuilder bld = new StringBuilder();
                bld.Append("kex_algorithm=");
                bld.Append(kex_algorithm);
                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(PacketType.SSH_MSG_KEXINIT, bld.ToString());
            }
            TransmitRawPayload(_clientKEXINITPayload);
        }
Beispiel #4
0
        private void OpenShellOrSubsystem(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader reader, string scheme) {
            if (_negotiationStatus == NegotiationStatus.WaitingChannelConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
                    if (pt != PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE)
                        receiver.OnChannelError(new SSHException("opening channel failed; packet type=" + pt));
                    else {
                        int errcode = reader.ReadInt32();
                        string msg = Encoding.ASCII.GetString(reader.ReadString());
                        receiver.OnChannelError(new SSHException(msg));
                    }
                    // Close() shouldn't be called because remote channel number is not given yet.
                    // We just remove an event receiver from the collection of channels.
                    // FIXME: _negotiationStatus sould be set an error status ?
                    _connection.ChannelCollection.UnregisterChannelEventReceiver(_localID);
                }
                else {
                    _remoteID = reader.ReadInt32();
                    _allowedDataSize = reader.ReadInt32();
                    _serverMaxPacketSize = reader.ReadInt32();

                    if (_type == ChannelType.Subsystem) {
                        OpenScheme(scheme);
                        _negotiationStatus = NegotiationStatus.WaitingSubsystemConfirmation;
                    }
                    else {
                        //open pty
                        SSH2DataWriter wr = new SSH2DataWriter();
                        SSHConnectionParameter param = _connection.Param;
                        wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
                        wr.WriteInt32(_remoteID);
                        wr.WriteString("pty-req");
                        wr.WriteBool(true);
                        wr.WriteString(param.TerminalName);
                        wr.WriteInt32(param.TerminalWidth);
                        wr.WriteInt32(param.TerminalHeight);
                        wr.WriteInt32(param.TerminalPixelWidth);
                        wr.WriteInt32(param.TerminalPixelHeight);
                        wr.WriteAsString(new byte[0]);
                        if (_connection.IsEventTracerAvailable)
                            _connection.TraceTransmissionEvent(PacketType.SSH_MSG_CHANNEL_REQUEST, "pty-req", "terminal={0} width={1} height={2}", param.TerminalName, param.TerminalWidth, param.TerminalHeight);
                        TransmitPayload(wr.ToByteArray());

                        _negotiationStatus = NegotiationStatus.WaitingPtyReqConfirmation;
                    }
                }
            }
            else if (_negotiationStatus == NegotiationStatus.WaitingPtyReqConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_SUCCESS) {
                    receiver.OnChannelError(new SSHException("opening pty failed"));
                    Close();
                }
                else {
                    //agent request (optional)
                    if (_connection.Param.AgentForward != null) {
                        SSH2DataWriter wr = new SSH2DataWriter();
                        wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
                        wr.WriteInt32(_remoteID);
                        wr.WriteString("*****@*****.**");
                        wr.WriteBool(true);
                        _connection.TraceTransmissionEvent(PacketType.SSH_MSG_CHANNEL_REQUEST, "auth-agent-req", "");
                        TransmitPayload(wr.ToByteArray());
                        _negotiationStatus = NegotiationStatus.WaitingAuthAgentReqConfirmation;
                    }
                    else {
                        OpenScheme(scheme);
                        _negotiationStatus = NegotiationStatus.WaitingShellConfirmation;
                    }
                }
            }
            else if (_negotiationStatus == NegotiationStatus.WaitingAuthAgentReqConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_SUCCESS && pt != PacketType.SSH_MSG_CHANNEL_FAILURE) {
                    receiver.OnChannelError(new SSHException("auth-agent-req error"));
                    Close();
                }
                else { //auth-agent-req is optional
                    _connection.SetAgentForwardConfirmed(pt == PacketType.SSH_MSG_CHANNEL_SUCCESS);
                    _connection.TraceReceptionEvent(pt, "auth-agent-req");

                    OpenScheme(scheme);
                    _negotiationStatus = NegotiationStatus.WaitingShellConfirmation;
                }
            }
            else if (_negotiationStatus == NegotiationStatus.WaitingShellConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_SUCCESS) {
                    receiver.OnChannelError(new SSHException("Opening shell failed: packet type=" + pt.ToString()));
                    Close();
                }
                else {
                    receiver.OnChannelReady();
                    _negotiationStatus = NegotiationStatus.Ready; //goal!
                }
            }
            else if (_negotiationStatus == NegotiationStatus.WaitingSubsystemConfirmation) {
                if (pt != PacketType.SSH_MSG_CHANNEL_SUCCESS) {
                    receiver.OnChannelError(new SSHException("Opening subsystem failed: packet type=" + pt.ToString()));
                    Close();
                }
                else {
                    receiver.OnChannelReady();
                    _negotiationStatus = NegotiationStatus.Ready; //goal!
                }
            }
        }
Beispiel #5
0
        private AuthenticationResult UserAuth() {
            const string sn = "ssh-connection";
            if (_param.AuthenticationType == AuthenticationType.KeyboardInteractive) {
                SSH2TransmissionPacket packet = OpenPacket();
                SSH2DataWriter wr = packet.DataWriter;
                wr.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST);
                wr.WriteString(_param.UserName);
                wr.WriteString(sn);
                wr.WriteString("keyboard-interactive");
                wr.WriteString(""); //lang
                wr.WriteString(""); //submethod
                TraceTransmissionEvent(PacketType.SSH_MSG_USERAUTH_REQUEST, "starting keyboard-interactive authentication");
                TransmitPacket(packet);
                _authenticationResult = ProcessAuthenticationResponse();
            }
            else {
                SSH2TransmissionPacket packet = OpenPacket();
                SSH2DataWriter wr = packet.DataWriter;
                wr.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST);
                wr.WriteString(_param.UserName);
                if (_param.AuthenticationType == AuthenticationType.Password) {
                    //Password authentication
                    wr.WriteString(sn);
                    wr.WriteString("password");
                    wr.WriteBool(false);
                    wr.WriteString(_param.Password);
                    TraceTransmissionEvent(PacketType.SSH_MSG_USERAUTH_REQUEST, "starting password authentication");
                }
                else {
                    //public key authentication
                    SSH2UserAuthKey kp = SSH2UserAuthKey.FromSECSHStyleFile(_param.IdentityFile, _param.Password);
                    SSH2DataWriter signsource = new SSH2DataWriter();
                    signsource.WriteAsString(_sessionID);
                    signsource.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST);
                    signsource.WriteString(_param.UserName);
                    signsource.WriteString(sn);
                    signsource.WriteString("publickey");
                    signsource.WriteBool(true);
                    signsource.WriteString(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm));
                    signsource.WriteAsString(kp.GetPublicKeyBlob());

                    SSH2DataWriter signpack = new SSH2DataWriter();
                    signpack.WriteString(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm));
                    signpack.WriteAsString(kp.Sign(signsource.ToByteArray()));

                    wr.WriteString(sn);
                    wr.WriteString("publickey");
                    wr.WriteBool(true);
                    wr.WriteString(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm));
                    wr.WriteAsString(kp.GetPublicKeyBlob());
                    wr.WriteAsString(signpack.ToByteArray());
                    TraceTransmissionEvent(PacketType.SSH_MSG_USERAUTH_REQUEST, "starting public key authentication");
                }
                TransmitPacket(packet);

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