def _get_fingerprint(self, signing_key):
        ssh_key = SSHKey("ssh-ed25519 {0}"
                         .format(signing_key.get_base64()))
        try:
            ssh_key.parse()
        except:
            self._raise_error("INVALID signing key type. ABORTING.")

        return ssh_key.hash_sha256()  # SHA256:xyz
Пример #2
0
 def check_key(self, pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment, **kwargs):  # pylint:disable=too-many-arguments
     """ Checks valid key """
     ssh = SSHKey(pubkey, **kwargs)
     ssh.parse()
     self.assertEqual(ssh.bits, bits)
     self.assertEqual(ssh.hash_md5(), fingerprint_md5)
     self.assertEqual(ssh.options_raw, options)
     self.assertEqual(ssh.comment, comment)
     if fingerprint_sha256 is not None:
         self.assertEqual(ssh.hash_sha256(), fingerprint_sha256)
Пример #3
0
def key_to_public_key(key):
    # type: (str) -> PublicKey
    """Convert the string representation of a public key to a PublicKey transfer object."""
    pubkey = SSHKey(key, strict=True)
    pubkey.parse()
    return PublicKey(
        public_key=pubkey.keydata.strip(),
        fingerprint=pubkey.hash_md5().replace("MD5:", ""),
        fingerprint_sha256=pubkey.hash_sha256().replace("SHA256:", ""),
    )
Пример #4
0
def sshkey_good_format(key):
    """Return False if the key hasn't a known format, else return a hash""" 
    sshkey = SSHKey(key, strict = True)

    try:
        sshkey.parse()
    except: 
        return False
    # We remove the "SHA256:" header and we add "=" at the end
    return sshkey.hash_sha256()[7:] + "="
Пример #5
0
 def check_key(self, pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment, **kwargs):  # pylint:disable=too-many-arguments
     """ Checks valid key """
     ssh = SSHKey(pubkey, **kwargs)
     ssh.parse()
     self.assertEqual(ssh.bits, bits)
     self.assertEqual(ssh.hash_md5(), fingerprint_md5)
     self.assertEqual(ssh.options_raw, options)
     self.assertEqual(ssh.comment, comment)
     if fingerprint_sha256 is not None:
         self.assertEqual(ssh.hash_sha256(), fingerprint_sha256)
Пример #6
0
def parse_key(data):
    key = {}

    ssh_key = SSHKey(data.decode())
    if ssh_key.bits is not None:
        name = ssh_key.key_type.decode()
        key[name + ":size"] = ssh_key.bits
        key[name + ":sha256"] = ssh_key.hash_sha256()

    return key
Пример #7
0
 def hash(sshkey):
     """ Return hash of sshkey """
     key = SSHKey(sshkey, strict=True)
     try:
         key.parse()
     except:
         app.logger.error("ERROR: wrong sshkey format: " + sshkey,
                          file=sys.stderr)
         return ("Wrong ssh key format - " + str(uuid.uuid4()))
     # We remove the "SHA256:" header and we add "=" at the end
     return key.hash_sha256()[7:] + "="
Пример #8
0
 def check_auth_publickey(self, username, key):
     ssh_pub_key = SSHKey("{} {}".format(key.get_name(), key.get_base64()))
     ssh_pub_key.parse()
     logging.info("check_auth_publickey: username=%s, key=%s %s %sbits",
                  username, key.get_name(), ssh_pub_key.hash_sha256(),
                  ssh_pub_key.bits)
     if self.args.disable_pubkey_auth:
         logging.debug(
             "Publickey login attempt, but publickey auth was disabled!")
         return paramiko.AUTH_FAILED
     return self.session.authenticator.authenticate(username, key=key)
Пример #9
0
 def parse(self):
     """
     Cleans the key from comments and options and pulates the MD5, SHA256
     and SHA512 sums.
     """
     ssh_key = SSHKey(self.public_key,
                      parse_options=False,
                      strict_mode=True)
     ssh_key.parse()
     # Tiny hack, to get the clean key
     self.public_key = ' '.join(ssh_key._split_key(ssh_key.keydata))
     self.md5 = ssh_key.hash_md5()
     self.sha256 = ssh_key.hash_sha256()
     self.sha512 = ssh_key.hash_sha512()
Пример #10
0
    def _get_fingerprint(self, signing_key):
        # This is hard-coded for now, until we figure out
        # a way to do this properly:
        encoding = self._add_encoding(b'ssh-ed25519') +\
                   self._add_encoding(signing_key)

        ssh_key_text: str = base64.b64encode(encoding).decode("utf-8")
        ssh_key = SSHKey("ssh-ed25519 {0}".format(ssh_key_text))
        try:
            ssh_key.parse()
        except Exception:
            self._raise_error("INVALID signing key type. ABORTING.")

        return ssh_key.hash_sha256()  # SHA256:xyz
Пример #11
0
 def add_public_key_to_user(self, key, user):
     # type: (str, str) -> None
     sql_user = User.get(self.session, name=user)
     assert sql_user
     public_key = SSHKey(key, strict=True)
     public_key.parse()
     sql_public_key = PublicKey(
         user_id=sql_user.id,
         public_key=public_key.keydata.strip(),
         fingerprint=public_key.hash_md5().replace("MD5:", ""),
         fingerprint_sha256=public_key.hash_sha256().replace("SHA256:", ""),
         key_size=public_key.bits,
         key_type=public_key.key_type,
         comment=public_key.comment,
     )
     sql_public_key.add(self.session)
Пример #12
0
 def auth_publickey(self, username, host, port, key):
     if key.can_sign():
         ssh_pub_key = SSHKey("{} {}".format(key.get_name(),
                                             key.get_base64()))
         ssh_pub_key.parse()
         logging.info(
             "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)
     if self.REQUEST_AGENT:
         # 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!
         logging.debug(
             "authentication failed. accept connection and wait for agent.")
         return paramiko.AUTH_SUCCESSFUL
     return paramiko.AUTH_FAILED
Пример #13
0
    def check_auth_publickey(self, username: Text, key: PKey) -> int:
        ssh_pub_key = SSHKey(f"{key.get_name()} {key.get_base64()}")
        ssh_pub_key.parse()
        logging.debug("check_auth_publickey: username=%s, key=%s %s %sbits",
                      username, key.get_name(), ssh_pub_key.hash_sha256(),
                      ssh_pub_key.bits)
        if self.session.session_log_dir:
            os.makedirs(self.session.session_log_dir, exist_ok=True)
            pubkeyfile_path = os.path.join(self.session.session_log_dir,
                                           'publickeys')
            with open(pubkeyfile_path, 'a+') as pubkeyfile:
                pubkeyfile.write(
                    f"{key.get_name()} {key.get_base64()} saved-from-auth-publickey\n"
                )
        if self.args.disable_pubkey_auth:
            logging.debug(
                "Publickey login attempt, but publickey auth was disabled!")
            return paramiko.common.AUTH_FAILED
        if self.args.accept_first_publickey:
            logging.debug('host probing disabled - first key accepted')
            if self.args.disallow_publickey_auth:
                logging.debug(
                    'ignoring argument --disallow-publickey-auth, first key still accepted'
                )
            self.session.authenticator.authenticate(username, key=None)
            self.session.accepted_key = key
            return paramiko.common.AUTH_SUCCESSFUL

        auth_result: int = self.session.authenticator.authenticate(username,
                                                                   key=key)
        if auth_result == paramiko.common.AUTH_SUCCESSFUL:
            self.session.accepted_key = key
        if self.session.accepted_key is not None and self.args.enable_trivial_auth:
            logging.debug("found valid key for trivial authentication")
            return paramiko.common.AUTH_FAILED
        if self.args.disallow_publickey_auth:
            return paramiko.common.AUTH_FAILED
        return auth_result
Пример #14
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
Пример #15
0
    def connect(self) -> bool:
        message = None

        self.transport = paramiko.Transport((self.host, self.port))
        if self.CIPHERS:
            if not isinstance(self.CIPHERS, tuple):
                raise ValueError('client ciphers must be a tuple')
            self.transport.get_security_options().ciphers = self.CIPHERS

        try:
            if self.method is AuthenticationMethod.password:
                self.transport.connect(username=self.user,
                                       password=self.password)
            elif self.method is AuthenticationMethod.publickey:
                self.transport.connect(username=self.user,
                                       password=self.password,
                                       pkey=self.key)
            elif self.method is AuthenticationMethod.agent:
                if self.agent is not None:
                    keys = self.agent.get_keys()
                    if not keys:
                        raise NoAgentKeys()
                    for k in keys:
                        try:
                            self.transport.connect(username=self.user,
                                                   password=self.password,
                                                   pkey=k)
                            ssh_pub_key = SSHKey(
                                f"{k.get_name()} {k.get_base64()}")
                            ssh_pub_key.parse()
                            logging.debug(
                                "ssh-mitm connected to remote host with username=%s, key=%s %s %sbits",
                                self.user, k.get_name(),
                                ssh_pub_key.hash_sha256(), ssh_pub_key.bits)
                            break
                        except paramiko.AuthenticationException:
                            self.transport.close()
                            self.transport = paramiko.Transport(
                                (self.host, self.port))

            else:
                logging.error('authentication method "%s" not supported!',
                              self.method.value)
                return False

            remotekey = self.transport.get_remote_server_key()
            if not self.check_host_key(f"{self.host}:{self.port}",
                                       remotekey.get_name(), remotekey):
                raise InvalidHostKey()
            self.connected = True
            return True

        except paramiko.SSHException:
            message = "general ssh error"
        except NoAgentKeys:
            message = "no agent keys found"
        except InvalidHostKey:
            message = "Hostkey is invalid"

        userstring = f"{self.user}:{self.password}@{self.host}:{self.port}"
        logging.debug('Authentication failed: %s, User: %s, Message: %s',
                      self.method.value, userstring, message or "")

        return False