Esempio n. 1
0
 def _ssh_authentication_input_loop(self, hostkeys: paramiko.HostKeys,
                                    key: paramiko.PKey) -> None:
     # Ask user for permission to continue
     # let it look like openssh
     sha64_fingerprint = base64.b64encode(
         hashlib.sha256(base64.b64decode(
             key.get_base64())).digest()).decode("utf-8")[:-1]
     key_type = key.get_name().replace("ssh-", "").upper()
     print(f"The authenticity of host '{self.hostname}' can't "
           "be established.")
     print(f"{key_type} key fingerprint is {sha64_fingerprint}.")
     print("Are you sure you want to continue connecting (yes/no)? ",
           end="")
     add = input()
     while True:
         if add == "yes":
             hostkeys.add(self.hostname, key.get_name(), key)
             # ask user if the key should be added permanently
             print(
                 f"Do you want to add {self.hostname} "
                 "to known_hosts (yes/no)? ",
                 end="",
             )
             save = input()
             while True:
                 if save == "yes":
                     try:
                         hostkeys.save(filename=self.known_hosts_file)
                     except OSError as e:
                         raise GvmError(
                             "Something went wrong with writing "
                             f"the known_hosts file: {e}") from None
                     logger.info(
                         "Warning: Permanently added '%s' (%s) to "
                         "the list of known hosts.",
                         self.hostname,
                         key_type,
                     )
                     break
                 elif save == "no":
                     logger.info(
                         "Warning: Host '%s' (%s) not added to "
                         "the list of known hosts.",
                         self.hostname,
                         key_type,
                     )
                     break
                 else:
                     print("Please type 'yes' or 'no': ", end="")
                     save = input()
             break
         elif add == "no":
             return sys.exit(
                 "User denied key. Host key verification failed.")
         else:
             print("Please type 'yes' or 'no': ", end="")
             add = input()
Esempio n. 2
0
    def _create_connection(self, params: StorageConfig) -> SFTPClient:
        self.__log.debug('Creating connection to SSH server ' + params['host'])
        self.__ssh = SSHClient()
        if 'enableHostKeys' not in params or params['enableHostKeys']:
            self.__ssh.load_system_host_keys(filename=params.get('hostKeysFilePath'))

        should_save_host_keys = False
        if 'knownHostsPolicy' in params:
            policy: str = params['knownHostsPolicy'].lower()
            if policy == 'reject':
                self.__ssh.set_missing_host_key_policy(RejectPolicy)
            elif policy == 'auto-add':
                self.__ssh.set_missing_host_key_policy(AutoAddPolicy)
                should_save_host_keys = True
            elif policy == 'ignore':
                self.__ssh.set_missing_host_key_policy(WarningPolicy)

        pkey = None
        if 'privateKey' in params:
            pkey = PKey(data=params['privateKey'])
        self.__ssh.connect(hostname=params['host'],
                           port=params.get('port', 22),
                           username=params.get('user'),
                           password=params.get('password'),
                           pkey=pkey,
                           key_filename=params.get('privateKeyPath'),
                           allow_agent=params.get('allowAgent'),
                           compress=params.get('compress'))

        if should_save_host_keys and 'hostKeysFilePath' in params:
            self.__ssh.save_host_keys(filename=params['hostKeysFilePath'])

        self.__log.debug('Starting SFTP client')
        return self.__ssh.open_sftp()
Esempio n. 3
0
def _validate_key(host: str, server_key: PKey):
    known_hosts_file = '~/.ssh/known_hosts'
    host_keys = HostKeys()
    host_keys.load(os.path.expanduser(known_hosts_file))
    known_server_keys = host_keys.get(host)
    add_host_key_instructions = 'You can add the host key with `\n' \
        f'ssh-keyscan -H {host} >> {known_hosts_file}\n`'
    if known_server_keys is None:
        raise SSHAuthenticationError(
            f'plz host is not known. {add_host_key_instructions}')
    known_server_keys = host_keys.get(host)
    if known_server_keys.get(server_key.get_name()) is None:
        raise SSHAuthenticationError(
            f'No key found for host {host} with name '
            f'{server_key.get_name()}. {add_host_key_instructions}')
    if server_key != known_server_keys.get(server_key.get_name()):
        raise SSHAuthenticationError(
            f'Bad host key for `{host}`. Fix your `{known_hosts_file}` file')
Esempio n. 4
0
 def auth_publickey(self, username: Text, host: Text, port: int,
                    key: PKey) -> int:
     ssh_pub_key = SSHKey(f"{key.get_name()} {key.get_base64()}")
     ssh_pub_key.parse()
     if key.can_sign():
         logging.debug(
             "AuthenticatorPassThrough.auth_publickey: username=%s, key=%s %s %sbits",
             username, key.get_name(), ssh_pub_key.hash_sha256(),
             ssh_pub_key.bits)
         return self.connect(username,
                             host,
                             port,
                             AuthenticationMethod.publickey,
                             key=key)
     # Ein Publickey wird nur direkt von check_auth_publickey
     # übergeben. In dem Fall müssen wir den Client authentifizieren,
     # damit wir auf den Agent warten können!
     publickey = paramiko.pkey.PublicBlob(key.get_name(), key.asbytes())
     if probe_host(host, port, username, publickey):
         logging.debug(
             f"Found valid key for host {host}:{port} username={username}, key={key.get_name()} {ssh_pub_key.hash_sha256()} {ssh_pub_key.bits}bits"
         )
         return paramiko.common.AUTH_SUCCESSFUL
     return paramiko.common.AUTH_FAILED
Esempio n. 5
0
def get_sftp_conn(config):
    """Make a SFTP connection, returns sftp client and connection objects"""
    remote = config.get('remote_location')
    parts = urlparse(remote)

    if ':' in parts.netloc:
        hostname, port = parts.netloc.split(':')
    else:
        hostname = parts.netloc
        port = 22
    port = int(port)

    username = config.get('remote_username') or getuser()
    luser = get_local_user(username)
    sshdir = get_ssh_dir(config, luser)
    hostkey = get_host_keys(hostname, sshdir)

    try:
        sftp = None
        keys = get_ssh_keys(sshdir)
        transport = Transport((hostname, port))
        while not keys.empty():
            try:
                key = PKey.from_private_key_file(keys.get())
                transport.connect(
                    hostkey=hostkey,
                    username=username,
                    password=None,
                    pkey=key)
                sftp = SFTPClient.from_transport(transport)
                break
            except (PasswordRequiredException, SSHException):
                pass
        if sftp is None:
            raise SaChannelUpdateTransportError("SFTP connection failed")
        return sftp, transport
    except BaseException as msg:
        raise SaChannelUpdateTransportError(msg)
Esempio n. 6
0
def get_sftp_conn(config):
    """Make a SFTP connection, returns sftp client and connection objects"""
    remote = config.get('remote_location')
    parts = urlparse(remote)

    if ':' in parts.netloc:
        hostname, port = parts.netloc.split(':')
    else:
        hostname = parts.netloc
        port = 22
    port = int(port)

    username = config.get('remote_username') or getuser()
    luser = get_local_user(username)
    sshdir = get_ssh_dir(config, luser)
    hostkey = get_host_keys(hostname, sshdir)

    try:
        sftp = None
        keys = get_ssh_keys(sshdir)
        transport = Transport((hostname, port))
        while not keys.empty():
            try:
                key = PKey.from_private_key_file(keys.get())
                transport.connect(hostkey=hostkey,
                                  username=username,
                                  password=None,
                                  pkey=key)
                sftp = SFTPClient.from_transport(transport)
                break
            except (PasswordRequiredException, SSHException):
                pass
        if sftp is None:
            raise SaChannelUpdateTransportError("SFTP connection failed")
        return sftp, transport
    except BaseException as msg:
        raise SaChannelUpdateTransportError(msg)
Esempio n. 7
0
def generate_host_key(pkey: paramiko.PKey):
    key_fh = StringIO()
    pkey.write_private_key(key_fh)
    key_fh.seek(0)
    key_obj = paramiko.RSAKey(file_obj=key_fh)
    return key_obj.get_base64()
Esempio n. 8
0
def generate_key_string(pkey: paramiko.PKey):
    key_fh = StringIO()
    pkey.write_private_key(key_fh)
    key_fh.seek(0)
    key_str = key_fh.read()
    return key_str
Esempio n. 9
0
def generate_key_string(pkey: paramiko.PKey, passphrase: Optional[str] = None):
    key_fh = StringIO()
    pkey.write_private_key(key_fh, password=passphrase)
    key_fh.seek(0)
    key_str = key_fh.read()
    return key_str