예제 #1
0
파일: Session.cs 프로젝트: x893/SharpSSH
        public void disconnect()
        {
            if (!m_isConnected)
                return;

            Channel.disconnect(this);
            m_isConnected = false;
            PortWatcher.delPort(this);
            ChannelForwardedTCPIP.delPort(this);

            lock (m_connectThread)
            {
                m_connectThread.yield();
                m_connectThread.Interrupt();
                m_connectThread = null;
            }
            m_thread = null;
            try
            {
                if (m_io != null)
                {
                    if (m_io.m_ins != null)
                        m_io.m_ins.Close();
                    if (m_io.m_outs != null)
                        m_io.m_outs.Close();
                    if (m_io.m_outs_ext != null)
                        m_io.m_outs_ext.Close();
                }
                if (m_proxy == null)
                {
                    if (m_socket != null)
                        m_socket.Close();
                }
                else
                {
                    lock (m_proxy)
                    {
                        m_proxy.close();
                    }
                    m_proxy = null;
                }
            }
            catch { }

            m_io = null;
            m_socket = null;
            m_jsch.removeSession(this);
        }
예제 #2
0
파일: Session.cs 프로젝트: x893/SharpSSH
        public void Connect(int connectTimeout)
        {
            if (m_isConnected)
                throw new JSchException("session is already connected");

            m_io = new IO();
            if (m_random == null)
                try
                {
                    Class c = Class.ForName(getConfig("random"));
                    m_random = (Random)(c.Instance());
                }
                catch (Exception e)
                {
                    throw e;
                }

            Packet.setRandom(m_random);
            try
            {
                int i, j;
                if (m_proxy == null)
                {
                    m_proxy = m_jsch.getProxy(m_host);
                    if (m_proxy != null)
                        lock (m_proxy)
                        {
                            m_proxy.close();
                        }
                }

                if (m_proxy == null)
                {
                    Stream In;
                    Stream Out;
                    if (m_socket_factory == null)
                    {
                        m_socket = Util.createSocket(m_host, m_port, connectTimeout);
                        In = m_socket.getInputStream();
                        Out = m_socket.getOutputStream();
                    }
                    else
                    {
                        m_socket = m_socket_factory.createSocket(m_host, m_port);
                        In = m_socket_factory.getInputStream(m_socket);
                        Out = m_socket_factory.getOutputStream(m_socket);
                    }
                    //if(timeout>0){ socket.setSoTimeout(timeout); }
                    m_socket.setTcpNoDelay(true);
                    m_io.setInputStream(In);
                    m_io.setOutputStream(Out);
                }
                else
                    lock (m_proxy)
                    {
                        m_proxy.connect(m_socket_factory, m_host, m_port, connectTimeout);
                        m_io.setInputStream(m_proxy.InputStream);
                        m_io.setOutputStream(m_proxy.OutputStream);
                        m_socket = m_proxy.Socket;
                    }

                if (connectTimeout > 0 && m_socket != null)
                    m_socket.setSoTimeout(connectTimeout);

                m_isConnected = true;

                while (true)
                {

                    i = 0;
                    j = 0;
                    while (i < m_buf.m_buffer.Length)
                    {
                        j = m_io.getByte();
                        if (j < 0)
                            break;
                        m_buf.m_buffer[i] = (byte)j; i++;
                        if (j == 10)
                            break;
                    }
                    if (j < 0)
                        throw new JSchException("connection is closed by foreign host");

                    if (m_buf.m_buffer[i - 1] == '\n')
                    {
                        i--;
                        if (m_buf.m_buffer[i - 1] == '\r')
                            i--;
                    }

                    if (i > 4
                    && (i != m_buf.m_buffer.Length)
                    && (m_buf.m_buffer[0] != 'S' || m_buf.m_buffer[1] != 'S' || m_buf.m_buffer[2] != 'H' || m_buf.m_buffer[3] != '-')
                        )
                        continue;

                    if (i == m_buf.m_buffer.Length
                    || i < 7    // SSH-1.99 or SSH-2.0
                    || (m_buf.m_buffer[4] == '1' && m_buf.m_buffer[6] != '9')  // SSH-1.5
                        )
                        throw new JSchException("invalid server's version String");
                    break;
                }

                m_server_version = new byte[i];
                Array.Copy(m_buf.m_buffer, 0, m_server_version, 0, i);
                {
                    // Some Cisco devices will miss to read '\n' if it is sent separately.
                    byte[] foo = new byte[m_client_version.Length + 1];
                    Array.Copy(m_client_version, 0, foo, 0, m_client_version.Length);
                    foo[foo.Length - 1] = (byte)'\n';
                    m_io.put(foo, 0, foo.Length);
                }

                m_buf = read(m_buf);
                if (m_buf.m_buffer[5] != SSH_MSG_KEXINIT)
                    throw new JSchException("invalid protocol: " + m_buf.m_buffer[5]);

                KeyExchange kex = receive_kexinit(m_buf);

                while (true)
                {
                    m_buf = read(m_buf);
                    if (kex.getState() == m_buf.m_buffer[5])
                    {
                        bool result = kex.next(m_buf);
                        if (!result)
                        {
                            m_in_kex = false;
                            throw new JSchException("verify: " + result);
                        }
                    }
                    else
                    {
                        m_in_kex = false;
                        throw new JSchException("invalid protocol(kex): " + m_buf.m_buffer[5]);
                    }
                    if (kex.getState() == KeyExchange.STATE_END)
                        break;
                }

                try
                {
                    checkHost(m_host, kex);
                }
                catch (JSchException ee)
                {
                    m_in_kex = false;
                    throw ee;
                }

                send_newkeys();

                // receive SSH_MSG_NEWKEYS(21)
                m_buf = read(m_buf);
                if (m_buf.m_buffer[5] == SSH_MSG_NEWKEYS)
                    receive_newkeys(m_buf, kex);
                else
                {
                    m_in_kex = false;
                    throw new JSchException("invalid protocol(newkyes): " + m_buf.m_buffer[5]);
                }

                bool auth = false;
                bool auth_cancel = false;

                UserAuthNone usn = new UserAuthNone(m_userinfo);
                auth = usn.start(this);

                string methods = null;
                if (!auth)
                {
                    methods = usn.getMethods();
                    if (methods != null)
                        methods = methods.ToLowerInvariant();
                    else
                        methods = "publickey,password,keyboard-interactive";
                }

                while (true)
                {
                    while (!auth && methods != null && methods.Length > 0)
                    {
                        UserAuth us = null;
                        if (methods.StartsWith("publickey"))
                        {
                            lock (m_jsch.Identities)
                            {
                                if (m_jsch.Identities.Count > 0)
                                    us = new UserAuthPublicKey(m_userinfo);
                            }
                        }
                        else if (methods.StartsWith("keyboard-interactive"))
                        {
                            if (m_userinfo is UIKeyboardInteractive)
                                us = new UserAuthKeyboardInteractive(m_userinfo);
                        }
                        else if (methods.StartsWith("password"))
                            us = new UserAuthPassword(m_userinfo);

                        if (us != null)
                        {
                            try
                            {
                                auth = us.start(this);
                                auth_cancel = false;
                            }
                            catch (JSchAuthCancelException)
                            {
                                auth_cancel = true;
                            }
                            catch (JSchPartialAuthException ex)
                            {
                                methods = ex.getMethods();
                                auth_cancel = false;
                                continue;
                            }
                            catch (RuntimeException ee)
                            {
                                throw ee;
                            }
                            catch (Exception ee)
                            {
                                Console.WriteLine("ee: " + ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures
                            }
                        }

                        if (!auth)
                        {
                            int comma = methods.IndexOf(",");
                            if (comma == -1)
                                break;
                            methods = methods.Substring(comma + 1);
                        }
                    }
                    break;
                }

                if (connectTimeout > 0 || m_timeout > 0)
                    m_socket.setSoTimeout(m_timeout);

                if (auth)
                {
                    m_isAuthed = true;
                    m_connectThread = new Thread(this);
                    m_connectThread.Name = "Connect thread " + m_host + " session";
                    m_connectThread.Start();
                    return;
                }
                if (auth_cancel)
                    throw new JSchException("Auth cancel");
                throw new JSchException("Auth fail");
            }
            catch (Exception e)
            {
                m_in_kex = false;
                if (m_isConnected)
                {
                    try
                    {
                        m_packet.reset();
                        m_buf.putByte((byte)SSH_MSG_DISCONNECT);
                        m_buf.putInt(3);
                        m_buf.putString(e.ToString());
                        m_buf.putString("en");
                        write(m_packet);
                        disconnect();
                    }
                    catch (Exception)
                    { }
                }
                m_isConnected = false;

                if (e is RuntimeException)
                    throw (RuntimeException)e;
                if (e is JSchException)
                    throw (JSchException)e;
                throw new JSchException("Session.connect: " + e);
            }
        }