/**
         * opens another SSH connection via port-forwarded connection
         */
        public SSHConnection OpenPortForwardedAnotherConnection(SSHConnectionParameter param, ISSHConnectionEventReceiver receiver, string host, int port)
        {
            ChannelSocket s  = new ChannelSocket(null);
            SSHChannel    ch = ForwardPort(s, host, port, "localhost", 0);

            s.SSHChennal = ch;
            VersionExchangeHandler pnh = new VersionExchangeHandler(param, s);

            s.SetHandler(pnh);

            return(ConnectMain(param, receiver, pnh, s));
        }
        /**
         * open a new SSH connection via the .NET socket
         */
        public static SSHConnection Connect(SSHConnectionParameter param, ISSHConnectionEventReceiver receiver, Socket underlying_socket)
        {
            if (param.UserName == null)
            {
                throw new InvalidOperationException("UserName property is not set");
            }
            if (param.AuthenticationType != AuthenticationType.KeyboardInteractive && param.Password == null)
            {
                throw new InvalidOperationException("Password property is not set");
            }

            PlainSocket            s   = new PlainSocket(underlying_socket, null);
            VersionExchangeHandler pnh = new VersionExchangeHandler(param, s);

            s.SetHandler(pnh);
            s.RepeatAsyncRead();
            return(ConnectMain(param, receiver, pnh, s));
        }
        private static SSHConnection ConnectMain(SSHConnectionParameter param, ISSHConnectionEventReceiver receiver, VersionExchangeHandler pnh, AbstractGranadosSocket s)
        {
            DataFragment data = pnh.WaitResponse();
            string       sv   = pnh.ServerVersion;

            SSHConnection con = null;

            if (param.Protocol == SSHProtocol.SSH1)
            {
                con = new SSH1Connection(param, s, receiver, sv, SSHUtil.ClientVersionString(param.Protocol));
            }
            else
            {
                con = new SSH2Connection(param, s, receiver, sv, SSHUtil.ClientVersionString(param.Protocol));
            }

            con.TraceReceptionEvent("server version-string", sv.Trim());
            pnh.Close();
            s.SetHandler(con.PacketBuilder);
            con.SendMyVersion(param);

            if (con.Connect() != AuthenticationResult.Failure)
            {
                return(con);
            }
            else
            {
                s.Close();
                return(null);
            }
        }