예제 #1
0
 public override void Close()
 {
     if(_connection.IsClosed) return;
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_CLOSE);
     wr.Write(_remoteID);
     TransmitPacket(wr.ToByteArray());
 }
예제 #2
0
 public override void ResizeTerminal(int width, int height, int pixel_width, int pixel_height)
 {
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
     wr.Write(_remoteID);
     wr.Write("window-change");
     wr.Write(false);
     wr.Write(width);
     wr.Write(height);
     wr.Write(pixel_width); //no graphics
     wr.Write(pixel_height);
     TransmitPacket(wr.ToByteArray());
 }
예제 #3
0
        private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH2DataReader reader)
        {
            string method = Encoding.ASCII.GetString(reader.ReadString());

            int remote_channel = reader.ReadInt32();
            int window_size = reader.ReadInt32(); //skip initial window size
            int servermaxpacketsize = reader.ReadInt32();
            string host = Encoding.ASCII.GetString(reader.ReadString());
            int port = reader.ReadInt32();
            string originator_ip = Encoding.ASCII.GetString(reader.ReadString());
            int originator_port = reader.ReadInt32();

            PortForwardingCheckResult r = receiver.CheckPortForwardingRequest(host,port,originator_ip,originator_port);
            SSH2DataWriter wr = new SSH2DataWriter();
            if(r.allowed) {
                //send OPEN_CONFIRMATION
                SSH2Channel channel = new SSH2Channel(this, ChannelType.ForwardedRemoteToLocal, RegisterChannelEventReceiver(null, r.channel)._localID, remote_channel, servermaxpacketsize);
                wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
                wr.Write(remote_channel);
                wr.Write(channel.LocalChannelID);
                wr.Write(_param.WindowSize); //initial window size
                wr.Write(_param.MaxPacketSize); //max packet size
                receiver.EstablishPortforwarding(r.channel, channel);
            }
            else {
                wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE);
                wr.Write(remote_channel);
                wr.Write(r.reason_code);
                wr.Write(r.reason_message);
                wr.Write(""); //lang tag
            }
            TransmitPacket(wr.ToByteArray());
        }
예제 #4
0
 public override void SendIgnorableData(string msg)
 {
     SSH2DataWriter w = new SSH2DataWriter();
     w.WritePacketType(PacketType.SSH_MSG_IGNORE);
     w.Write(msg);
     TransmitPacket(w.ToByteArray());
 }
예제 #5
0
        public override SSHChannel OpenShell(ISSHChannelEventReceiver receiver)
        {
            //open channel
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN);
            wr.Write("session");
            int local_channel = this.RegisterChannelEventReceiver(null, receiver)._localID;

            wr.Write(local_channel);
            wr.Write(_param.WindowSize); //initial window size
            int windowsize = _param.WindowSize;
            wr.Write(_param.MaxPacketSize); //max packet size
            SSH2Channel channel = new SSH2Channel(this, ChannelType.Shell, local_channel);
            TransmitPacket(wr.ToByteArray());

            return channel;
        }
예제 #6
0
        public override void ListenForwardedPort(string allowed_host, int bind_port)
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_GLOBAL_REQUEST);
            wr.Write("tcpip-forward");
            wr.Write(true);
            wr.Write(allowed_host);
            wr.Write(bind_port);

            _waitingForPortForwardingResponse = true;
            TransmitPacket(wr.ToByteArray());
        }
예제 #7
0
 //maybe this is SSH2 only feature
 public void SetEnvironmentVariable(string name, string value)
 {
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
     wr.Write(_remoteID);
     wr.Write("env");
     wr.Write(false);
     wr.Write(name);
     wr.Write(value);
     TransmitPacket(wr.ToByteArray());
 }
예제 #8
0
 public override void CancelForwardedPort(string host, int port)
 {
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_GLOBAL_REQUEST);
     wr.Write("cancel-tcpip-forward");
     wr.Write(true);
     wr.Write(host);
     wr.Write(port);
     TransmitPacket(wr.ToByteArray());
 }
예제 #9
0
 public override void Disconnect(string msg)
 {
     if(_closed) return;
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_DISCONNECT);
     wr.Write(0);
     wr.Write(msg);
     wr.Write(""); //language
     TransmitPacket(wr.ToByteArray());
     _stream.Flush();
     _closed = true;
     _stream.Close();
 }
예제 #10
0
        internal void ProcessPacket(ISSHChannelEventReceiver receiver, PacketType pt, int data_length, SSH2DataReader re)
        {
            //NOTE: the offset of 're' is next to 'receipiant channel' field
            _leftWindowSize -= data_length;
            if(pt!=PacketType.SSH_MSG_CHANNEL_EOF && pt!=PacketType.SSH_MSG_CHANNEL_CLOSE) { //window adjust is not necessary if the channel is being closed
                while(_leftWindowSize <= _windowSize) {
                    SSH2DataWriter adj = new SSH2DataWriter();
                    adj.WritePacketType(PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST);
                    adj.Write(_remoteID);
                    adj.Write(_windowSize);
                    TransmitPacket(adj.ToByteArray());
                    _leftWindowSize += _windowSize;
                    //Debug.WriteLine("Window size is adjusted to " + _leftWindowSize);
                }
            }

            if(pt==PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST) {
                int w = re.ReadInt32();
                //some servers may not send SSH_MSG_CHANNEL_WINDOW_ADJUST.
                //it is dangerous to wait this message in send procedure
                _allowedDataSize += w;
                //Debug.WriteLine(String.Format("Window Adjust +={0}",w));
            }
            else if(_negotiationStatus!=0) { //when the negotiation is not completed
                if(_type==ChannelType.Shell)
                    OpenShell(receiver, pt, re);
                else if(_type==ChannelType.ForwardedLocalToRemote)
                    ReceivePortForwardingResponse(receiver, pt, re);
                else if(_type==ChannelType.Session)
                    EstablishSession(receiver, pt, re);
            }
            else {
                switch(pt) {
                    case PacketType.SSH_MSG_CHANNEL_DATA: {
                        int len = re.ReadInt32();
                        receiver.OnData(re.Image, re.Offset, len);
                    }
                        break;
                    case PacketType.SSH_MSG_CHANNEL_EXTENDED_DATA: {
                        int t = re.ReadInt32();
                        byte[] data = re.ReadString();
                        receiver.OnExtendedData(t, data);
                    }
                        break;
                    case PacketType.SSH_MSG_CHANNEL_REQUEST: {
                        string request = Encoding.ASCII.GetString(re.ReadString());
                        bool reply = re.ReadBool();
                        if(request=="exit-status") {
                            int status = re.ReadInt32();
                        }
                        else if(reply) { //we reject unknown requests including keep-alive check
                            SSH2DataWriter wr = new SSH2DataWriter();
                            wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_FAILURE);
                            wr.Write(_remoteID);
                            TransmitPacket(wr.ToByteArray());
                        }
                    }
                        break;
                    case PacketType.SSH_MSG_CHANNEL_EOF:
                        receiver.OnChannelEOF();
                        break;
                    case PacketType.SSH_MSG_CHANNEL_CLOSE:
                        _connection.UnregisterChannelEventReceiver(_localID);
                        receiver.OnChannelClosed();
                        break;
                    case PacketType.SSH_MSG_CHANNEL_FAILURE:
                    case PacketType.SSH_MSG_CHANNEL_SUCCESS:
                        receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest);
                        break;
                    default:
                        receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest);
                        Debug.WriteLine("Unknown Packet "+pt);
                        break;
                }

            }
        }
예제 #11
0
        private void OpenShell(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader reader)
        {
            if(_negotiationStatus==3) {
                if(pt!=PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
                    if(pt!=PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE)
                        receiver.OnChannelError(null, "opening channel failed; packet type="+pt);
                    else {
                        int errcode = reader.ReadInt32();
                        string msg = Encoding.ASCII.GetString(reader.ReadString());
                        receiver.OnChannelError(null, msg);
                    }
                    Close();
                }
                else {
                    _remoteID = reader.ReadInt32();
                    _allowedDataSize = reader.ReadInt32();
                    _serverMaxPacketSize = reader.ReadInt32();

                    //open pty
                    SSH2DataWriter wr = new SSH2DataWriter();
                    wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
                    wr.Write(_remoteID);
                    wr.Write("pty-req");
                    wr.Write(true);
                    wr.Write(_connection.Param.TerminalName);
                    wr.Write(_connection.Param.TerminalWidth);
                    wr.Write(_connection.Param.TerminalHeight);
                    wr.Write(_connection.Param.TerminalPixelWidth);
                    wr.Write(_connection.Param.TerminalPixelHeight);
                    wr.WriteAsString(new byte[0]);
                    TransmitPacket(wr.ToByteArray());

                    _negotiationStatus = 2;
                }
            }
            else if(_negotiationStatus==2) {
                if(pt!=PacketType.SSH_MSG_CHANNEL_SUCCESS) {
                    receiver.OnChannelError(null, "opening pty failed");
                    Close();
                }
                else {
                    //open shell
                    SSH2DataWriter wr = new SSH2DataWriter();
                    wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
                    wr.Write(_remoteID);
                    wr.Write("shell");
                    wr.Write(true);
                    TransmitPacket(wr.ToByteArray());

                    _negotiationStatus = 1;
                }
            }
            else if(_negotiationStatus==1) {
                if(pt!=PacketType.SSH_MSG_CHANNEL_SUCCESS) {
                    receiver.OnChannelError(null, "Opening shell failed: packet type="+pt.ToString());
                    Close();
                }
                else {
                    receiver.OnChannelReady();
                    _negotiationStatus = 0; //goal!
                }
            }
            else
                Debug.Assert(false);
        }
예제 #12
0
        public override void Transmit(byte[] data, int offset, int length)
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_DATA);
            wr.Write(_remoteID);
            wr.WriteAsString(data, offset, length);

            TransmitPacket(wr.ToByteArray());
        }
예제 #13
0
        public override void Transmit(byte[] data)
        {
            //!!it is better idea that we wait a WINDOW_ADJUST if the left size is lack
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_DATA);
            wr.Write(_remoteID);
            wr.WriteAsString(data);

            TransmitPacket(wr.ToByteArray());
        }
예제 #14
0
        private void SendKEXINIT()
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_KEXINIT);
            byte[] cookie = new byte[16];
            _param.Random.NextBytes(cookie);
            wr.Write(cookie);
            wr.Write("diffie-hellman-group1-sha1"); //    kex_algorithms
            wr.Write(FormatHostKeyAlgorithmDescription());            //    server_host_key_algorithms
            wr.Write(FormatCipherAlgorithmDescription());      //    encryption_algorithms_client_to_server
            wr.Write(FormatCipherAlgorithmDescription());      //    encryption_algorithms_server_to_client
            wr.Write("hmac-sha1");                  //    mac_algorithms_client_to_server
            wr.Write("hmac-sha1");                  //    mac_algorithms_server_to_client
            wr.Write("none");                       //    compression_algorithms_client_to_server
            wr.Write("none");                       //    compression_algorithms_server_to_client
            wr.Write("");                           //    languages_client_to_server
            wr.Write("");                           //    languages_server_to_client
            wr.Write(false); //Indicates whether a guessed key exchange packet follows
            wr.Write(0);       //reserved for future extension

            _clientKEXINITPayload = wr.ToByteArray();
            _status = Status.WAIT_KEXINIT;
            TransmitPacket(_clientKEXINITPayload);
        }
예제 #15
0
        private void ServiceRequest(string servicename)
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_SERVICE_REQUEST);
            wr.Write(servicename);
            TransmitPacket(wr.ToByteArray());

            byte[] response = ReceivePacket().Data;
            SSH2DataReader re = new SSH2DataReader(response);
            PacketType t = re.ReadPacketType();
            if(t!=PacketType.SSH_MSG_SERVICE_ACCEPT) {
                throw new SSHException("service establishment failed "+t);
            }

            string s = Encoding.ASCII.GetString(re.ReadString());
            if(servicename!=s)
                throw new SSHException("protocol error");
        }
예제 #16
0
        public AuthenticationResult DoKeyboardInteractiveAuth(string[] input)
        {
            if(_param.AuthenticationType!=AuthenticationType.KeyboardInteractive)
                throw new SSHException("DoKeyboardInteractiveAuth() must be called with keyboard-interactive authentication");
            SSH2DataWriter re = new SSH2DataWriter();
            re.WritePacketType(PacketType.SSH_MSG_USERAUTH_INFO_RESPONSE);
            re.Write(input.Length);
            foreach(string t in input)
                re.Write(t);
            TransmitPacket(re.ToByteArray());

            _authenticationResult = ProcessAuthenticationResponse();
            //try again on failure
            if(_authenticationResult==AuthenticationResult.Failure) {
                SSH2DataWriter wr = new SSH2DataWriter();
                wr.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST);
                wr.Write(_param.UserName);
                wr.Write("ssh-connection");
                wr.Write("keyboard-interactive");
                wr.Write(""); //lang
                wr.Write(""); //submethod
                TransmitPacket(wr.ToByteArray());
                _authenticationResult = ProcessAuthenticationResponse();
            }
            return _authenticationResult;
        }
예제 #17
0
        private AuthenticationResult UserAuth()
        {
            string sn = "ssh-connection";

            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST);
            wr.Write(_param.UserName);
            if(_param.AuthenticationType==AuthenticationType.Password) {
                //Password authentication
                wr.Write(sn);
                wr.Write("password");
                wr.Write(false);
                wr.Write(_param.Password);
            }
            else if(_param.AuthenticationType==AuthenticationType.KeyboardInteractive) {
                wr.Write(sn);
                wr.Write("keyboard-interactive");
                wr.Write(""); //lang
                wr.Write(""); //submethod
            }
            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.Write(_param.UserName);
                signsource.Write(sn);
                signsource.Write("publickey");
                signsource.Write(true);
                signsource.Write(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm));
                signsource.WriteAsString(kp.GetPublicKeyBlob());

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

                wr.Write(sn);
                wr.Write("publickey");
                wr.Write(true);
                wr.Write(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm));
                wr.WriteAsString(kp.GetPublicKeyBlob());
                wr.WriteAsString(signpack.ToByteArray());
            }
            TransmitPacket(wr.ToByteArray());

            _authenticationResult = ProcessAuthenticationResponse();
            if(_authenticationResult==AuthenticationResult.Failure)
                throw new SSHException(Strings.GetString("AuthenticationFailed"));
            return _authenticationResult;
        }
예제 #18
0
        public override SSHChannel ForwardPort(ISSHChannelEventReceiver receiver, string remote_host, int remote_port, string originator_host, int originator_port)
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN);
            wr.Write("direct-tcpip");
            int local_id = RegisterChannelEventReceiver(null, receiver)._localID;
            wr.Write(local_id);
            wr.Write(_param.WindowSize); //initial window size
            int windowsize = _param.WindowSize;
            wr.Write(_param.MaxPacketSize); //max packet size
            wr.Write(remote_host);
            wr.Write(remote_port);
            wr.Write(originator_host);
            wr.Write(originator_port);

            SSH2Channel channel = new SSH2Channel(this, ChannelType.ForwardedLocalToRemote, local_id);

            TransmitPacket(wr.ToByteArray());

            return channel;
        }
예제 #19
0
 public void SendBreak(int time)
 {
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST);
     wr.Write(_remoteID);
     wr.Write("break");
     wr.Write(true);
     wr.Write(time);
     TransmitPacket(wr.ToByteArray());
 }
예제 #20
0
 private void SendKEXDHINIT()
 {
     //Round1 computes and sends [e]
     byte[] sx = new byte[16];
     _param.Random.NextBytes(sx);
     _x = new BigInteger(sx);
     _e = new BigInteger(2).modPow(_x, DH_PRIME);
     SSH2DataWriter wr = new SSH2DataWriter();
     wr.WritePacketType(PacketType.SSH_MSG_KEXDH_INIT);
     wr.Write(_e);
     _status = Status.WAIT_KEXDH_REPLY;
     TransmitPacket(wr.ToByteArray());
 }