示例#1
0
 def test_reraising_bad_host_key_exc(self):
     self.client.password = "******"
     self.client.private_key = self.rsakey
     exc = paramiko.BadHostKeyException(None, None, None)
     self.mock_connect.side_effect = exc
     self.assertRaises(paramiko.BadHostKeyException,
                       self.client.connect)
示例#2
0
 def is_missing_host_key(self, client, hostname, key):
     k = client._host_keys.lookup(hostname)
     if k is None:
         return True
     host_key = k.get(key.get_name(), None)
     if host_key is None:
         return True
     if host_key != key:
         raise paramiko.BadHostKeyException(hostname, key, host_key)
示例#3
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)
示例#4
0
 def test_logging_when_badhostkey(self, mock_LOG):
     """Test when raising BadHostKeyException."""
     self.client.password = "******"
     self.client.private_key = self.rsakey
     exc = paramiko.BadHostKeyException(None, None, None)
     self.mock_connect.side_effect = exc
     try:
         self.client.connect()
     except paramiko.BadHostKeyException:
         pass
     mock_LOG.info.assert_called_with(
         "ssh://%s@%s:%d failed:  %s. "
         "You might have a bad key entry on your server, "
         "but this is a security issue and won't be handled "
         "automatically. To fix this you can remove the "
         "host entry for this host from the /.ssh/known_hosts file",
         'test-user', '123.456.789.0', 22, exc)
示例#5
0
 def missing_host_key(self, client, hostname, key):
     if self.gw.ssh_host_key:
         # Verify host key
         line = base64.b64decode(self.gw.ssh_host_key).decode()
         entry = paramiko.hostkeys.HostKeyEntry.from_line(line)
         if hostname not in entry.hostnames or key != entry.key:
             raise paramiko.BadHostKeyException(hostname, key, entry.key)
     else:
         # Auto-add host key
         entry = paramiko.hostkeys.HostKeyEntry([hostname], key)
         line = entry.to_line()
         self.gw.ssh_host_key = base64.b64encode(line.encode())
         self.gw.ssh_host_key_filename = SSH_KNOWN_HOSTS
         self.gw.message_post(body=(_("Added host key for '%s' (%s)") %
                                    (self.gw.server,
                                     self.gw.ssh_host_fingerprint)))
         _logger.warning("Added host key for '%s' (%s)",
                         self.gw.server, self.gw.ssh_host_fingerprint)
示例#6
0
 def test_SFTP_handle_connection_exceptions(self, mock_ssh):
     """SFTP should catch exceptions raised when trying to connect"""
     # Before you implement the logging you'll want to test for it here
     exceptions = [
         paramiko.AuthenticationException,
         paramiko.BadHostKeyException(mock.Mock(), mock.Mock(),
                                      mock.Mock()), paramiko.SSHException
     ]
     mock_ssh.return_value.connect.side_effect = exceptions
     for exc in exceptions:
         with self.subTest(msg=str(exc)):
             with self.assertLogs(msutils.uploading.logger, 'ERROR') as cm:
                 try:
                     msutils.uploading.send_pages_sftp(
                         pages=self.mock_pages, **self.call_args)
                 except Exception as e:
                     self.fail(str(e))
             self.assertGreaterEqual(len(cm.output), 1)
示例#7
0
    def connect(cls,
                host,
                port,
                hostkey,
                userkey,
                keypass=None,
                username=None,
                password=None):
        """
        Create a new SFTP client and connect to C{host}.

        Returns None if creation or connection fails.

        C{username} and C{password} are optional and not needed
        for the authentication, that is by default public key.

        @param host: the host name or ip address.
        @type host: str
        @param port: the host port.
        @type port: int
        @param hostkey: the path to the host's public key.
        @type hostkey: str
        @param userkey: the path to the user's private key.
        @type userkey: str
        @param keypass: password for encrypted key.
        @type keypass: str
        @param username: the user's name (optional).
        @type username: str
        @param password: the user's password (optional).
        @type password: str
        @return: L{SFTPClient} or None.
        @rtype: L{SFTPClient}
        """

        known_host = ''
        # file format "ssh-rsa AAA.... user@somemachine"
        with open(hostkey, 'rb') as f:
            known_host = f.read()
        # get the base64 encoded data of the host's public key
        known_host = known_host.split(' ')[1]

        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.connect((host, int(port)))
        transport = paramiko.Transport(client_socket)
        transport.start_client()

        key_data = transport.get_remote_server_key().get_base64()
        if not known_host == key_data:
            raise paramiko.BadHostKeyException(host, key_data, known_host)

        key = paramiko.RSAKey.from_private_key_file(userkey, keypass)
        username = username if username else ''
        try:
            transport.auth_publickey(username, key)
        except Exception:
            transport.auth_password(username, password)

        chan = transport.open_session()
        if chan is None:
            return None
        chan.invoke_subsystem('sftp')
        return cls(chan)
示例#8
0
def connect_keyboard_interactive(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):
    """
    modified from paramiko.SSHClient.connect() and
    paramiko.Transport.auth_interactive() so that it will not cause failed
    authentication attempts on hosts that allow "keyboard_interactive"
    but not "password" authentication (even though those two are
    essentially the same thing).
    """

    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
    sock.connect(addr)
    t = self._transport = paramiko.Transport(sock)
    t.use_compression(compress=compress)
    if self._log_channel is not None:
        t.set_log_channel(self._log_channel)
    t.start_client()
    paramiko.resource.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 paramiko.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

    def handler(title, instructions, fields):
        if len(fields) > 1:
            raise SSHException('Fallback authentication failed.')
        if len(fields) == 0:
            # for some reason, at least on os x, a 2nd request will
            # be made with zero fields requested.  maybe it's just
            # to try to fake out automated scripting of the exact
            # type we're doing here.  *shrug* :)
            return []
        return [password]

    self._transport.auth_interactive(username, handler)