Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 def connect(self, hostname, sock, port=22, username=None, password=None, pkey=None,
             key_filename=None, timeout=None, allow_agent=True, look_for_keys=True):
     t = self._transport = ssh.Transport(sock)
     
     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()
     
     our_server_key = self._system_host_keys.get(hostname, {}).get(keytype, None)
     if our_server_key is None:
         our_server_key = self._host_keys.get(hostname, {}).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, hostname, server_key)
         # if the callback returns, assume the key is ok
         our_server_key = server_key
     
     if server_key != our_server_key:
         raise ssh.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
     self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
Exemplo n.º 3
0
    def _get_ssh_connection(self):
        """Returns an ssh connection to the specified host"""
        _timeout = True
        ssh = SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        _start_time = time.time()
        saved_exception = exceptions.StandardError()
        #doing this because the log file fills up with these messages
        #this way it only logs it once
        log_attempted = False
        socket_error_logged = False
        auth_error_logged = False
        ssh_error_logged = False
        while not self._is_timed_out(self.timeout, _start_time):
            try:
                if not log_attempted:
                    self._log.debug('Attempting to SSH connect to: ')
                    self._log.debug('host: %s, username: %s, password: %s' %
                                    (self.host, self.username, self.password))
                    log_attempted = True
                ssh.connect(hostname=self.host,
                            username=self.username,
                            password=self.password,
                            timeout=20,
                            key_filename=[],
                            look_for_keys=False,
                            allow_agent=False)
                _timeout = False
                break
            except socket.error as e:
                if not socket_error_logged:
                    self._log.error('Socket Error: %s' % str(e))
                    socket_error_logged = True
                saved_exception = e
                continue
            except paramiko.AuthenticationException as e:
                if not auth_error_logged:
                    self._log.error('Auth Exception: %s' % str(e))
                    auth_error_logged = True
                saved_exception = e
                time.sleep(2)
                continue
            except paramiko.SSHException as e:
                if not ssh_error_logged:
                    self._log.error('SSH Exception: %s' % str(e))
                    ssh_error_logged = True
                saved_exception = e
                time.sleep(2)
                continue
                #Wait 2 seconds otherwise
            time.sleep(2)
        if _timeout:
            self._log.error('SSHConnector timed out while trying to establish a connection')
            raise saved_exception

        #This MUST be done because the transport gets garbage collected if it
        #is not done here, which causes the connection to close on invoke_shell
        #which is needed for exec_shell_command
        ResourceManager.register(self, ssh.get_transport())
        return ssh
Exemplo n.º 4
0
    def connect(self,
                hostname,
                sock,
                port=22,
                username=None,
                password=None,
                pkey=None,
                key_filename=None,
                timeout=None,
                allow_agent=True,
                look_for_keys=True):
        t = self._transport = ssh.Transport(sock)

        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()

        our_server_key = self._system_host_keys.get(hostname,
                                                    {}).get(keytype, None)
        if our_server_key is None:
            our_server_key = self._host_keys.get(hostname,
                                                 {}).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, hostname, server_key)
            # if the callback returns, assume the key is ok
            our_server_key = server_key

        if server_key != our_server_key:
            raise ssh.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
        self._auth(username, password, pkey, key_filenames, allow_agent,
                   look_for_keys)
Exemplo n.º 5
0
 def connect(self, ip , port = 36000 , username = None, passwd = None):
     if self.ssh:
         self.ssh.close()
         self.ssh = None
         self.sftp = None
     self.ssh = paramiko.SSHClient()
     self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
     try: 
         self.ssh.connect(ip , port , username, passwd , timeout=5 )#password
     except paramiko.BadAuthenticationType , e:
         log.warning('use password failed  try keyboard-interactive')
         #see SSHClient::connect
         from paramiko.resource import ResourceManager
         t = self.ssh._transport = paramiko.Transport((ip, port))
         t.start_client()
         ResourceManager.register(self.ssh, t)
         def handler(title, instructions, prompts):
            return [ passwd ]
         t.auth_interactive(username,handler)
Exemplo n.º 6
0
	def __create_and_connect_transport(self, _hostname, _transport_sock, _username=None, _password=None):
		"""
		Helper function to create a new Transport and perform the required SSH authentication
		-- just here to keep the code more readable
		"""
		#print 'Create transport on: %s' % _transport_sock
		t = self._transport = __Transport(_transport_sock)
		self._chained_transports.append(t)

		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()
		
		our_server_key = self._system_host_keys.get(_hostname, {}).get(keytype, None)
		if our_server_key is None:
			our_server_key = self._host_keys.get(_hostname, {}).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, _hostname, 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

		self._auth(_username, _password, pkey, key_filenames, allow_agent, look_for_keys)
Exemplo n.º 7
0
    def connect(self, ip, port=36000, username=None, passwd=None):
        if self.ssh:
            self.ssh.close()
            self.ssh = None
            self.sftp = None
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            self.ssh.connect(ip, port, username, passwd, timeout=5)  #password
        except paramiko.BadAuthenticationType, e:
            log.warning('use password failed  try keyboard-interactive')
            #see SSHClient::connect
            from paramiko.resource import ResourceManager
            t = self.ssh._transport = paramiko.Transport((ip, port))
            t.start_client()
            ResourceManager.register(self.ssh, t)

            def handler(title, instructions, prompts):
                return [passwd]

            t.auth_interactive(username, handler)
Exemplo n.º 8
0
    def _paramiko_connect(self):
        # Find supported address families.
        addrinfo = socket.getaddrinfo(self.host, self.port)
        for family, socktype, proto, canonname, sockaddr in addrinfo:
            af = family
            addr = sockaddr
            if socktype == socket.SOCK_STREAM:
                break

        # Open a socket.
        sock = socket.socket(af, socket.SOCK_STREAM)
        try:
            sock.settimeout(self.connect_timeout or None)
        except:
            pass
        sock.connect(addr)

        # Init the paramiko protocol.
        t = paramiko.Transport(sock)
        t.banner_timeout = self.banner_timeout
        t.start_client()
        ResourceManager.register(self, t)

        # Check system host keys.
        server_key = t.get_remote_server_key()
        keytype = server_key.get_name()
        our_server_key = self._system_host_keys.get(self.host,
                                                    {}).get(keytype, None)
        if our_server_key is None:
            our_server_key = self._host_keys.get(self.host,
                                                 {}).get(keytype, None)
        if our_server_key is None:
            self._missing_host_key(server_key)
            # if the callback returns, assume the key is ok
            our_server_key = server_key
        if server_key != our_server_key:
            raise BadHostKeyException(self.host, server_key, our_server_key)

        t.set_keepalive(self.KEEPALIVE_INTERVAL)
        return t
Exemplo n.º 9
0
    def _paramiko_connect(self):
        # Find supported address families.
        addrinfo = socket.getaddrinfo(self.host, self.port)
        for family, socktype, proto, canonname, sockaddr in addrinfo:
            af = family
            addr = sockaddr
            if socktype == socket.SOCK_STREAM:
                break

        # Open a socket.
        sock = socket.socket(af, socket.SOCK_STREAM)
        try:
            sock.settimeout(self.timeout or None)
        except:
            pass
        sock.connect(addr)

        # Init the paramiko protocol.
        t = paramiko.Transport(sock)
        t.start_client()
        ResourceManager.register(self, t)

        # Check system host keys.
        server_key = t.get_remote_server_key()
        keytype = server_key.get_name()
        our_server_key = self._system_host_keys.get(self.host, {}).get(keytype, None)
        if our_server_key is None:
            our_server_key = self._host_keys.get(self.host, {}).get(keytype, None)
        if our_server_key is None:
            self._missing_host_key(server_key)
            # if the callback returns, assume the key is ok
            our_server_key = server_key
        if server_key != our_server_key:
            raise BadHostKeyException(self.host, server_key, our_server_key)

        t.set_keepalive(self.KEEPALIVE_INTERVAL)

        return t
Exemplo n.º 10
0
    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:
            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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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:
            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)
Exemplo n.º 13
0
    def connect(self, hostname, port=22, username=None, password=None, pkey=None,
                key_filename=None, timeout=None, allow_agent=True, look_for_keys=True):
        """
        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 of an optional private key to use
            for authentication
        @type key_filename: 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

        @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
        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if timeout is not None:
            try:
                sock.settimeout(timeout)
            except:
                pass

        sock.connect((hostname, port))
        t = self._transport = Transport(sock)

        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()
        
        our_server_key = self._system_host_keys.get(hostname, {}).get(keytype, None)
        if our_server_key is None:
            our_server_key = self._host_keys.get(hostname, {}).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, hostname, 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()
        
        self._auth(username, password, pkey, key_filename, allow_agent, look_for_keys)
Exemplo n.º 14
0
    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)
Exemplo n.º 16
0
    def connect(self, username=None, password=None,
                accept_missing_host_key=True, tcp_timeout=30,
                auth_strategy=SSHAuthStrategy.PASSWORD,
                port=22, key=None, allow_agent=True, key_filename=None):
        """
        Attempts to connect to a remote server via SSH

        @param username: Username to be used for SSH connection
        @type username: string
        @param password: Password to be used for SSH connection
        @type password: string
        @param auth_strategy: Authentication strategy to use to connect
        @type auth_strategy: string
        @param port: Port to use for the SSH connection
        @type port: int
        @param key: Text of an SSH key to be used to connect
        @type key: string
        @param key_filename: Name of a file that contains a SSH key
        @type key_filename: string
        @param allow_agent: Set to False to disable connecting to
                            the SSH agent
        @type allow_agent: bool
        @param accept_missing_host_key: Sets if a SSH connection can
                                        be made to remote server if
                                        the server does not have a
                                        host key in the local system
        @type accept_missing_host_key: bool
        @return: None
        """

        ssh = ExtendedParamikoSSHClient()
        if accept_missing_host_key:
            ssh.set_missing_host_key_policy(AutoAddPolicy())

        connect_args = {'hostname': self.host, 'username': username,
                        'timeout': tcp_timeout, 'port': port,
                        'allow_agent': allow_agent}

        self._log.debug('Attempting to SSH connect to {host} '
                        'with user {user} and strategy {strategy}.'.format(
                            host=self.host, user=username,
                            strategy=auth_strategy))

        if auth_strategy == SSHAuthStrategy.PASSWORD:
            connect_args['password'] = password

        if auth_strategy == SSHAuthStrategy.LOCAL_KEY:
            connect_args['look_for_keys'] = True

        if auth_strategy == SSHAuthStrategy.KEY_STRING:
            key_file = io.StringIO(key)
            key = RSAKey.from_private_key(key_file)
            connect_args['pkey'] = key

        if auth_strategy == SSHAuthStrategy.KEY_FILE_LIST:
            connect_args['key_filename'] = key_filename

        # Add sock proxy if ssh tunnel through proxy/bastion is required
        if self.is_proxy_needed():
            self._log.info("Using a proxy: {proxy}".format(proxy=self.proxy))
            proxy_str = 'ssh -q -a -x {proxy} nc {host} {port}'
            proxy_cmd = proxy_str.format(proxy=self.proxy,
                                         host=self.host, port=port)
            connect_args['sock'] = ProxyCommand(proxy_cmd)

        try:
            ssh.connect(**connect_args)
        except (AuthenticationException, SSHException,
                socket.error, EOFError) as exception:
            # Log the failure
            self._log.error(exception.message)
        else:
            # Complete setup of the client
            ResourceManager.register(self, ssh.get_transport())
            self.ssh_connection = ssh
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
    def connect(self,
                hostname,
                port=22,
                username=None,
                password=None,
                pkey=None,
                key_filename=None,
                timeout=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 of an optional private key to use
            for authentication
        @type key_filename: str
        @param timeout: an optional timeout (in seconds) for the TCP connect
        @type timeout: float
        
        @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
        """
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if timeout is not None:
            try:
                sock.settimeout(timeout)
            except:
                pass

        sock.connect((hostname, port))
        t = self._transport = Transport(sock)

        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()

        our_server_key = self._system_host_keys.get(hostname,
                                                    {}).get(keytype, None)
        if our_server_key is None:
            our_server_key = self._host_keys.get(hostname,
                                                 {}).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, hostname, 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()
        self._auth(username, password, pkey, key_filename)
Exemplo n.º 19
0
    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):
        """
        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

        @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
        """
        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:
            raise SSHException('No suitable address family for %s' % hostname)
        sock = socket.socket(af, socket.SOCK_STREAM)
        if timeout is not None:
            try:
                sock.settimeout(timeout)
            except:
                pass
        sock.connect(addr)
        t = self._transport = Transport(sock)

        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, (str, unicode)):
            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, 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)