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); }
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); } }