/// <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) { #if PODEROSA_KEYFORMAT PrivateKeyLoader loader = new PrivateKeyLoader(path); loader.LoadSSH1PrivateKey( passphrase, out _modulus, out _publicExponent, out _privateExponent, out _primeP, out _primeQ, out _crtCoefficient, out _comment); #else 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(); _comment = reader.ReadString(); byte[] prvt = reader.GetRemainingDataView().GetBytes(); //必要なら復号 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(); #endif }
/// <summary> /// Read SSH1 private key parameters. /// </summary> /// <param name="passphrase">passphrase for decrypt the key file</param> /// <param name="modulus">private key parameter</param> /// <param name="publicExponent">private key parameter</param> /// <param name="privateExponent">private key parameter</param> /// <param name="primeP">private key parameter</param> /// <param name="primeQ">private key parameter</param> /// <param name="crtCoefficient">private key parameter</param> /// <exception cref="SSHException">failed to parse</exception> public void Load( string passphrase, out BigInteger modulus, out BigInteger publicExponent, out BigInteger privateExponent, out BigInteger primeP, out BigInteger primeQ, out BigInteger crtCoefficient) { if (keyFile == null) throw new SSHException("A key file is not loaded yet"); byte[] hdr = Encoding.ASCII.GetBytes(PrivateKeyFileHeader.SSH1_HEADER); if (!ByteArrayUtil.ByteArrayStartsWith(keyFile, hdr)) throw new SSHException(Strings.GetString("NotValidPrivateKeyFile")); SSH1DataReader reader = new SSH1DataReader(keyFile); reader.Read(hdr.Length); 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, SSH1PassphraseToKey(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 void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1DataReader reader) { int server_channel = reader.ReadInt32(); string host = reader.ReadString(); int port = reader.ReadInt32(); PortForwardingCheckResult result = receiver.CheckPortForwardingRequest(host, port, "", 0); if (result.allowed) { int local_id = _channel_collection.RegisterChannelEventReceiver(null, result.channel).LocalID; _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel)); Transmit( new SSH1Packet(SSH1PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) .WriteInt32(server_channel) .WriteInt32(local_id) ); } else { Transmit( new SSH1Packet(SSH1PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE) .WriteInt32(server_channel) ); } }
private DataFragment ReceivePacket() { while (true) { DataFragment data = _packetReceiver.WaitResponse(); PacketType pt = (PacketType)data.ByteAt(0); //shortcut if (pt == PacketType.SSH_MSG_IGNORE) { SSH1DataReader r = new SSH1DataReader(data); r.ReadPacketType(); if (_eventReceiver != null) _eventReceiver.OnIgnoreMessage(r.ReadString()); } else if (pt == PacketType.SSH_MSG_DEBUG) { SSH1DataReader r = new SSH1DataReader(data); r.ReadPacketType(); if (_eventReceiver != null) _eventReceiver.OnDebugMessage(false, r.ReadString()); } else return data; } }
private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH1DataReader reader) { 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 = _channel_collection.RegisterChannelEventReceiver(null, result.channel).LocalID; _eventReceiver.EstablishPortforwarding(result.channel, new SSH1Channel(this, ChannelType.ForwardedRemoteToLocal, local_id, server_channel)); writer.WriteInt32(server_channel); writer.WriteInt32(local_id); SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION, writer.ToByteArray()); p.WriteTo(_stream, _tCipher); } else { writer.WriteInt32(server_channel); SSH1Packet p = SSH1Packet.FromPlainPayload(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE, writer.ToByteArray()); p.WriteTo(_stream, _tCipher); } }
internal void AsyncReceivePacket(DataFragment data) { try { int len = 0, channel = 0; SSH1DataReader re = new SSH1DataReader(data); PacketType pt = re.ReadPacketType(); switch (pt) { case PacketType.SSH_SMSG_STDOUT_DATA: len = re.ReadInt32(); _channel_collection.FindChannelEntry(_shellID).Receiver.OnData(re.Image, re.Offset, len); break; case PacketType.SSH_SMSG_STDERR_DATA: { _channel_collection.FindChannelEntry(_shellID).Receiver.OnExtendedData((int)PacketType.SSH_SMSG_STDERR_DATA, re.ReadString()); } break; case PacketType.SSH_MSG_CHANNEL_DATA: channel = re.ReadInt32(); len = re.ReadInt32(); _channel_collection.FindChannelEntry(channel).Receiver.OnData(re.Image, re.Offset, len); break; case PacketType.SSH_MSG_PORT_OPEN: ProcessPortforwardingRequest(_eventReceiver, re); break; case PacketType.SSH_MSG_CHANNEL_CLOSE: { channel = re.ReadInt32(); ISSHChannelEventReceiver r = _channel_collection.FindChannelEntry(channel).Receiver; _channel_collection.UnregisterChannelEventReceiver(channel); r.OnChannelClosed(); } break; case PacketType.SSH_MSG_CHANNEL_CLOSE_CONFIRMATION: channel = re.ReadInt32(); break; case PacketType.SSH_MSG_DISCONNECT: _eventReceiver.OnConnectionClosed(); break; case PacketType.SSH_SMSG_EXITSTATUS: _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelClosed(); break; case PacketType.SSH_MSG_DEBUG: _eventReceiver.OnDebugMessage(false, re.ReadString()); break; case PacketType.SSH_MSG_IGNORE: _eventReceiver.OnIgnoreMessage(re.ReadString()); break; case PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION: { int local = re.ReadInt32(); int remote = re.ReadInt32(); _channel_collection.FindChannelEntry(local).Receiver.OnChannelReady(); } break; case PacketType.SSH_SMSG_SUCCESS: if (_executingShell) { ExecShell(); _channel_collection.FindChannelEntry(_shellID).Receiver.OnChannelReady(); _executingShell = false; } break; default: _eventReceiver.OnUnknownMessage((byte)pt, re.ReadAll()); break; } } catch (Exception ex) { _eventReceiver.OnError(ex); } }