public override string DumpHostKeyInKnownHostsStyle()
        {
            StringBuilder bld = new StringBuilder();

            bld.Append(SSH2Util.PublicKeyAlgorithmName(_hostkey.Algorithm));
            bld.Append(' ');
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(SSH2Util.PublicKeyAlgorithmName(_hostkey.Algorithm));
            if (_hostkey.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAPublicKey rsa = (RSAPublicKey)_hostkey;
                wr.Write(rsa.Exponent);
                wr.Write(rsa.Modulus);
            }
            else if (_hostkey.Algorithm == PublicKeyAlgorithm.DSA)
            {
                DSAPublicKey dsa = (DSAPublicKey)_hostkey;
                wr.Write(dsa.P);
                wr.Write(dsa.Q);
                wr.Write(dsa.G);
                wr.Write(dsa.Y);
            }
            else
            {
                throw new SSHException("Host key algorithm is unsupported");
            }

            bld.Append(Encoding.ASCII.GetString(Base64.Encode(wr.ToByteArray())));
            return(bld.ToString());
        }
        public byte[] GetPublicKeyBlob()
        {
            SSH2DataWriter w = new SSH2DataWriter();

            w.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
            _keypair.PublicKey.WriteTo(w);
            return(w.ToByteArray());
        }
 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());
 }
        private string FormatBase64EncodedPublicKeyBody()
        {
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
            _keypair.PublicKey.WriteTo(wr);

            return(Encoding.ASCII.GetString(Base64.Encode(wr.ToByteArray())));
        }
 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());
 }
Exemple #6
0
        public static SSH2Packet FromDecryptedHead(byte[] head, byte[] buffer, int offset, Cipher cipher, int sequence, MAC mac)
        {
            SSH2Packet p = new SSH2Packet();

            p._packetLength = SSHUtil.ReadInt32(head, 0);
            if (p._packetLength <= 0 || p._packetLength >= MAX_PACKET_LENGTH)
            {
                throw new SSHException(String.Format("packet size {0} is invalid", p._packetLength));
            }
            SSH2DataWriter buf = new SSH2DataWriter();

            buf.Write(sequence);
            buf.Write(head);
            if (p._packetLength > (cipher.BlockSize - 4))
            {
                byte[] tmp = new byte[p._packetLength - (cipher.BlockSize - 4)];
                cipher.Decrypt(buffer, offset, tmp.Length, tmp, 0);
                offset += tmp.Length;
                buf.Write(tmp);
            }
            byte[] result      = buf.ToByteArray();
            int    padding_len = (int)result[8];

            if (padding_len < 4)
            {
                throw new SSHException("padding length is invalid");
            }

            byte[] payload = new byte[result.Length - 9 - padding_len];
            Array.Copy(result, 9, payload, 0, payload.Length);
            p._payload = payload;

            if (mac != null)
            {
                p._mac = mac.Calc(result);
                if (SSHUtil.memcmp(p._mac, 0, buffer, offset, mac.Size) != 0)
                {
                    throw new SSHException("MAC Error");
                }
            }
            return(p);
        }
 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();
 }
 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());
 }
        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();
                    _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.Write((byte)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);
        }
Exemple #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;
            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();
                //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.Write((byte)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;
                }

            }
        }
        private string FormatBase64EncodedPublicKeyBody()
        {
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
            _keypair.PublicKey.WriteTo(wr);

            return Encoding.ASCII.GetString(Base64.Encode(wr.ToByteArray()));
        }
Exemple #12
0
 public override void SendIgnorableData(string msg)
 {
     SSH2DataWriter w = new SSH2DataWriter();
     w.WritePacketType(PacketType.SSH_MSG_IGNORE);
     w.Write(msg);
     TransmitPacket(w.ToByteArray());
 }
Exemple #13
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());
        }
Exemple #14
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());
        }
Exemple #15
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());
 }
Exemple #16
0
        private bool ProcessKEXDHREPLY(SSH2Packet packet)
        {
            //Round2 receives response
            SSH2DataReader re = new SSH2DataReader(packet.Data);
            PacketType h = re.ReadPacketType();
            if(h!=PacketType.SSH_MSG_KEXDH_REPLY) throw new SSHException(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h));
            byte[] key_and_cert = re.ReadString();
            BigInteger f = re.ReadMPInt();
            byte[] signature = re.ReadString();
            Debug.Assert(re.Rest==0);

            //Round3 calc hash H
            SSH2DataWriter wr = new SSH2DataWriter();
            _k = f.modPow(_x, DH_PRIME);
            wr = new SSH2DataWriter();
            wr.Write(_cInfo._clientVersionString);
            wr.Write(_cInfo._serverVersionString);
            wr.WriteAsString(_clientKEXINITPayload);
            wr.WriteAsString(_serverKEXINITPayload);
            wr.WriteAsString(key_and_cert);
            wr.Write(_e);
            wr.Write(f);
            wr.Write(_k);
            _hash = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());

            if(!VerifyHostKey(key_and_cert, signature, _hash)) return false;

            //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash));
            if(_sessionID==null) _sessionID = _hash;
            return true;
        }
Exemple #17
0
        public override string DumpHostKeyInKnownHostsStyle()
        {
            StringBuilder bld = new StringBuilder();
            bld.Append(SSH2Util.PublicKeyAlgorithmName(_hostkey.Algorithm));
            bld.Append(' ');
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.Write(SSH2Util.PublicKeyAlgorithmName(_hostkey.Algorithm));
            if(_hostkey.Algorithm==PublicKeyAlgorithm.RSA) {
                RSAPublicKey rsa = (RSAPublicKey)_hostkey;
                wr.Write(rsa.Exponent);
                wr.Write(rsa.Modulus);
            }
            else if(_hostkey.Algorithm==PublicKeyAlgorithm.DSA) {
                DSAPublicKey dsa = (DSAPublicKey)_hostkey;
                wr.Write(dsa.P);
                wr.Write(dsa.Q);
                wr.Write(dsa.G);
                wr.Write(dsa.Y);
            }
            else
                throw new SSHException("Host key algorithm is unsupported");

            bld.Append(Encoding.ASCII.GetString(Base64.Encode(wr.ToByteArray())));
            return bld.ToString();
        }
 public byte[] GetPublicKeyBlob()
 {
     SSH2DataWriter w = new SSH2DataWriter();
     w.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm));
     _keypair.PublicKey.WriteTo(w);
     return w.ToByteArray();
 }
        public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(0);             //this field is filled later
            if (_keypair.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAKeyPair   rsa = (RSAKeyPair)_keypair;
                RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
                wr.WriteBigIntWithBits(pub.Exponent);
                wr.WriteBigIntWithBits(rsa.D);
                wr.WriteBigIntWithBits(pub.Modulus);
                wr.WriteBigIntWithBits(rsa.U);
                wr.WriteBigIntWithBits(rsa.P);
                wr.WriteBigIntWithBits(rsa.Q);
            }
            else
            {
                DSAKeyPair   dsa = (DSAKeyPair)_keypair;
                DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
                wr.Write(0);
                wr.WriteBigIntWithBits(pub.P);
                wr.WriteBigIntWithBits(pub.G);
                wr.WriteBigIntWithBits(pub.Q);
                wr.WriteBigIntWithBits(pub.Y);
                wr.WriteBigIntWithBits(dsa.X);
            }

            int padding_len = 0;

            if (passphrase != null)
            {
                padding_len = 8 - (int)wr.Length % 8;
                wr.Write(new byte[padding_len]);
            }
            byte[] encrypted_body = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4);

            //encrypt if necessary
            if (passphrase != null)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] tmp = new Byte[encrypted_body.Length];
                c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
                encrypted_body = tmp;
            }

            //step2 make binary key data
            wr = new SSH2DataWriter();
            wr.Write(MAGIC_VAL);
            wr.Write(0);             //for total size
            wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA?
                     "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                     "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

            wr.Write(passphrase == null? "none" : "3des-cbc");
            wr.WriteAsString(encrypted_body);

            byte[] rawdata = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length);             //fix total length

            //step3 write final data
            StreamWriter sw = new StreamWriter(dest, Encoding.ASCII);

            sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----");
            if (comment != null)
            {
                WriteKeyFileBlock(sw, "Comment: " + comment, true);
            }
            WriteKeyFileBlock(sw, Encoding.ASCII.GetString(Base64.Encode(rawdata)), false);
            sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----");
            sw.Close();
        }
Exemple #20
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;
        }
Exemple #21
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;
        }
Exemple #22
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;
        }
Exemple #23
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());
 }
Exemple #24
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;
        }
Exemple #25
0
        public static SSH2Packet FromDecryptedHead(byte[] head, byte[] buffer, int offset, Cipher cipher, int sequence, MAC mac)
        {
            SSH2Packet p = new SSH2Packet();
            p._packetLength = SSHUtil.ReadInt32(head, 0);
            if(p._packetLength<=0 || p._packetLength>=MAX_PACKET_LENGTH) throw new SSHException(String.Format("packet size {0} is invalid", p._packetLength));
            SSH2DataWriter buf = new SSH2DataWriter();
            buf.Write(sequence);
            buf.Write(head);
            if(p._packetLength > (cipher.BlockSize - 4)) {
                byte[] tmp = new byte[p._packetLength-(cipher.BlockSize - 4)];
                cipher.Decrypt(buffer, offset, tmp.Length, tmp, 0);
                offset += tmp.Length;
                buf.Write(tmp);
            }
            byte[] result = buf.ToByteArray();
            int padding_len = (int)result[8];
            if(padding_len<4) throw new SSHException("padding length is invalid");

            byte[] payload = new byte[result.Length-9-padding_len];
            Array.Copy(result, 9, payload, 0, payload.Length);
            p._payload = payload;

            if(mac!=null) {
                p._mac = mac.Calc(result);
                if(SSHUtil.memcmp(p._mac, 0, buffer, offset, mac.Size)!=0)
                    throw new SSHException("MAC Error");
            }
            return p;
        }
Exemple #26
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);
        }
        public void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();
            wr.Write(0); //this field is filled later
            if(_keypair.Algorithm==PublicKeyAlgorithm.RSA) {
                RSAKeyPair rsa = (RSAKeyPair)_keypair;
                RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
                wr.WriteBigIntWithBits(pub.Exponent);
                wr.WriteBigIntWithBits(rsa.D);
                wr.WriteBigIntWithBits(pub.Modulus);
                wr.WriteBigIntWithBits(rsa.U);
                wr.WriteBigIntWithBits(rsa.P);
                wr.WriteBigIntWithBits(rsa.Q);
            }
            else {
                DSAKeyPair dsa = (DSAKeyPair)_keypair;
                DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
                wr.Write(0);
                wr.WriteBigIntWithBits(pub.P);
                wr.WriteBigIntWithBits(pub.G);
                wr.WriteBigIntWithBits(pub.Q);
                wr.WriteBigIntWithBits(pub.Y);
                wr.WriteBigIntWithBits(dsa.X);
            }

            int padding_len = 0;
            if(passphrase!=null) {
                padding_len = 8 - (int)wr.Length % 8;
                wr.Write(new byte[padding_len]);
            }
            byte[] encrypted_body = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4);

            //encrypt if necessary
            if(passphrase!=null) {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase,24));
                Debug.Assert(encrypted_body.Length % 8 ==0);
                byte[] tmp = new Byte[encrypted_body.Length];
                c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
                encrypted_body = tmp;
            }

            //step2 make binary key data
            wr = new SSH2DataWriter();
            wr.Write(MAGIC_VAL);
            wr.Write(0); //for total size
            wr.Write(_keypair.Algorithm==PublicKeyAlgorithm.RSA?
                "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

            wr.Write(passphrase==null? "none" : "3des-cbc");
            wr.WriteAsString(encrypted_body);

            byte[] rawdata = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length

            //step3 write final data
            StreamWriter sw = new StreamWriter(dest, Encoding.ASCII);
            sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----");
            if(comment!=null)
                WriteKeyFileBlock(sw, "Comment: " + comment, true);
            WriteKeyFileBlock(sw, Encoding.ASCII.GetString(Base64.Encode(rawdata)), false);
            sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----");
            sw.Close();
        }
Exemple #28
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");
        }
Exemple #29
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());
 }
Exemple #30
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());
        }
Exemple #31
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());
        }
Exemple #32
0
        private byte[] DeriveKey(BigInteger key, byte[] hash, char ch, int length)
        {
            byte[] result = new byte[length];

            SSH2DataWriter wr = new SSH2DataWriter();
            wr.Write(key);
            wr.Write(hash);
            wr.Write((byte)ch);
            wr.Write(_sessionID);
            byte[] h1 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());
            if(h1.Length >= length) {
                Array.Copy(h1, 0, result, 0, length);
                return result;
            }
            else {
                wr = new SSH2DataWriter();
                wr.Write(key);
                wr.Write(_sessionID);
                wr.Write(h1);
                byte[] h2 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray());
                if(h1.Length+h2.Length >= length) {
                    Array.Copy(h1, 0, result, 0, h1.Length);
                    Array.Copy(h2, 0, result, h1.Length, length-h1.Length);
                    return result;
                }
                else
                    throw new SSHException("necessary key length is too big"); //long key is not supported
            }
        }
Exemple #33
0
        public byte[] ToByteArray(string passphrase)
        {
            //step1 key body
            SSH2DataWriter wr = new SSH2DataWriter();

            wr.Write(0);             //this field is filled later
            if (_keypair.Algorithm == PublicKeyAlgorithm.RSA)
            {
                RSAKeyPair   rsa = (RSAKeyPair)_keypair;
                RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey;
                wr.WriteBigIntWithBits(pub.Exponent);
                wr.WriteBigIntWithBits(rsa.D);
                wr.WriteBigIntWithBits(pub.Modulus);
                wr.WriteBigIntWithBits(rsa.U);
                wr.WriteBigIntWithBits(rsa.P);
                wr.WriteBigIntWithBits(rsa.Q);
            }
            else
            {
                DSAKeyPair   dsa = (DSAKeyPair)_keypair;
                DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey;
                wr.Write(0);
                wr.WriteBigIntWithBits(pub.P);
                wr.WriteBigIntWithBits(pub.G);
                wr.WriteBigIntWithBits(pub.Q);
                wr.WriteBigIntWithBits(pub.Y);
                wr.WriteBigIntWithBits(dsa.X);
            }

            int padding_len = 0;

            if (passphrase != null)
            {
                padding_len = 8 - (int)wr.Length % 8;
                wr.Write(new byte[padding_len]);
            }
            byte[] encrypted_body = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4);

            //encrypt if necessary
            if (passphrase != null)
            {
                Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24));
                Debug.Assert(encrypted_body.Length % 8 == 0);
                byte[] tmp = new Byte[encrypted_body.Length];
                c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0);
                encrypted_body = tmp;
            }

            //step2 make binary key data
            wr = new SSH2DataWriter();
            wr.Write(MAGIC_VAL);
            wr.Write(0);             //for total size
            wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA?
                     "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" :
                     "dl-modp{sign{dsa-nist-sha1},dh{plain}}");

            wr.Write(passphrase == null? "none" : "3des-cbc");
            wr.WriteAsString(encrypted_body);

            byte[] rawdata = wr.ToByteArray();
            SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length);             //fix total length

            return(rawdata);
        }