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); } }
/// <summary> /// constructs from file /// </summary> /// <param name="path">file name</param> /// <param name="passphrase">passphrase or empty string if passphrase is not required</param> public SSH1UserAuthKey(string path, string passphrase) { Stream s = File.Open(path, FileMode.Open); byte[] header = new byte[32]; s.Read(header, 0, header.Length); if (Encoding.ASCII.GetString(header) != "SSH PRIVATE KEY FILE FORMAT 1.1\n") { throw new SSHException(String.Format(Strings.GetString("BrokenKeyFile"), path)); } SSH1DataReader reader = new SSH1DataReader(ReadAll(s)); s.Close(); byte[] cipher = reader.Read(2); //first 2 bytes indicates algorithm and next 8 bytes is space reader.Read(8); _modulus = reader.ReadMPInt(); _publicExponent = reader.ReadMPInt(); byte[] comment = reader.ReadString(); byte[] prvt = reader.ReadAll(); //必要なら復号 CipherAlgorithm algo = (CipherAlgorithm)cipher[1]; if (algo != 0) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH1, algo, ConvertToKey(passphrase)); byte[] buf = new byte[prvt.Length]; c.Decrypt(prvt, 0, prvt.Length, buf, 0); prvt = buf; } SSH1DataReader prvtreader = new SSH1DataReader(prvt); byte[] mark = prvtreader.Read(4); if (mark[0] != mark[2] || mark[1] != mark[3]) { throw new SSHException(Strings.GetString("WrongPassphrase")); } _privateExponent = prvtreader.ReadMPInt(); _crtCoefficient = prvtreader.ReadMPInt(); _primeP = prvtreader.ReadMPInt(); _primeQ = prvtreader.ReadMPInt(); }
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); } } }
//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では頭が0かどうかで変なハンドリングがあった 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); } }
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); } } }
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); } }