Ejemplo n.º 1
0
def is_valid_ssh_key(ssh_key):
    ssh = SSHKey(ssh_key)
    try:
        ssh.parse()
    except (InvalidKeyException, NotImplementedError):
        return False
    return True
Ejemplo n.º 2
0
        def get_agent_pubkeys() -> List[Tuple[Text, SSHKey, bool, Text]]:
            pubkeyfile_path = None

            keys_parsed: List[Tuple[Text, SSHKey, bool, Text]] = []
            if self.session.agent is None:
                return keys_parsed

            keys = self.session.agent.get_keys()
            for k in keys:
                ssh_pub_key = SSHKey(f"{k.get_name()} {k.get_base64()}")
                ssh_pub_key.parse()
                keys_parsed.append(
                    (k.get_name(), ssh_pub_key, k.can_sign(), k.get_base64()))

            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("".join([
                        f"{k[0]} {k[3]} saved-from-agent\n"
                        for k in keys_parsed
                    ]))

            return keys_parsed
async def validate_ssh(ssh_pub: str):
    ssh = SSHKey(ssh_pub)
    try:
        ssh.parse()
        return True
    except:
        return False
Ejemplo n.º 4
0
 def validate_key(self, key):
     try:
         ssh = SSHKey(key)
         ssh.parse()
         return ssh
     except:
         return False
Ejemplo n.º 5
0
def ssh_key(key_string):
    import sshpubkeys
    from sshpubkeys import SSHKey

    key = SSHKey(key_string, strict_mode=True)
    try:
        key.parse()
    except sshpubkeys.exceptions.InvalidTypeException as err:
        print("Invalid/unrecognised key type:", err)
        exit(1)
    except sshpubkeys.exceptions.TooShortKeyException as err:
        print("Key too short:", err)
        exit(1)
    except sshpubkeys.exceptions.InvalidKeyLengthException as err:
        print("Key length too short or too long:", err)
        exit(1)
    except sshpubkeys.exceptions.TooLongKeyException as err:
        print("Key too long:", err)
        exit(1)
    except sshpubkeys.exceptions.MalformedDataException as err:
        print(
            "Malformed data - key may be corrupted, truncated or include extra content:",
            err)
        exit(1)
    except sshpubkeys.exceptions.InvalidKeyException as err:
        print("Invalid key:", err)
        exit(1)
    except NotImplementedError as err:
        print("Invalid/unsupported key type:", err)
        exit(1)
Ejemplo n.º 6
0
def get_node_data():
    count = db.session.query(func.count(Vm.id)) \
        .filter_by(state='running').scalar()
    n = (5 - count)
    user = User.query.filter_by(username=g.user.username).first()

    if request.method == "POST":
        counts = request.form['counts']
        name = request.form['node_name']
        hours_ = request.form['hours']
        key = request.form['pubkey']

        # Validating the hours and node counts
        if int(counts) > 5 or int(hours_) > 4 or int(counts) > n:
            flash('Please enter the valid data')
            logging.exception('User entered the invalid hours or counts value')
            return render_template('form.html', n=n, pubkey=user.pubkey)

        # checking if key is changed by user or not
        if key != user.pubkey:
            public_key = key
            # Validating the new SSH public key
            ssh = SSHKey(public_key, strict=True)
            try:
                ssh.parse()
            except (exceptions.InvalidKeyError, exceptions.MalformedDataError):
                logging.exception('Invalid or no key is passed')
                flash('Please upload a valid SSH key')
                return render_template('form.html', n=n, pubkey=user.pubkey)
        else:
            public_key = user.pubkey

        # Validating the machine label
        label = Vm.query.filter(Vm.state == 'running',
                                NodeRequest.node_name == name). \
            join(NodeRequest).first()
        if label is None:
            if re.match("^[a-zA-Z0-9_]+$", str(name)):
                node_request = NodeRequest(user_id=g.user.id,
                                           node_name=name,
                                           node_counts=counts,
                                           hours=hours_)
                db.session.add(node_request)
                db.session.commit()
                create_node.delay(counts, name, node_request.id, public_key)
                flash('Creating your machine. Please wait for a moment.')
                return redirect('/dashboard')
            else:
                flash('Invalid label entry.')
        else:
            flash('Machine label already exists.'
                  'Please choose different name.')
    else:
        if count >= 5:
            flash('All our available machines are in use.'
                  'Please wait until we have a slot available')
            return redirect('/dashboard')
        else:
            flash('You can request upto {} machines'.format(n))
    return render_template('form.html', n=n, pubkey=user.pubkey)
Ejemplo n.º 7
0
def ssh_key(key_string):
    import sshpubkeys
    from sshpubkeys import SSHKey

    key = SSHKey(key_string, strict_mode=True)
    try:
        key.parse()
    except sshpubkeys.exceptions.InvalidTypeException as err:
        print("Invalid/unrecognised key type:", err)
        exit(1)
    except sshpubkeys.exceptions.TooShortKeyException as err:
        print("Key too short:", err)
        exit(1)
    except sshpubkeys.exceptions.InvalidKeyLengthException as err:
        print("Key length too short or too long:", err)
        exit(1)
    except sshpubkeys.exceptions.TooLongKeyException as err:
        print("Key too long:", err)
        exit(1)
    except sshpubkeys.exceptions.MalformedDataException as err:
        print("Malformed data - key may be corrupted, truncated or include extra content:", err)
        exit(1)
    except sshpubkeys.exceptions.InvalidKeyException as err:
        print("Invalid key:", err)
        exit(1)
    except NotImplementedError as err:
        print("Invalid/unsupported key type:", err)
        exit(1)
Ejemplo n.º 8
0
 def get_agent_pubkeys():
     keys = self.session.agent.get_keys()
     keys_parsed = []
     for k in keys:
         ssh_pub_key = SSHKey("{} {}".format(k.get_name(), k.get_base64()))
         ssh_pub_key.parse()
         keys_parsed.append((k.get_name(), ssh_pub_key, k.can_sign()))
     return keys_parsed
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def valid_sshkey(public_key):
    ssh = SSHKey(public_key, strict=True)
    try:
        ssh.parse()
    except InvalidKeyError:
        return False
    except NotImplementedError:
        return False
    return True
Ejemplo n.º 11
0
def _validate_public_key(value):
    """
    Validates that the given key is a valid SSH public key.
    """
    ssh_key = SSHKey(value, parse_options=False, strict_mode=True)
    try:
        ssh_key.parse()
    except MalformedDataException as exc:
        raise ValidationError(exc.message, code='invalid-key')
    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
Ejemplo n.º 13
0
 def parse_ssh_key(key_string: str) -> SSHKey:
     try:
         key = SSHKey(key_string)
         key.parse()
         if not key.comment:
             raise ValueError("No name set. Please add a name to your key.")
         return key
     except InvalidKeyError as err:
         raise DatabaseError(f"Invalid SSH key: {err}")
Ejemplo n.º 14
0
def validate_public_key(path: str) -> Union[str, None]:
    """
    :param str path: path to the public key
    :return: str or None
    """
    pub_key = helpers.read_path(path)
    ssh = SSHPubKey(pub_key, strict=True)
    if ssh.parse() is None:
        return pub_key
Ejemplo n.º 15
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)
Ejemplo n.º 16
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
Ejemplo n.º 17
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:] + "="
Ejemplo n.º 18
0
def pubkey_to_fingerprint(pubkey): # done
    # converts pubkey in ssh-rsa BASE64SHIT to fingerprint
    try:
        msg_debug("Creating SSH key fingerprint")
        ssh = SSHKey(pubkey)
        fingerprint = ssh.hash()
        return fingerprint
    except Exception, e:
        msg_debug(e)
        msg_fail("ssh fingerprint generation failed.")
def pubkey_to_fingerprint(pubkey): # done
    # converts pubkey in ssh-rsa BASE64SHIT to fingerprint
    try:
        msg_debug("Creating SSH key fingerprint")
        ssh = SSHKey(pubkey)
        fingerprint = ssh.hash()
        return fingerprint
    except Exception, e:
        msg_debug(e)
        msg_fail("ssh fingerprint generation failed.")
Ejemplo n.º 20
0
 def clean_publish_ssh_key_for_authentication(self):
     public_key = self.cleaned_data['publish_ssh_key_for_authentication']
     if public_key:
         ssh_key = SSHKey(public_key)
         try:
             ssh_key.parse()
         except InvalidKeyError as err:
             raise forms.ValidationError("Invalid key: {}".format(err))
         except NotImplementedError as err:
             raise forms.ValidationError("Invalid key type: {}".format(err))
     return public_key
Ejemplo n.º 21
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:] + "="
Ejemplo n.º 22
0
def check_ssh_key(key_name: str) -> bool:
    client = boto3.client("ec2")
    response = client.describe_key_pairs(KeyNames=[key_name])
    fingerprint = dpath.util.get(response, "KeyPairs/0/KeyFingerprint")
    path = str(Path.home() / ".ssh" / f"{key_name}.pub")
    # try:
    with open(path, "r") as file:
        ssh = SSHKey(file.read(), strict=True)
        ssh.parse()
        assert (ssh.hash_md5() == fingerprint
                ), f"Local key {ssh.hash_md5()} does not match {fingerprint}"
        return True
Ejemplo n.º 23
0
    def generate_host_key(self) -> None:
        key_algorithm_class: Optional[Type[PKey]] = None
        key_algorithm_bits = None
        if self.key_algorithm == 'dss':
            key_algorithm_class = DSSKey
            key_algorithm_bits = self.key_length
        elif self.key_algorithm == 'rsa':
            key_algorithm_class = RSAKey
            key_algorithm_bits = self.key_length
        elif self.key_algorithm == 'ecdsa':
            key_algorithm_class = ECDSAKey
        elif self.key_algorithm == 'ed25519':
            key_algorithm_class = Ed25519Key
            if not self.key_file:
                logging.error(
                    "ed25519 requires a key file, please use also use --host-key parameter"
                )
                sys.exit(1)
        else:
            raise ValueError(
                f"host key algorithm '{self.key_algorithm}' not supported!")

        if not self.key_file:
            try:
                self._hostkey = key_algorithm_class.generate(
                    bits=key_algorithm_bits)  # type: ignore
            except ValueError as err:
                logging.error(str(err))
                raise KeyGenerationError()
        else:
            if not os.path.isfile(self.key_file):
                raise FileNotFoundError(
                    f"host key '{self.key_file}' file does not exist")
            for pkey_class in (RSAKey, DSSKey, ECDSAKey, Ed25519Key):
                try:
                    key = self._key_from_filepath(self.key_file, pkey_class,
                                                  None)
                    self._hostkey = key
                    break
                except SSHException:
                    pass
            else:
                logging.error('host key format not supported!')
                raise KeyGenerationError()

        ssh_pub_key = SSHKey(
            f"{self._hostkey.get_name()} {self._hostkey.get_base64()}")
        ssh_pub_key.parse()
        logging.info((
            f"{'loaded' if self.key_file else 'generated temporary'} {key_algorithm_class.__name__} key with {self._hostkey.get_bits()} bit length and fingerprints:\n"
            f"    {stylize(ssh_pub_key.hash_md5(), fg('light_blue') + attr('bold'))}\n"
            f"    {stylize(ssh_pub_key.hash_sha256(),fg('light_blue') + attr('bold'))}"
        ))
Ejemplo n.º 24
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
Ejemplo n.º 25
0
def majora_clean_ssh_key(ssh_key):
    if ssh_key:
        ssh_key = "".join(ssh_key.splitlines()).strip()
        key = SSHKey(ssh_key)
        try:
            key.parse()
        except Exception as e:
            raise forms.ValidationError("Unable to decode your key. Please ensure this is your public key and has been entered correctly.")

        if key.key_type != b'ssh-ed25519':
            raise forms.ValidationError("This system accepts ed25519 keys only.")

    return ssh_key
Ejemplo n.º 26
0
def validate_public_key(value):
    """Raise a ValidationError if the value is not a valid SSH public key, of type RSA"""
    try:
        key = SSHKey(value, strict=True)
        key.parse()
        key_type = key.key_type.decode()
        if key_type != "ssh-rsa":
            raise ValidationError(
                f"{key_type} keys are not supported. Please use RSA.")
    except (InvalidKeyError, NotImplementedError):
        raise ValidationError("Invalid SSH key")

    return value
Ejemplo n.º 27
0
def add_key():
    user = login_user
    payload = request.get_json()
    if not payload:
        return jsonify({
            'message': 'illegal params',
            'code': 104000,
        }), 400

    public_key = payload.get('public_key')
    name = payload.get('name')
    if not public_key:
        return jsonify({'message': 'invalid public key', 'code': 104000}), 400

    ssh = SSHKey(public_key)
    try:
        ssh.parse()
    except Exception as err:
        return jsonify({
            'message': 'invalid ssh key: {}'.format(str(err)),
            'code': 104001,
        }), 400

    fingerprint = ssh.hash_md5()
    existed = db.collection('public_keys').find_one(
        {'fingerprint': fingerprint})
    if existed:
        return jsonify({
            'message': 'ssh public key existed',
            'code': 104003
        }), 400

    options = {'vault_pass': config.vault.get('secret')}
    encode = Vault(options).encrypt_string(public_key)
    data = {
        'fingerprint': fingerprint,
        'user_id': user.get('user_id'),
        'content': encode,
        'name': name,
        'created_at': time.time()
    }

    result = db.collection('public_keys').insert_one(data)
    data['_id'] = result.inserted_id
    logger.info('add public_keys', extra={'record': data})

    return jsonify({
        'message': 'ok',
        'code': 0,
    })
Ejemplo n.º 28
0
    def get(self, request, *args, **kwargs):
        context = super(UpdateProfileView,
                        self).get_context_data(**kwargs)  # get context data

        # Add new record
        new_key = request.GET.get('new_key')
        if (new_key != None):
            if (len(new_key) > 0):
                try:
                    ssh = SSHKey(new_key)
                    ssh.parse()  # make sure the key is ok
                    key = SSHPublicKey(user=get_current_user(),
                                       comment=ssh.comment,
                                       key=new_key)
                    key.save()
                    self.key_status = 'Added new key with ID: ' + ssh.comment
                except:
                    self.key_status = 'Could not add key'

        # Updating existing record
        key_id = request.GET.get('key_id')
        update_key = request.GET.get('update_key')
        if ((update_key != None) and (key_id != None)):
            try:
                ssh = SSHKey(update_key)
                ssh.parse()  # make sure the key is ok
                key = SSHPublicKey.objects.get(id=key_id)
                key.key = update_key
                key.comment = ssh.comment
                key.save()
                self.key_status = 'Updated key with ID: ' + ssh.comment
            except:
                self.key_status = 'Could not update key'

        return super(UpdateProfileView, self).get(request, *args, **kwargs)
Ejemplo n.º 29
0
def validate_pks(key_list):
    err = 0
    msg = ""

    for k in key_list:
        if k == None:
            return 1, "No Key was passed in."
        ssh = SSHKey(k, strict_mode=True)
        try:
            ssh.parse()
        except InvalidKeyException as err:
            err += 1
            msg = msg + "\nInvalid SSH Public Key:" % k
    return err, msg
Ejemplo n.º 30
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
Ejemplo n.º 31
0
def get_pub_key_from_string(key: str) -> Optional[str]:
    if key is None or key == '':
        return None
    ssh_key = SSHKey(key, strict=True)
    try:
        ssh_key.parse()
    except InvalidKeyError as err:
        print(f'Invalid key: {err}')
        return None
    except NotImplementedError as err:
        print(f'Invalid key type: {err}')
        return None
    # Library can return some hash functions of the key
    # I'm just using it for checking - if valid key, return it
    return key
Ejemplo n.º 32
0
    def add_ssh_key(self, ssh_key, user_email):
        """ Adds ssh key to group """

        try:
            ssh_key = SSHKey(ssh_key.replace("\r\n", "\n"))
        except:
            return "Not a valid SSH key! Please ensure that everything from the .pub file has been copied."

        with open(self._ssh_file, "a+") as ssh_file:
            if ssh_key.key_comment is not None:
                commented_key = "{0} {1} {2} {3}\n".format(
                    ssh_key.key_type, ssh_key.key_content, ssh_key.key_comment, user_email
                )
            else:
                commented_key = "{0} {1} {2}\n".format(ssh_key.key_type, ssh_key.key_content, user_email)
            ssh_file.write(commented_key)
Ejemplo n.º 33
0
    def add(self, username, user_api, filename=None):
        """
        Add SSH public key to a user's profile.

        Args:
            username: Username to attach SSH public key to
            filename: Filename containing keys to add (optional)

        Raises:
            ldap3.core.exceptions.LDAPNoSuchAttributeResult:
                ldapPublicKey isn't attached to objectClass

        """
        keys = API.__get_keys(filename)
        user = user_api.find(username)[0]
        distinguished_name = user.entry_dn
        if 'ldapPublicKey' not in user.objectClass:
            raise ldap3.core.exceptions.LDAPNoSuchAttributeResult(
                'LDAP Public Key Object Class not found. ' +
                'Please ensure user was created correctly.')
        else:
            for key in list(set(keys)):  # prevents duplicate insertion
                print(key)
                try:
                    SSHKey(key).parse()
                except Exception as err:
                    raise err from None
                else:
                    operation = {'sshPublicKey': [(ldap3.MODIFY_ADD, [key])]}
                    self.client.modify(distinguished_name, operation)
Ejemplo n.º 34
0
def is_valid_ssh(ssh_key):
    try:
        SSHKey(ssh_key)
        return True
    except (InvalidKeyException, TooShortKeyException, TooLongKeyException,
            InvalidTypeException, MalformedDataException):
        return False
Ejemplo n.º 35
0
 def check_valid_option(self, option, parsed_option):
     ssh = SSHKey()
     parsed = ssh.parse_options(option)
     self.assertEqual(parsed, parsed_option)
Ejemplo n.º 36
0
def verify_openssh_public_key(s):
    try:
        ssh = SSHKey(s)
        return (ssh.bits >= SECURE_KEY_BITS and ssh.hash())
    except:
        return False