def connect(self, hostname, username=None, password=None, sock=None): """ This only creates the Transport object and use start_client() to begin a client session. """ port = self._ssh_port timeout = self._conn_timeout if not sock: for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) t = self._transport = Transport(sock) self._sock = sock ResourceManager.register(self, t)
def an_open_socket_can_be_used_for_ssh_connection_with_sock_argument(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) retry_on_signal(lambda: sock.connect((HOSTNAME, PORT))) with _create_shell_with_wrong_port(sock=sock) as shell: result = shell.run(["echo", "hello"]) assert_equal(b"hello\n", result.output)
def connect(self): """ Get a handle to a remote connection """ # Check URL schema = urlparse(self.url) if schema.scheme == 'sftp': hostname = schema.hostname port = int(schema.port) # Socket creation code inspired from paramiko.Transport.__init__ # with added bind support. for family, socktype, _, _, _ in getaddrinfo( hostname, port, AF_UNSPEC, SOCK_STREAM, ): if socktype == SOCK_STREAM: sock = socket(family, SOCK_STREAM) if self.bind_address: # XXX: Expects bind address to be of same family as hostname. # May not be easy if name resolution is involved. # Try to reconciliate them ? sock.bind((self.bind_address, 0)) retry_on_signal(lambda: sock.connect((hostname, port))) break else: raise SFTPError('No suitable socket family found') self.transport = Transport(sock) else: raise SFTPError('Not a valid sftp url %s, type is %s' % (self.url, schema.scheme)) # Add authentication to transport try: if self.password: self.transport.connect(username=self.user_name, password=self.password) elif self.private_key: self.transport.connect(username=self.user_name, pkey=RSAKey.from_private_key( StringIO(self.private_key))) else: raise SFTPError("No password or private_key defined") # Connect self.conn = SFTPClient.from_transport(self.transport) except (gaierror, error), msg: raise SFTPError( str(msg) + ' while establishing connection to %s' % (self.url, ))
def connect(self): """ Method automatically called by ``AgentProxyThread.run``. """ if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'): conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: retry_on_signal(lambda: conn.connect(os.environ['SSH_AUTH_SOCK'])) except: # probably a dangling env var: the ssh agent is gone return elif sys.platform == 'win32': import paramiko.win_pageant as win_pageant if win_pageant.can_talk_to_agent(): conn = win_pageant.PageantConnection() else: return else: # no agent support return self._conn = conn
def connect(self): """ Method automatically called by the run() method of the AgentProxyThread """ if ('SSH_AUTH_SOCK' in os.environ) and (sys.platform != 'win32'): conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: retry_on_signal( lambda: conn.connect(os.environ['SSH_AUTH_SOCK'])) except: # probably a dangling env var: the ssh agent is gone return elif sys.platform == 'win32': if win_pageant.can_talk_to_agent(): conn = win_pageant.PageantConnection() else: return else: # no agent support return self._conn = conn
def connect(self): """ Get a handle to a remote connection """ # Check URL schema = urlparse(self.url) if schema.scheme == 'sftp': hostname = schema.hostname port = int(schema.port) # Socket creation code inspired from paramiko.Transport.__init__ # with added bind support. for family, socktype, _, _, _ in getaddrinfo( hostname, port, AF_UNSPEC, SOCK_STREAM, ): if socktype == SOCK_STREAM: sock = socket(family, SOCK_STREAM) if self.bind_address: # XXX: Expects bind address to be of same family as hostname. # May not be easy if name resolution is involved. # Try to reconciliate them ? sock.bind((self.bind_address, 0)) retry_on_signal(lambda: sock.connect((hostname, port))) break else: raise SFTPError('No suitable socket family found') self.transport = Transport(sock) else: raise SFTPError('Not a valid sftp url %s, type is %s' %(self.url, schema.scheme)) # Add authentication to transport try: if self.password: self.transport.connect(username=self.user_name, password=self.password) elif self.private_key: self.transport.connect(username=self.user_name, pkey=RSAKey.from_private_key(StringIO(self.private_key))) else: raise SFTPError("No password or private_key defined") # Connect self.conn = SFTPClient.from_transport(self.transport) except (gaierror, error), msg: raise SFTPError(str(msg) + ' while establishing connection to %s' % (self.url,))
def _ssh_socket(self, interface=None): """ Returns a socket object for the ssh connection to the node. It is necessary for forcing paramiko to use a specific interface rather than just an ip address for binding the socket. """ for (family, stype, _, _, sockaddr) in socket.getaddrinfo( self.ip, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM): if stype == socket.SOCK_STREAM: af = family addr = sockaddr break else: af, _, _, _, addr = socket.getaddrinfo( self.ip, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM) sock = socket.socket(af, socket.SOCK_STREAM) if interface is not None: sock.setsockopt(socket.SOL_SOCKET, 25, interface + '\0') sock.settimeout(SOCKET_TIMEOUT) retry_on_signal(lambda: sock.connect(addr)) return sock
def connect(self): """ Method automatically called by ``AgentProxyThread.run``. """ if ("SSH_AUTH_SOCK" in os.environ) and (sys.platform != "win32"): conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: retry_on_signal( lambda: conn.connect(os.environ["SSH_AUTH_SOCK"])) except: # probably a dangling env var: the ssh agent is gone return elif sys.platform == "win32": import paramiko.win_pageant as win_pageant if win_pageant.can_talk_to_agent(): conn = win_pageant.PageantConnection() else: return else: # no agent support return self._conn = conn
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :raises BadHostKeyException: if the server's host key could not be verified :raises AuthenticationException: if authentication failed :raises SSHException: if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. """ if not sock: for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) elif gss_kex and gss_host is not None: t.set_gss_host(gss_host) else: pass if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout t.start_client() ResourceManager.register(self, t) server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.use_gss_kex: our_server_key = self._system_host_keys.get( server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename if gss_host is None: gss_host = hostname self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see L{load_system_host_keys}) and any local host keys (L{load_host_keys}). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see L{set_missing_host_key_policy}). The default policy is to reject the key and raise an L{SSHException}. Authentication is attempted in the following order of priority: - The C{pkey} or C{key_filename} passed in (if any) - Any key we can find through an SSH agent - Any "id_rsa" or "id_dsa" key discoverable in C{~/.ssh/} - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. @param hostname: the server to connect to @type hostname: str @param port: the server port to connect to @type port: int @param username: the username to authenticate as (defaults to the current local username) @type username: str @param password: a password to use for authentication or for unlocking a private key @type password: str @param pkey: an optional private key to use for authentication @type pkey: L{PKey} @param key_filename: the filename, or list of filenames, of optional private key(s) to try for authentication @type key_filename: str or list(str) @param timeout: an optional timeout (in seconds) for the TCP connect @type timeout: float @param allow_agent: set to False to disable connecting to the SSH agent @type allow_agent: bool @param look_for_keys: set to False to disable searching for discoverable private key files in C{~/.ssh/} @type look_for_keys: bool @param compress: set to True to turn on compression @type compress: bool @param sock: an open socket or socket-like object (such as a L{Channel}) to use for communication to the target host @type sock: socket @raise BadHostKeyException: if the server's host key could not be verified @raise AuthenticationException: if authentication failed @raise SSHException: if there was any other error connecting or establishing an SSH session @raise socket.error: if a socket error occurred while connecting """ if not sock: for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) t = self._transport = Transport(sock) t.use_compression(compress=compress) if self._log_channel is not None: t.set_log_channel(self._log_channel) t.start_client() ResourceManager.register(self, t) server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [ key_filename ] else: key_filenames = key_filename self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, progress_bar_callback=None): if not sock: progress_bar_callback(1) # Resolving DNS for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) progress_bar_callback(2) # Creating socket sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) progress_bar_callback(3) # Creating transport t = self._transport = Transport(sock) t.use_compression(compress=compress) if self._log_channel is not None: t.set_log_channel(self._log_channel) t.start_client() ResourceManager.register(self, t) progress_bar_callback(4) # Exchange keys server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, (str, unicode)): key_filenames = [ key_filename ] else: key_filenames = key_filename progress_bar_callback(5) # Authenticate self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
def connect( self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, check_key=False ): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :param bool check_key: set to True to perform server-based pubkey checking. This option mimics openssh behavior and could fix auth issues for some SSH server implementations. :raises BadHostKeyException: if the server's host key could not be verified :raises AuthenticationException: if authentication failed :raises SSHException: if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. """ if not sock: errors = {} # Try multiple possible address families (e.g. IPv4 vs IPv6) to_try = list(self._families_and_addresses(hostname, port)) for af, addr in to_try: try: sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) # Break out of the loop on success break except socket.error as e: # Raise anything that isn't a straight up connection error # (such as a resolution error) if e.errno not in (ECONNREFUSED, EHOSTUNREACH): raise # Capture anything else so we know how the run looks once # iteration is complete. Retain info about which attempt # this was. errors[addr] = e # Make sure we explode usefully if no address family attempts # succeeded. We've no way of knowing which error is the "right" # one, so we construct a hybrid exception containing all the real # ones, of a subclass that client code should still be watching for # (socket.error) if len(errors) == len(to_try): raise NoValidConnectionsError(errors) t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) elif gss_kex and gss_host is not None: t.set_gss_host(gss_host) else: pass if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout t.start_client() ResourceManager.register(self, t) server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.use_gss_kex: our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename if gss_host is None: gss_host = hostname self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host, check_key)
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, progress_bar_callback=None): """ Patched ``paramiko.client.SSHClient.connect``. This adds callbacks for the connection progress bar. """ if not sock: progress_bar_callback(1) # Resolving DNS for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) progress_bar_callback(2) # Creating socket sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) progress_bar_callback(3) # Creating transport t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) elif gss_kex and gss_host is not None: t.set_gss_host(gss_host) else: pass if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout t.start_client() ResourceManager.register(self, t) progress_bar_callback(4) # Exchange keys server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.use_gss_kex: our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename if gss_host is None: gss_host = hostname progress_bar_callback(5) # Authenticate self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
def connect( self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, ): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - ``key_filename`` may contain OpenSSH public certificate paths as well as regular private-key paths; when files ending in ``-cert.pub`` are found, they are assumed to match a private key, and both components will be loaded. (The private key itself does *not* need to be listed in ``key_filename`` for this to occur - *just* the certificate.) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - When OpenSSH-style public certificates exist that match an existing such private key (so e.g. one has ``id_rsa`` and ``id_rsa-cert.pub``) the certificate will be loaded alongside the private key and used for authentication. - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) and/or certs to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param bool gss_trust_dns: Indicates whether or not the DNS is trusted to securely canonicalize the name of the host being connected to (default ``True``). :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :param float auth_timeout: an optional timeout (in seconds) to wait for an authentication response. :raises: `.BadHostKeyException` -- if the server's host key could not be verified :raises: `.AuthenticationException` -- if authentication failed :raises: `.SSHException` -- if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. .. versionchanged:: 2.3 Added the ``gss_trust_dns`` argument. """ if not sock: errors = {} # Try multiple possible address families (e.g. IPv4 vs IPv6) to_try = list(self._families_and_addresses(hostname, port)) for af, addr in to_try: try: sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) # Break out of the loop on success break except socket.error as e: # Raise anything that isn't a straight up connection error # (such as a resolution error) if e.errno not in (ECONNREFUSED, EHOSTUNREACH): raise # Capture anything else so we know how the run looks once # iteration is complete. Retain info about which attempt # this was. errors[addr] = e # Make sure we explode usefully if no address family attempts # succeeded. We've no way of knowing which error is the "right" # one, so we construct a hybrid exception containing all the real # ones, of a subclass that client code should still be watching for # (socket.error) if len(errors) == len(to_try): raise NoValidConnectionsError(errors) t = self._transport = Transport( sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds ) t.use_compression(compress=compress) t.set_gss_host( kex_requested=gss_kex, gss_host=gss_host, trust_dns=gss_trust_dns, ) if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout if auth_timeout is not None: t.auth_timeout = auth_timeout if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) our_server_keys = None our_server_keys = self._system_host_keys.get(server_hostkey_name) if our_server_keys is None: our_server_keys = self._host_keys.get(server_hostkey_name) if our_server_keys is not None: keytype = our_server_keys.keys()[0] sec_opts = t.get_security_options() other_types = [x for x in sec_opts.key_types if x != keytype] sec_opts.key_types = [keytype] + other_types t.start_client(timeout=timeout) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.gss_kex_used: server_key = t.get_remote_server_key() if our_server_keys is None: # will raise exception if the key is rejected self._policy.missing_host_key( self, server_hostkey_name, server_key ) else: our_key = our_server_keys.get(server_key.get_name()) if our_key != server_key: if our_key is None: our_key = list(our_server_keys.values())[0] raise BadHostKeyException(hostname, server_key, our_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename self._auth( username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, t.gss_host, )
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :raises BadHostKeyException: if the server's host key could not be verified :raises AuthenticationException: if authentication failed :raises SSHException: if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. """ if not sock: for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM): if socktype == socket.SOCK_STREAM: af = family addr = sockaddr break else: # some OS like AIX don't indicate SOCK_STREAM support, so just guess. :( af, _, _, _, addr = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM) sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) t = self._transport = Transport(sock, gss_kex, gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) elif gss_kex and gss_host is not None: t.set_gss_host(gss_host) else: pass if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout t.start_client() ResourceManager.register(self, t) server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.use_gss_kex: our_server_key = self._system_host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename if gss_host is None: gss_host = hostname self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host)
def connect( self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, passphrase=None, ): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - ``key_filename`` may contain OpenSSH public certificate paths as well as regular private-key paths; when files ending in ``-cert.pub`` are found, they are assumed to match a private key, and both components will be loaded. (The private key itself does *not* need to be listed in ``key_filename`` for this to occur - *just* the certificate.) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa", "id_ecdsa", or "id_ed25519" key discoverable in ``~/.ssh/`` - When OpenSSH-style public certificates exist that match an existing such private key (so e.g. one has ``id_rsa`` and ``id_rsa-cert.pub``) the certificate will be loaded alongside the private key and used for authentication. - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: Used for password authentication; is also used for private key decryption if ``passphrase`` is not given. :param str passphrase: Used for decrypting private keys. :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) and/or certs to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param bool gss_trust_dns: Indicates whether or not the DNS is trusted to securely canonicalize the name of the host being connected to (default ``True``). :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :param float auth_timeout: an optional timeout (in seconds) to wait for an authentication response. :raises: `.BadHostKeyException` -- if the server's host key could not be verified :raises: `.AuthenticationException` -- if authentication failed :raises: `.SSHException` -- if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. .. versionchanged:: 2.3 Added the ``gss_trust_dns`` argument. .. versionchanged:: 2.4 Added the ``passphrase`` argument. """ if not sock: sock = retry_on_signal(lambda: socket.create_connection( (hostname, port), timeout)) t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) t.set_gss_host( # t.hostname may be None, but GSS-API requires a target name. # Therefore use hostname as fallback. gss_host=gss_host or hostname, trust_dns=gss_trust_dns, gssapi_requested=gss_auth or gss_kex, ) if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout if auth_timeout is not None: t.auth_timeout = auth_timeout if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[{}]:{}".format(hostname, port) our_server_keys = None our_server_keys = self._system_host_keys.get(server_hostkey_name) if our_server_keys is None: our_server_keys = self._host_keys.get(server_hostkey_name) if our_server_keys is not None: keytype = our_server_keys.keys()[0] sec_opts = t.get_security_options() other_types = [x for x in sec_opts.key_types if x != keytype] sec_opts.key_types = [keytype] + other_types t.start_client(timeout=timeout) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.gss_kex_used: server_key = t.get_remote_server_key() if our_server_keys is None: # will raise exception if the key is rejected self._policy.missing_host_key(self, server_hostkey_name, server_key) else: our_key = our_server_keys.get(server_key.get_name()) if our_key != server_key: if our_key is None: our_key = list(our_server_keys.values())[0] raise BadHostKeyException(hostname, server_key, our_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename self._auth( username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, t.gss_host, passphrase, )
def connect( self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, auth_timeout=None, gss_trust_dns=True, ): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - ``key_filename`` may contain OpenSSH public certificate paths as well as regular private-key paths; when files ending in ``-cert.pub`` are found, they are assumed to match a private key, and both components will be loaded. (The private key itself does *not* need to be listed in ``key_filename`` for this to occur - *just* the certificate.) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - When OpenSSH-style public certificates exist that match an existing such private key (so e.g. one has ``id_rsa`` and ``id_rsa-cert.pub``) the certificate will be loaded alongside the private key and used for authentication. - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) and/or certs to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param bool gss_trust_dns: Indicates whether or not the DNS is trusted to securely canonicalize the name of the host being connected to (default ``True``). :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :param float auth_timeout: an optional timeout (in seconds) to wait for an authentication response. :raises: `.BadHostKeyException` -- if the server's host key could not be verified :raises: `.AuthenticationException` -- if authentication failed :raises: `.SSHException` -- if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. .. versionchanged:: 2.3 Added the ``gss_trust_dns`` argument. """ if not sock: errors = {} # Try multiple possible address families (e.g. IPv4 vs IPv6) to_try = list(self._families_and_addresses(hostname, port)) for af, addr in to_try: try: sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) # Break out of the loop on success break except socket.error as e: # Raise anything that isn't a straight up connection error # (such as a resolution error) if e.errno not in (ECONNREFUSED, EHOSTUNREACH): raise # Capture anything else so we know how the run looks once # iteration is complete. Retain info about which attempt # this was. errors[addr] = e # Make sure we explode usefully if no address family attempts # succeeded. We've no way of knowing which error is the "right" # one, so we construct a hybrid exception containing all the real # ones, of a subclass that client code should still be watching for # (socket.error) if len(errors) == len(to_try): raise NoValidConnectionsError(errors) t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) t.set_gss_host( # t.hostname may be None, but GSS-API requires a target name. # Therefore use hostname as fallback. gss_host=gss_host or hostname, trust_dns=gss_trust_dns, gssapi_requested=gss_auth or gss_kex, ) if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout if auth_timeout is not None: t.auth_timeout = auth_timeout if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) our_server_keys = None our_server_keys = self._system_host_keys.get(server_hostkey_name) if our_server_keys is None: our_server_keys = self._host_keys.get(server_hostkey_name) if our_server_keys is not None: keytype = our_server_keys.keys()[0] sec_opts = t.get_security_options() other_types = [x for x in sec_opts.key_types if x != keytype] sec_opts.key_types = [keytype] + other_types t.start_client(timeout=timeout) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.gss_kex_used: server_key = t.get_remote_server_key() if our_server_keys is None: # will raise exception if the key is rejected self._policy.missing_host_key(self, server_hostkey_name, server_key) else: our_key = our_server_keys.get(server_key.get_name()) if our_key != server_key: if our_key is None: our_key = list(our_server_keys.values())[0] raise BadHostKeyException(hostname, server_key, our_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename self._auth( username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, t.gss_host, )
def connect(self, hostname, port=SSH_PORT, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None, check_key=False): """ Connect to an SSH server and authenticate to it. The server's host key is checked against the system host keys (see `load_system_host_keys`) and any local host keys (`load_host_keys`). If the server's hostname is not found in either set of host keys, the missing host key policy is used (see `set_missing_host_key_policy`). The default policy is to reject the key and raise an `.SSHException`. Authentication is attempted in the following order of priority: - The ``pkey`` or ``key_filename`` passed in (if any) - Any key we can find through an SSH agent - Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ``~/.ssh/`` - Plain username/password auth, if a password was given If a private key requires a password to unlock it, and a password is passed in, that password will be used to attempt to unlock the key. :param str hostname: the server to connect to :param int port: the server port to connect to :param str username: the username to authenticate as (defaults to the current local username) :param str password: a password to use for authentication or for unlocking a private key :param .PKey pkey: an optional private key to use for authentication :param str key_filename: the filename, or list of filenames, of optional private key(s) to try for authentication :param float timeout: an optional timeout (in seconds) for the TCP connect :param bool allow_agent: set to False to disable connecting to the SSH agent :param bool look_for_keys: set to False to disable searching for discoverable private key files in ``~/.ssh/`` :param bool compress: set to True to turn on compression :param socket sock: an open socket or socket-like object (such as a `.Channel`) to use for communication to the target host :param bool gss_auth: ``True`` if you want to use GSS-API authentication :param bool gss_kex: Perform GSS-API Key Exchange and user authentication :param bool gss_deleg_creds: Delegate GSS-API client credentials or not :param str gss_host: The targets name in the kerberos database. default: hostname :param float banner_timeout: an optional timeout (in seconds) to wait for the SSH banner to be presented. :param bool check_key: set to True to perform server-based pubkey checking. This option mimics openssh behavior and could fix auth issues for some SSH server implementations. :raises BadHostKeyException: if the server's host key could not be verified :raises AuthenticationException: if authentication failed :raises SSHException: if there was any other error connecting or establishing an SSH session :raises socket.error: if a socket error occurred while connecting .. versionchanged:: 1.15 Added the ``banner_timeout``, ``gss_auth``, ``gss_kex``, ``gss_deleg_creds`` and ``gss_host`` arguments. """ if not sock: errors = {} # Try multiple possible address families (e.g. IPv4 vs IPv6) to_try = list(self._families_and_addresses(hostname, port)) for af, addr in to_try: try: sock = socket.socket(af, socket.SOCK_STREAM) if timeout is not None: try: sock.settimeout(timeout) except: pass retry_on_signal(lambda: sock.connect(addr)) # Break out of the loop on success break except socket.error as e: # Raise anything that isn't a straight up connection error # (such as a resolution error) if e.errno not in (ECONNREFUSED, EHOSTUNREACH): raise # Capture anything else so we know how the run looks once # iteration is complete. Retain info about which attempt # this was. errors[addr] = e # Make sure we explode usefully if no address family attempts # succeeded. We've no way of knowing which error is the "right" # one, so we construct a hybrid exception containing all the real # ones, of a subclass that client code should still be watching for # (socket.error) if len(errors) == len(to_try): raise NoValidConnectionsError(errors) t = self._transport = Transport(sock, gss_kex=gss_kex, gss_deleg_creds=gss_deleg_creds) t.use_compression(compress=compress) if gss_kex and gss_host is None: t.set_gss_host(hostname) elif gss_kex and gss_host is not None: t.set_gss_host(gss_host) else: pass if self._log_channel is not None: t.set_log_channel(self._log_channel) if banner_timeout is not None: t.banner_timeout = banner_timeout t.start_client() ResourceManager.register(self, t) server_key = t.get_remote_server_key() keytype = server_key.get_name() if port == SSH_PORT: server_hostkey_name = hostname else: server_hostkey_name = "[%s]:%d" % (hostname, port) # If GSS-API Key Exchange is performed we are not required to check the # host key, because the host is authenticated via GSS-API / SSPI as # well as our client. if not self._transport.use_gss_kex: our_server_key = self._system_host_keys.get( server_hostkey_name, {}).get(keytype, None) if our_server_key is None: our_server_key = self._host_keys.get(server_hostkey_name, {}).get(keytype, None) if our_server_key is None: # will raise exception if the key is rejected; let that fall out self._policy.missing_host_key(self, server_hostkey_name, server_key) # if the callback returns, assume the key is ok our_server_key = server_key if server_key != our_server_key: raise BadHostKeyException(hostname, server_key, our_server_key) if username is None: username = getpass.getuser() if key_filename is None: key_filenames = [] elif isinstance(key_filename, string_types): key_filenames = [key_filename] else: key_filenames = key_filename if gss_host is None: gss_host = hostname self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys, gss_auth, gss_kex, gss_deleg_creds, gss_host, check_key)