* @param password for connecting
* @throws JSchException if any errors occur
*/
public void connect(int connectTimeout, byte[] password) throws JSchException {
if( _connected ) {
throw new JSchException("Session is already connected");
}
JSch.getLogger().log(Logger.Level.INFO, "Connecting to " + _host + " port " + _port);
try {
/* Create the socket to the remote host and set the input/output
* streams. If a proxy instance is set, use the proxy for creating
* the socket. If socket factory is set, use factory for creating
* socket, otherwise use default socket factory.
*/
_io = new IO(); // Create new IO instance for current connection
if( _proxy == null ) {
_socket = _socketFactory.createSocket(_host, _port, connectTimeout);
_io.setInputStream(_socketFactory.getInputStream(_socket));
_io.setOutputStream(_socketFactory.getOutputStream(_socket));
_socket.setTcpNoDelay(true);
} else {
synchronized( _proxyLock ) {
_proxy.connect(_socketFactory, _host, _port, connectTimeout);
_socket = _proxy.getSocket();
_io.setInputStream(_proxy.getInputStream());
_io.setOutputStream(_proxy.getOutputStream());
}
}
// Set the socket timeout for reads if timeout is greater than zero
if( connectTimeout > 0 && _socket != null ) {
_socket.setSoTimeout(connectTimeout);
}
_connected = true; // Set connected as true (socket is connected)
_sessionIO = SessionIO.createIO(this, _io.in, _io._out);
JSch.getLogger().log(Logger.Level.INFO, "Connection established");
// Exchange version information (send client version, read server version)
_versionExchange.exchangeVersions(_io.in, _io._out);
JSch.getLogger().log(Logger.Level.INFO, "Server SSH version: " + getServerVersion());
JSch.getLogger().log(Logger.Level.INFO, "Client SSH version: " + getClientVersion());
// Create key exchange and start kex process
_keyExchange = new KeyExchange(this);
_sessionId = _keyExchange.runFirstKex();
_sessionIO.initNewKeys(_keyExchange);
// Perform user authentication
if( !UserAuth.authenticateUser(this, password) ) {
throw new JSchException("User was not authenticated");
}
_authenticated = true;
// Updates the socket timeout to the session timeout, replacing any
// local timeout set in the connect(timeout) method
if( (connectTimeout > 0 || _timeout > 0) && _timeout != connectTimeout ) {
_socket.setSoTimeout(_timeout);
}
synchronized( _writeLock ) {
if( _connected ) {
_connectThread = _threadFactory.newThread(this);
_connectThread.setName("Connect thread " + _host + " session");
_connectThread.setDaemon(_daemonThread);
_connectThread.start();
}
}
} catch(Exception e) {
if( _keyExchange != null ) {
_keyExchange.kexCompleted();
}
if( _connected ) {
try {
// Make best effort to notify server we are disconnecting
Buffer buffer = new Buffer(500);
Packet packet = new Packet(buffer);
packet.reset();
buffer.putByte(SSH_MSG_DISCONNECT);
buffer.putInt(SSH_DISCONNECT_KEY_EXCHANGE_FAILED); // TODO Value should be dynamic
buffer.putString(e.toString());
buffer.putString("en");
write(packet);
} catch(Exception ee) {
/* Ignore close error. */
} finally {
disconnect(); // Ensure disconnect in finally!
}
}
_connected = false;
if( e instanceof JSchException ) {
throw (JSchException) e;
}
throw new JSchException("Failed to connect session: " + e, e);
} finally {
Util.bzero(password);
}
}