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 Exception(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 Exception("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 Exception("MAC Error"); } } return(p); }
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()); }
internal 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(SSH_COM_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.UTF8); sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"); if(comment!=null) WriteKeyFileBlock(sw, "Comment: " + comment, true); byte[] tmpdata = Base64.Encode(rawdata); WriteKeyFileBlock(sw, Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length), false); sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----"); sw.Dispose(); }
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 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(wr.ToByteArray().AsBuffer()).ToArray(); 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 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(wr.ToByteArray().AsBuffer()).ToArray(); 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 Exception("necessary key length is too big"); //long key is not supported } }
internal 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(SSH_COM_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.UTF8); sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"); if (comment != null) { WriteKeyFileBlock(sw, "Comment: " + comment, true); } byte[] tmpdata = Base64.Encode(rawdata); WriteKeyFileBlock(sw, Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length), false); sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----"); sw.Dispose(); }
private AuthenticationResult ProcessAuthenticationResponse() { do { SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data); PacketType h = response.ReadPacketType(); if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) { byte[] tmpdata = response.ReadString(); string msg = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); _eventReceiver.OnDebugMessage(true, tmpdata); bool partialSuccess = response.ReadBool(); return GranadosRT.Routrek.SSHC.AuthenticationResult.Failure; } else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) { //Debug.WriteLine("USERAUTH_BANNER"); byte[] tmpdata = response.ReadString(); _eventReceiver.OnDebugMessage(true, tmpdata); } else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) { _packetBuilder.Handler = new CallbackSSH2PacketHandler(this); return GranadosRT.Routrek.SSHC.AuthenticationResult.Success; //successfully exit } else if (h == PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) { byte[] tmpdata = response.ReadString(); string name = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string inst = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string lang = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int num = response.ReadInt32(); string[] prompts = new string[num]; for (int i = 0; i < num; i++) { tmpdata = response.ReadString(); prompts[i] = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool echo = response.ReadBool(); } if (prompts.Length == 0) { //TODO 0 length response SSH2DataWriter re = new SSH2DataWriter(); re.WritePacketType(PacketType.SSH_MSG_USERAUTH_INFO_RESPONSE); re.Write(0); byte[] ba = re.ToByteArray(); TransmitPacket(ba); return ProcessAuthenticationResponse(); } else { _eventReceiver.OnAuthenticationPrompt(prompts); return GranadosRT.Routrek.SSHC.AuthenticationResult.Prompt; } } else { //throw new Exception(resLoader.GetString("ProtocolError") + resLoader.GetString("UnexpectedPacket") + h); } } while(true); }
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 Exception("service establishment failed "+t); } byte[] tmpdata = re.ReadString(); string s = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); if(servicename!=s) throw new Exception(resLoader.GetString("ProtocolError")); }
public 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()); }
public 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()); }
public void SendEOF() { if(_connection.IsClosed()) return; SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_EOF); wr.Write(_remoteID); TransmitPacket(wr.ToByteArray()); }
//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()); }
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()); }
public 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()); }
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 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; }
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 (_negotiationStatus < 1) { 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(); //await receiver.OnData(re.Image, re.Offset, len); 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: { byte[] tmpdata = re.ReadString(); string request = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool reply = re.ReadBool(); if(request=="exit-status") { int status = re.ReadInt32(); } } 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(resLoader.GetString("UnexpectedPacket")+pt); break; } } }
public void SendIgnorableData(string msg) { SSH2DataWriter w = new SSH2DataWriter(); w.WritePacketType(PacketType.SSH_MSG_IGNORE); w.Write(msg); TransmitPacket(w.ToByteArray()); }
public 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 ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH2DataReader reader) { byte[] tmpdata = reader.ReadString(); string method = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int remote_channel = reader.ReadInt32(); int window_size = reader.ReadInt32(); //skip initial window size int servermaxpacketsize = reader.ReadInt32(); tmpdata = reader.ReadString(); string host = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int port = reader.ReadInt32(); tmpdata = reader.ReadString(); string originator_ip = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); 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()); }
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(); byte[] tmpdata = reader.ReadString(); string msg = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); 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); }
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); SSH2UserAuthKey kp = SSH2UserAuthKey.FromPrivateKeyFile(_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 == GranadosRT.Routrek.SSHC.AuthenticationResult.Failure) // throw new Exception(Strings.GetString("AuthenticationFailed")); return _authenticationResult; }
public 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(); }
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 Exception(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 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(wr.ToByteArray().AsBuffer()).ToArray(); if(!VerifyHostKey(key_and_cert, signature, _hash)) return false; //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash)); if(_sessionID==null) _sessionID = _hash; return true; }
public AuthenticationResult DoKeyboardInteractiveAuth([ReadOnlyArray()] string[] input) { if(_param.AuthenticationType!=AuthenticationType.KeyboardInteractive) throw new Exception("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); byte[] ba = re.ToByteArray(); TransmitPacket(ba); _authenticationResult = ProcessAuthenticationResponse(); //try again on failure if (_authenticationResult == GranadosRT.Routrek.SSHC.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; }
public byte[] GetPublicKeyBlob() { SSH2DataWriter w = new SSH2DataWriter(); w.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm)); _keypair.PublicKey.WriteTo(w); return w.ToByteArray(); }
public 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; }
private string FormatBase64EncodedPublicKeyBody() { SSH2DataWriter wr = new SSH2DataWriter(); wr.Write(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm)); _keypair.PublicKey.WriteTo(wr); byte[] tmpdata = Base64.Encode(wr.ToByteArray()); return Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); }
public 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()); }
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 Exception(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 Exception("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 Exception("MAC Error"); } return p; }
public 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 Exception("Host key algorithm is unsupported"); throw new Exception("Host key algorithm is unsupported"); byte[] tmpdata = Base64.Encode(wr.ToByteArray()); bld.Append(Encoding.UTF8.GetString(tmpdata, 0 ,tmpdata.Length)); return bld.ToString(); }