// 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"); }
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()); }
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); }
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! } } }
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; }