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)
def is_valid_ssh_key(ssh_key): ssh = SSHKey(ssh_key) try: ssh.parse() except (InvalidKeyException, NotImplementedError): return False return True
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)
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
def validate_key(self, key): try: ssh = SSHKey(key) ssh.parse() return ssh except: return False
async def validate_ssh(ssh_pub: str): ssh = SSHKey(ssh_pub) try: ssh.parse() return True except: return False
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)
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)
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
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)
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
def valid_sshkey(public_key): ssh = SSHKey(public_key, strict=True) try: ssh.parse() except InvalidKeyError: return False except NotImplementedError: return False return True
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}")
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)
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:] + "="
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:", ""), )
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:] + "="
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
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'))}" ))
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
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
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
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
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
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, })
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
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()
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
def validate_ssh_key(ssh_key): """ Validates an ssh_key argument. """ result = None if ssh_key is None: result = True # If None we don't care if not isinstance(ssh_key, str): result = False ssh_key_object = SSHKey(ssh_key, skip_option_parsing=True, disallow_options=True) try: ssh_key_object.parse() result = True except Exception: result = False return result
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)