def set_or_update_passphrase(passphrase: Optional[str], current_passphrase: Optional[str]) -> bool: # Prompt for the current passphrase, if necessary if Keychain.has_master_passphrase(): # Try the default passphrase first if using_default_passphrase(): current_passphrase = default_passphrase() if not current_passphrase: try: current_passphrase = obtain_current_passphrase( "Current Passphrase: ") except Exception as e: print(f"Unable to confirm current passphrase: {e}") sys.exit(1) success = False new_passphrase = passphrase try: # Prompt for the new passphrase, if necessary if not new_passphrase: new_passphrase = prompt_for_new_passphrase() if new_passphrase == current_passphrase: raise ValueError("passphrase is unchanged") Keychain.set_master_passphrase(current_passphrase=current_passphrase, new_passphrase=new_passphrase) success = True except Exception as e: print(f"Unable to set or update passphrase: {e}") success = False return success
def remove_passphrase(current_passphrase: Optional[str]) -> bool: """ Removes the user's keyring passphrase. The keyring will be re-encrypted to the default passphrase. """ success = False if not Keychain.has_master_passphrase() or using_default_passphrase(): print("Passphrase is not currently set") success = False else: # Try the default passphrase first if using_default_passphrase(): current_passphrase = default_passphrase() # Prompt for the current passphrase, if necessary if not current_passphrase: try: current_passphrase = obtain_current_passphrase( "Current Passphrase: ") except Exception as e: print(f"Unable to confirm current passphrase: {e}") success = False if current_passphrase: try: Keychain.remove_master_passphrase(current_passphrase) success = True except Exception as e: print(f"Unable to remove passphrase: {e}") success = False return success
def initialize_passphrase() -> None: if Keychain.has_master_passphrase(): print("Keyring is already protected by a passphrase") print( "\nUse 'chia passphrase set' or 'chia passphrase remove' to update or remove your passphrase" ) sys.exit(1) # We'll rely on Keyring initialization to leverage the cached passphrase for # bootstrapping the keyring encryption process print("Setting keyring passphrase") passphrase: Optional[str] = None # save_passphrase indicates whether the passphrase should be saved in the # macOS Keychain or Windows Credential Manager save_passphrase: bool = False if Keychain.has_cached_passphrase(): passphrase = Keychain.get_cached_master_passphrase() if not passphrase or passphrase == default_passphrase(): passphrase, save_passphrase = prompt_for_new_passphrase() Keychain.set_master_passphrase(current_passphrase=None, new_passphrase=passphrase, save_passphrase=save_passphrase)
async def remove_keyring_passphrase(self, request: Dict[str, Any]) -> Dict[str, Any]: success: bool = False error: Optional[str] = None current_passphrase: Optional[str] = None if not Keychain.has_master_passphrase(): return {"success": False, "error": "passphrase not set"} current_passphrase = request.get("current_passphrase", None) if type(current_passphrase) is not str: return {"success": False, "error": "missing current_passphrase"} try: Keychain.remove_master_passphrase(current_passphrase) except KeyringCurrentPassphaseIsInvalid: error = "current passphrase is invalid" except Exception as e: tb = traceback.format_exc() self.log.error(f"Failed to remove keyring passphrase: {e} {tb}") else: success = True # Inform the GUI of keyring status changes self.keyring_status_changed(await self.keyring_status(), "wallet_ui") response: Dict[str, Any] = {"success": success, "error": error} return response
async def set_keyring_passphrase(self, request: Dict[str, Any]): success: bool = False error: Optional[str] = None current_passphrase: Optional[str] = None new_passphrase: Optional[str] = None if using_default_passphrase(): current_passphrase = default_passphrase() if Keychain.has_master_passphrase() and not current_passphrase: current_passphrase = request.get("current_passphrase", None) if type(current_passphrase) is not str: return {"success": False, "error": "missing current_passphrase"} new_passphrase = request.get("new_passphrase", None) if type(new_passphrase) is not str: return {"success": False, "error": "missing new_passphrase"} try: assert new_passphrase is not None # mypy, I love you Keychain.set_master_passphrase(current_passphrase, new_passphrase, allow_migration=False) except KeyringRequiresMigration: error = "keyring requires migration" except KeyringCurrentPassphaseIsInvalid: error = "current passphrase is invalid" except Exception as e: tb = traceback.format_exc() self.log.error(f"Failed to set keyring passphrase: {e} {tb}") else: success = True response: Dict[str, Any] = {"success": success, "error": error} return response
def get_current_passphrase() -> Optional[str]: if not Keychain.has_master_passphrase(): return None current_passphrase = None if using_default_passphrase(): current_passphrase = default_passphrase() else: try: current_passphrase = obtain_current_passphrase() except Exception as e: print(f"Unable to confirm current passphrase: {e}") raise e return current_passphrase
def update_passphrase_hint(hint: Optional[str] = None) -> bool: updated: bool = False if Keychain.has_master_passphrase() is False or using_default_passphrase(): print( "Updating the passphrase hint requires that a passphrase has been set" ) else: current_passphrase: Optional[str] = get_current_passphrase() if current_passphrase is None: print("Keyring is not passphrase-protected") else: # Set or remove the passphrase hint Keychain.set_master_passphrase_hint(current_passphrase, hint) updated = True return updated
def initialize_passphrase() -> None: if Keychain.has_master_passphrase(): print("Keyring is already protected by a passphrase") print( "\nUse 'chia passphrase set' or 'chia passphrase remove' to update or remove your passphrase" ) sys.exit(1) # We'll rely on Keyring initialization to leverage the cached passphrase for # bootstrapping the keyring encryption process print("Setting keyring passphrase") passphrase = None if Keychain.has_cached_passphrase(): passphrase = Keychain.get_cached_master_passphrase() if not passphrase or passphrase == default_passphrase(): passphrase = prompt_for_new_passphrase() Keychain.set_master_passphrase(current_passphrase=None, new_passphrase=passphrase)
async def set_keyring_passphrase(self, request: Dict[str, Any]) -> Dict[str, Any]: success: bool = False error: Optional[str] = None current_passphrase: Optional[str] = None new_passphrase: Optional[str] = None if using_default_passphrase(): current_passphrase = default_passphrase() if Keychain.has_master_passphrase() and not current_passphrase: current_passphrase = request.get("current_passphrase", None) if type(current_passphrase) is not str: return {"success": False, "error": "missing current_passphrase"} new_passphrase = request.get("new_passphrase", None) if type(new_passphrase) is not str: return {"success": False, "error": "missing new_passphrase"} if not Keychain.passphrase_meets_requirements(new_passphrase): return {"success": False, "error": "passphrase doesn't satisfy requirements"} try: assert new_passphrase is not None # mypy, I love you Keychain.set_master_passphrase(current_passphrase, new_passphrase, allow_migration=False) except KeyringRequiresMigration: error = "keyring requires migration" except KeyringCurrentPassphaseIsInvalid: error = "current passphrase is invalid" except Exception as e: tb = traceback.format_exc() self.log.error(f"Failed to set keyring passphrase: {e} {tb}") else: success = True # Inform the GUI of keyring status changes self.keyring_status_changed(await self.keyring_status(), "wallet_ui") response: Dict[str, Any] = {"success": success, "error": error} return response
def using_default_passphrase() -> bool: if not Keychain.has_master_passphrase(): return False return Keychain.master_passphrase_is_valid(default_passphrase())