SSH1Connection.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:23k
- /* ---------------------------------------------------------------------------
- *
- * Copyright (c) Granados Networks, Inc. All Rights Reserved..
- *
- * This file is a part of the Granados SSH Client Library that is subject to
- * the license included in the distributed package.
- * You may not use this file except in compliance with the license.
- *
- * ---------------------------------------------------------------------------
- */
- using System;
- using System.IO;
- using System.Security.Cryptography;
- using System.Net.Sockets;
- using System.Text;
- using System.Diagnostics;
- using Granados.PKI;
- using Granados.SSHC;
- using Granados.Toolkit;
- namespace Granados.SSHCV1
- {
- public sealed class SSH1Connection : SSHConnection {
-
- private const int AUTH_NOT_REQUIRED = 0;
- private const int AUTH_REQUIRED = 1;
- private SSH1ConnectionInfo _cInfo;
- private int _shellID;
- private SSH1PacketBuilder _packetBuilder;
- private bool _executingShell;
-
- public SSH1Connection(SSHConnectionParameter param, ISSHConnectionEventReceiver er, string serverversion, string clientversion) : base(param, er) {
- _cInfo = new SSH1ConnectionInfo();
- _cInfo._serverVersionString = serverversion;
- _cInfo._clientVersionString = clientversion;
- _shellID = -1;
- _packetBuilder = new SSH1PacketBuilder(new SynchronizedSSH1PacketHandler());
- }
- public override SSHConnectionInfo ConnectionInfo {
- get {
- return _cInfo;
- }
- }
- internal override IByteArrayHandler PacketBuilder {
- get {
- return _packetBuilder;
- }
- }
- public override int ChannelCount {
- get {
- return base.ChannelCount + 1; //'1' is for the shell
- }
- }
- internal override AuthenticationResult Connect(AbstractSocket s) {
- _stream = s;
-
- // Phase2 receives server keys
- ReceiveServerKeys();
- if(_param.KeyCheck!=null && !_param.KeyCheck(_cInfo)) {
- _stream.Close();
- return AuthenticationResult.Failure;
- }
- // Phase3 generates session key
- byte[] session_key = GenerateSessionKey();
-
- // Phase4 establishes the session key
- try {
- _packetBuilder.SetSignal(false);
- SendSessionKey(session_key);
- InitCipher(session_key);
- }
- finally {
- _packetBuilder.SetSignal(true);
- }
- ReceiveKeyConfirmation();
-
- // Phase5 user authentication
- SendUserName(_param.UserName);
- if(ReceiveAuthenticationRequirement()==AUTH_REQUIRED) {
- if(_param.AuthenticationType==AuthenticationType.Password) {
- SendPlainPassword();
- } else if(_param.AuthenticationType==AuthenticationType.PublicKey) {
- DoRSAChallengeResponse();
- }
- bool auth = ReceiveAuthenticationResult();
- if(!auth) throw new SSHException(Strings.GetString("AuthenticationFailed"));
- }
-
- _packetBuilder.Handler = new CallbackSSH1PacketHandler(this);
- return AuthenticationResult.Success;
- }
- internal void Transmit(SSH1Packet p) {
- lock(this) {
- p.WriteTo(_stream, _tCipher);
- }
- }
- public override void Disconnect(string msg) {
- if(_closed) return;
- SSH1DataWriter w = new SSH1DataWriter();
- w.Write(msg);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_DISCONNECT, w.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- _stream.Flush();
- _closed = true;
- _stream.Close();
- }
- public override void Close() {
- if(_closed) return;
- _closed = true;
- _stream.Close();
- }
- public override void SendIgnorableData(string msg) {
- SSH1DataWriter w = new SSH1DataWriter();
- w.Write(msg);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_IGNORE, w.ToByteArray());
- Transmit(p);
- }
-
- private void ReceiveServerKeys() {
- SSH1Packet SSH1Packet = ReceivePacket();
- if(SSH1Packet.Type!=PacketType.SSH_SMSG_PUBLIC_KEY) throw new SSHException("unexpected SSH SSH1Packet type " + SSH1Packet.Type, SSH1Packet.Data);
-
- SSH1DataReader reader = new SSH1DataReader(SSH1Packet.Data);
- _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", SSH1Packet.Data);
-
- //Debug Info
- /*
- System.out.println("Flags="+protocol_flags);
- System.out.println("Cipher="+supported_ciphers_mask);
- System.out.println("Auth="+supported_authentications_mask);
- */
-
- 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")), SSH1Packet.Data);
- if(_param.AuthenticationType==AuthenticationType.PublicKey && (supported_authentications_mask & (1 << (int)AuthenticationType.PublicKey))==0)
- throw new SSHException(String.Format(Strings.GetString("ServerNotSupportedRSA")), SSH1Packet.Data);
- }
-
- private byte[] GenerateSessionKey() {
- //session key(256bits)
- byte[] session_key = new byte[32];
- _param.Random.NextBytes(session_key);
- //for(int i=0; i<32; i++) Debug.Write(String.Format("0x{0:x}, ", session_key[i]));
-
- return session_key;
- }
-
- private void SendSessionKey(byte[] session_key) {
- try
- {
- //step1 XOR with session_id
- byte[] working_data = new byte[session_key.Length];
- byte[] session_id = CalcSessionID();
- Array.Copy(session_key, 0, working_data, 0, session_key.Length);
- for(int i=0; i<session_id.Length; i++) working_data[i] ^= session_id[i];
- //step2 decrypts with RSA
- RSAPublicKey first_encryption;
- RSAPublicKey second_encryption;
- SSHServerInfo si = _cInfo._serverinfo;
- int first_key_bytelen, second_key_bytelen;
- if(si.server_key_bits < si.host_key_bits)
- {
- first_encryption = new RSAPublicKey(si.server_key_public_exponent, si.server_key_public_modulus);
- second_encryption = new RSAPublicKey(si.host_key_public_exponent, si.host_key_public_modulus);
- first_key_bytelen = (si.server_key_bits+7)/8;
- second_key_bytelen = (si.host_key_bits+7)/8;
- }
- else
- {
- first_encryption = new RSAPublicKey(si.host_key_public_exponent, si.host_key_public_modulus);
- second_encryption = new RSAPublicKey(si.server_key_public_exponent, si.server_key_public_modulus);
- first_key_bytelen = (si.host_key_bits+7)/8;
- second_key_bytelen = (si.server_key_bits+7)/8;
- }
- BigInteger first_result = RSAUtil.PKCS1PadType2(new BigInteger(working_data), first_key_bytelen, _param.Random).modPow(first_encryption.Exponent, first_encryption.Modulus);
- BigInteger second_result = RSAUtil.PKCS1PadType2(first_result, second_key_bytelen, _param.Random).modPow(second_encryption.Exponent, second_encryption.Modulus);
- //output
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write((byte)_cInfo._algorithmForTransmittion);
- writer.Write(si.anti_spoofing_cookie);
- writer.Write(second_result);
- writer.Write(0); //protocol flags
- //send
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_SESSION_KEY, writer.ToByteArray());
- SSH1Packet.WriteTo(_stream);
- _sessionID = session_id;
- }
- catch(Exception e)
- {
- if(e is IOException)
- throw (IOException)e;
- else
- {
- string t = e.StackTrace;
- throw new SSHException(e.Message); //IOException埲奜偼傒側SSHException偵偟偰偟傑偆
- }
- }
- }
-
- private void ReceiveKeyConfirmation() {
- SSH1Packet SSH1Packet = ReceivePacket();
- if(SSH1Packet.Type!=PacketType.SSH_SMSG_SUCCESS)
- throw new SSHException("unexpected packet type [" + SSH1Packet.Type +"] at ReceiveKeyConfirmation()", SSH1Packet.Data);
- }
-
- private int ReceiveAuthenticationRequirement() {
- SSH1Packet SSH1Packet = ReceivePacket();
- if(SSH1Packet.Type==PacketType.SSH_SMSG_SUCCESS)
- return AUTH_NOT_REQUIRED;
- else if(SSH1Packet.Type==PacketType.SSH_SMSG_FAILURE)
- return AUTH_REQUIRED;
- else
- throw new SSHException("type " + SSH1Packet.Type, SSH1Packet.Data);
- }
-
- private void SendUserName(string username) {
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(username);
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_USER, writer.ToByteArray());
- SSH1Packet.WriteTo(_stream, _tCipher);
- }
- private void SendPlainPassword() {
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(_param.Password);
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_PASSWORD, writer.ToByteArray());
- SSH1Packet.WriteTo(_stream, _tCipher);
- }
- //RSA authentication
- private void DoRSAChallengeResponse() {
- //read key
- SSH1UserAuthKey key = new SSH1UserAuthKey(_param.IdentityFile, _param.Password);
- SSH1DataWriter w = new SSH1DataWriter();
- w.Write(key.PublicModulus);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA, w.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- p = ReceivePacket();
- if(p.Type==PacketType.SSH_SMSG_FAILURE)
- throw new SSHException(Strings.GetString("ServerRefusedRSA"));
- else if(p.Type!=PacketType.SSH_SMSG_AUTH_RSA_CHALLENGE)
- throw new SSHException(String.Format(Strings.GetString("UnexpectedResponse"), p.Type));
- //creating challenge
- SSH1DataReader r = new SSH1DataReader(p.Data);
- BigInteger challenge = key.decryptChallenge(r.ReadMPInt());
- byte[] rawchallenge = RSAUtil.StripPKCS1Pad(challenge, 2).getBytes();
- //building response
- MemoryStream bos = new MemoryStream();
- bos.Write(rawchallenge, 0, rawchallenge.Length); //!!mindterm偱偼摢偑侽偐偳偆偐偱曄側僴儞僪儕儞僌偑偁偭偨
- bos.Write(_sessionID, 0, _sessionID.Length);
- byte[] response = new MD5CryptoServiceProvider().ComputeHash(bos.ToArray());
- w = new SSH1DataWriter();
- w.Write(response);
- p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_AUTH_RSA_RESPONSE, w.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- }
- private bool ReceiveAuthenticationResult() {
- SSH1Packet SSH1Packet = ReceivePacket();
- PacketType type = SSH1Packet.Type;
- if(type==PacketType.SSH_MSG_DEBUG) {
- SSH1DataReader r = new SSH1DataReader(SSH1Packet.Data);
- //Debug.WriteLine("receivedd debug message:"+Encoding.ASCII.GetString(r.ReadString()));
- return ReceiveAuthenticationResult();
- }
- else if(type==PacketType.SSH_SMSG_SUCCESS)
- return true;
- else if(type==PacketType.SSH_SMSG_FAILURE)
- return false;
- else
- throw new SSHException("type: " + type, SSH1Packet.Data);
- }
- public override SSHChannel OpenShell(ISSHChannelEventReceiver receiver) {
- if(_shellID!=-1)
- throw new SSHException("A shell is opened already");
- _shellID = RegisterChannelEventReceiver(null, receiver)._localID;
- SendRequestPTY();
- _executingShell = true;
- return new SSH1Channel(this, ChannelType.Shell, _shellID);
- }
- private void SendRequestPTY() {
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(_param.TerminalName);
- writer.Write(_param.TerminalHeight);
- writer.Write(_param.TerminalWidth);
- writer.Write(_param.TerminalPixelWidth);
- writer.Write(_param.TerminalPixelHeight);
- writer.Write(new byte[1]); //TTY_OP_END
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_REQUEST_PTY, writer.ToByteArray());
- SSH1Packet.WriteTo(_stream, _tCipher);
- }
-
- private void ExecShell() {
- //System.out.println("EXEC SHELL");
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_EXEC_SHELL);
- SSH1Packet.WriteTo(_stream, _tCipher);
- }
- public override SSHChannel ForwardPort(ISSHChannelEventReceiver receiver, string remote_host, int remote_port, string originator_host, int originator_port) {
- if(_shellID==-1) {
- ExecShell();
- _shellID = RegisterChannelEventReceiver(null, new SSH1DummyReceiver())._localID;
- }
-
- int local_id = this.RegisterChannelEventReceiver(null, receiver)._localID;
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(local_id); //channel id is fixed to 0
- writer.Write(remote_host);
- writer.Write(remote_port);
- //originator is specified only if SSH_PROTOFLAG_HOST_IN_FWD_OPEN is specified
- //writer.Write(originator_host);
- SSH1Packet SSH1Packet = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_PORT_OPEN, writer.ToByteArray());
- SSH1Packet.WriteTo(_stream, _tCipher);
- return new SSH1Channel(this, ChannelType.ForwardedLocalToRemote, local_id);
- }
- public override void ListenForwardedPort(string allowed_host, int bind_port) {
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(bind_port);
- writer.Write(allowed_host);
- writer.Write(0);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_PORT_FORWARD_REQUEST, writer.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- if(_shellID==-1) {
- ExecShell();
- _shellID = RegisterChannelEventReceiver(null, new SSH1DummyReceiver())._localID;
- }
- }
- public override void CancelForwardedPort(string host, int port) {
- throw new NotSupportedException("not implemented");
- }
- private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1Packet packet) {
- SSH1DataReader reader = new SSH1DataReader(packet.Data);
- 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 = this.RegisterChannelEventReceiver(null, result.channel)._localID;
- _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel));
- writer.Write(server_channel);
- writer.Write(local_id);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, writer.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- }
- else {
- writer.Write(server_channel);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE, writer.ToByteArray());
- p.WriteTo(_stream, _tCipher);
- }
- }
- private byte[] CalcSessionID() {
- MemoryStream bos = new MemoryStream();
- SSHServerInfo si = _cInfo._serverinfo;
- byte[] h = si.host_key_public_modulus.getBytes();
- byte[] s = si.server_key_public_modulus.getBytes();
- //System.out.println("len h="+h.Length);
- //System.out.println("len s="+s.Length);
-
- int off_h = (h[0]==0? 1 : 0);
- int off_s = (s[0]==0? 1 : 0);
- bos.Write(h, off_h, h.Length-off_h);
- bos.Write(s, off_s, s.Length-off_s);
- bos.Write(si.anti_spoofing_cookie, 0, si.anti_spoofing_cookie.Length);
-
- byte[] session_id = new MD5CryptoServiceProvider().ComputeHash(bos.ToArray());
- //System.out.println("sess-id-len=" + session_id.Length);
- return session_id;
- }
-
- //init ciphers
- private void InitCipher(byte[] session_key) {
- _tCipher = CipherFactory.CreateCipher(SSHProtocol.SSH1, _cInfo._algorithmForTransmittion, session_key);
- Cipher rc = CipherFactory.CreateCipher(SSHProtocol.SSH1, _cInfo._algorithmForReception, session_key);
- _packetBuilder.SetCipher(rc, _param.CheckMACError);
- }
- private SSH1Packet ReceivePacket() {
- while(true) {
- SSH1Packet p = null;
- SynchronizedSSH1PacketHandler handler = (SynchronizedSSH1PacketHandler)_packetBuilder.Handler;
- if(!handler.HasPacket) {
- handler.Wait();
- if(handler.State==ReceiverState.Error)
- throw new SSHException(handler.ErrorMessage);
- else if(handler.State==ReceiverState.Closed)
- throw new SSHException("socket closed");
- }
- p = handler.PopPacket();
- SSH1DataReader r = new SSH1DataReader(p.Data);
- PacketType pt = p.Type;
- if(pt==PacketType.SSH_MSG_IGNORE) {
- if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(r.ReadString());
- }
- else if(pt==PacketType.SSH_MSG_DEBUG) {
- if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(false, r.ReadString());
- }
- else
- return p;
- }
- }
-
- internal void AsyncReceivePacket(SSH1Packet p) {
- try {
- int len = 0, channel = 0;
- switch(p.Type) {
- case PacketType.SSH_SMSG_STDOUT_DATA:
- len = SSHUtil.ReadInt32(p.Data, 0);
- FindChannelEntry(_shellID)._receiver.OnData(p.Data, 4, len);
- break;
- case PacketType.SSH_SMSG_STDERR_DATA: {
- SSH1DataReader re = new SSH1DataReader(p.Data);
- FindChannelEntry(_shellID)._receiver.OnExtendedData((int)PacketType.SSH_SMSG_STDERR_DATA, re.ReadString());
- }
- break;
- case PacketType.SSH_MSG_CHANNEL_DATA:
- channel = SSHUtil.ReadInt32(p.Data, 0);
- len = SSHUtil.ReadInt32(p.Data, 4);
- FindChannelEntry(channel)._receiver.OnData(p.Data, 8, len);
- break;
- case PacketType.SSH_MSG_PORT_OPEN:
- this.ProcessPortforwardingRequest(_eventReceiver, p);
- break;
- case PacketType.SSH_MSG_CHANNEL_CLOSE: {
- channel = SSHUtil.ReadInt32(p.Data, 0);
- ISSHChannelEventReceiver r = FindChannelEntry(channel)._receiver;
- UnregisterChannelEventReceiver(channel);
- r.OnChannelClosed();
- }
- break;
- case PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION:
- channel = SSHUtil.ReadInt32(p.Data, 0);
- break;
- case PacketType.SSH_MSG_DISCONNECT:
- _eventReceiver.OnConnectionClosed();
- break;
- case PacketType.SSH_SMSG_EXITSTATUS:
- FindChannelEntry(_shellID)._receiver.OnChannelClosed();
- break;
- case PacketType.SSH_MSG_DEBUG: {
- SSH1DataReader re = new SSH1DataReader(p.Data);
- _eventReceiver.OnDebugMessage(false, re.ReadString());
- }
- break;
- case PacketType.SSH_MSG_IGNORE: {
- SSH1DataReader re = new SSH1DataReader(p.Data);
- _eventReceiver.OnIgnoreMessage(re.ReadString());
- }
- break;
- case PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: {
- int local = SSHUtil.ReadInt32(p.Data, 0);
- int remote = SSHUtil.ReadInt32(p.Data, 4);
- FindChannelEntry(local)._receiver.OnChannelReady();
- }
- break;
- case PacketType.SSH_SMSG_SUCCESS:
- if(_executingShell) {
- ExecShell();
- this.FindChannelEntry(_shellID)._receiver.OnChannelReady();
- _executingShell = false;
- }
- break;
- default:
- _eventReceiver.OnUnknownMessage((byte)p.Type, p.Data);
- break;
- }
- }
- catch(Exception ex) {
- if(!_closed)
- _eventReceiver.OnError(ex, ex.Message);
- }
- }
- }
- public class SSH1Channel : SSHChannel {
-
- public SSH1Channel(SSHConnection con, ChannelType type, int local_id) : base(con, type, local_id) {
- }
- public SSH1Channel(SSHConnection con, ChannelType type, int local_id, int remote_id) : base(con, type, local_id) {
- _remoteID = remote_id;
- }
- /**
- * resizes the size of terminal
- */
- public override void ResizeTerminal(int width, int height, int pixel_width, int pixel_height) {
- SSH1DataWriter writer = new SSH1DataWriter();
- writer.Write(height);
- writer.Write(width);
- writer.Write(pixel_width);
- writer.Write(pixel_height);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_WINDOW_SIZE, writer.ToByteArray());
- Transmit(p);
- }
- /**
- * transmits channel data
- */
- public override void Transmit(byte[] data) {
- SSH1DataWriter wr = new SSH1DataWriter();
- if(_type==ChannelType.Shell) {
- wr.WriteAsString(data);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_STDIN_DATA, wr.ToByteArray());
- Transmit(p);
- }
- else {
- wr.Write(_remoteID);
- wr.WriteAsString(data);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_DATA, wr.ToByteArray());
- Transmit(p);
- }
- }
- /**
- * transmits channel data
- */
- public override void Transmit(byte[] data, int offset, int length) {
- SSH1DataWriter wr = new SSH1DataWriter();
- if(_type==ChannelType.Shell) {
- wr.WriteAsString(data, offset, length);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_STDIN_DATA, wr.ToByteArray());
- Transmit(p);
- }
- else {
- wr.Write(_remoteID);
- wr.WriteAsString(data, offset, length);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_DATA, wr.ToByteArray());
- Transmit(p);
- }
- }
- public override void SendEOF() {
- }
- /**
- * closes this channel
- */
- public override void Close() {
- if(_connection.IsClosed) return;
- if(_type==ChannelType.Shell) {
- SSH1DataWriter wr2 = new SSH1DataWriter();
- wr2.Write(_remoteID);
- SSH1Packet p2 = SSH1Packet.FromPlainPayload(PacketType.SSH_CMSG_EOF, wr2.ToByteArray());
- Transmit(p2);
- }
- SSH1DataWriter wr = new SSH1DataWriter();
- wr.Write(_remoteID);
- SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_CLOSE, wr.ToByteArray());
- Transmit(p);
- }
- private void Transmit(SSH1Packet p) {
- ((SSH1Connection)_connection).Transmit(p);
- }
- }
- //if port forwardings are performed without a shell, we use SSH1DummyChannel to receive shell data
- internal class SSH1DummyReceiver : ISSHChannelEventReceiver {
- public void OnData(byte[] data, int offset, int length) {
- }
- public void OnExtendedData(int type, byte[] data) {
- }
- public void OnChannelClosed() {
- }
- public void OnChannelEOF() {
- }
- public void OnChannelReady() {
- }
- public void OnChannelError(Exception error, string msg) {
- }
- public void OnMiscPacket(byte packet_type, byte[] data, int offset, int length) {
- }
- }
- }