def command(self): config = self.session.config policyttl = self.args[1] if (len(self.args) > 1) else 'cache-only:-1' if 'policy-ttl' in self.data: policyttl = self.data['policy-ttl'][0] if ':' in policyttl: policy, ttl = policyttl.split(':') else: policy, ttl = policyttl, -1 if 'policy' in self.data: policy = self.data['policy'][0] if 'ttl' in self.data: ttl = self.data['policy'][0] ttl = float(ttl) fingerprint = info = None keyid = self.args[0] if self.args else self.data.get('id', [None])[0] if keyid: fingerprint, info = self._lookup_key(keyid) result = {'key': info} else: result = {'keylist': self._gnupg().list_secret_keys()} if self.data.get('_method', None) == 'GET': password = False return self._success(_('Enter your password'), result) assert(keyid is not None and fingerprint is not None) def happy(msg): # Fun side effect: changing the passphrase invalidates the message cache import mailpile.mailutils mailpile.mailutils.ClearParseCache(full=True) redirect = self.data.get('redirect', [None])[0] if redirect: raise UrlRedirectException(redirect) return self._success(msg, result) if policy == 'forget': if fingerprint in config.passphrases: del config.passphrases[fingerprint] if fingerprint in config.secrets: config.secrets[fingerprint].password = '' return happy(_('Password forgotten!')) if policy == 'fail': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = { 'policy': policy } return happy(_('Password will never be stored')) if self.data.get('_method', None) == 'POST': password = self.data.get('password', [None])[0] else: password = self.session.ui.get_password(_('Enter your password:'******' ') if policy == 'store': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = { 'password': password, 'policy': policy } return happy(_('Password stored permanently')) elif policy == 'cache-only' and password: sps = SecurePassphraseStorage(password) if ttl > 0: sps.expiration = time.time() + ttl config.passphrases[fingerprint] = sps if fingerprint.lower() in config.secrets: del config.secrets[fingerprint.lower()] return happy(_('Password stored temporarily')) else: return self._error(_('Invalid password policy!'), result)
def command(self): config = self.session.config policyttl = self.args[1] if (len(self.args) > 1) else 'cache-only:-1' if 'policy-ttl' in self.data: policyttl = self.data['policy-ttl'][0] if ':' in policyttl: policy, ttl = policyttl.split(':') else: policy, ttl = policyttl, -1 if 'policy' in self.data: policy = self.data['policy'][0] if 'ttl' in self.data: ttl = self.data['policy'][0] ttl = float(ttl) fingerprint = info = None keyid = self.args[0] if self.args else self.data.get('id', [None])[0] if keyid: fingerprint, info = self._lookup_key(keyid) result = {'key': info} else: result = {'keylist': self._gnupg().list_secret_keys()} if self.data.get('_method', None) == 'GET': password = False return self._success(_('Enter your password'), result) assert (keyid is not None and fingerprint is not None) def happy(msg): # Fun side effect: changing the passphrase invalidates the message cache import mailpile.mailutils mailpile.mailutils.ClearParseCache(full=True) redirect = self.data.get('redirect', [None])[0] if redirect: raise UrlRedirectException(redirect) return self._success(msg, result) if policy == 'forget': if fingerprint in config.passphrases: del config.passphrases[fingerprint] if fingerprint in config.secrets: config.secrets[fingerprint].password = '' return happy(_('Password forgotten!')) if policy == 'fail': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = {'policy': policy} return happy(_('Password will never be stored')) if self.data.get('_method', None) == 'POST': password = self.data.get('password', [None])[0] else: password = self.session.ui.get_password( _('Enter your password:'******' ') if policy == 'store': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = { 'password': password, 'policy': policy } return happy(_('Password stored permanently')) elif policy == 'cache-only' and password: sps = SecurePassphraseStorage(password) if ttl > 0: sps.expiration = time.time() + ttl config.passphrases[fingerprint] = sps if fingerprint.lower() in config.secrets: del config.secrets[fingerprint.lower()] return happy(_('Password stored temporarily')) else: return self._error(_('Invalid password policy!'), result)
def command(self): config = self.session.config policyttl = self.args[1] if (len(self.args) > 1) else 'cache-only:-1' is_locked = self.data.get('is_locked', [0])[0] if 'policy-ttl' in self.data: policyttl = self.data['policy-ttl'][0] if ':' in policyttl: policy, ttl = policyttl.split(':') else: policy, ttl = policyttl, -1 if 'policy' in self.data: policy = self.data['policy'][0] if 'ttl' in self.data: ttl = self.data['policy'][0] ttl = float(ttl) fingerprint = info = account = keyid = None which = self.args[0] if self.args else self.data.get('id', [None])[0] if which and '@' in which: account = which else: keyid = which if not account and not keyid: msid = self.data.get('mailsource', [None])[0] if msid: account = self._get_account(config.sources[msid]) mrid = self.data.get('mailroute', [None])[0] if mrid: account = self._get_account(config.routes[mrid]) fingerprint, result = self._prepare_result( account=account, keyid=keyid, is_locked=is_locked) if policy in ('display', 'unprotect'): pass_prompt = _('Enter your Mailpile password') pass_check = self._check_master_password else: pass_prompt = _('Enter your password') pass_check = self._check_password if self.data.get('_method', None) == 'GET': return self._success(pass_prompt, result) safe_assert(fingerprint is not None) fingerprint = fingerprint.lower() if fingerprint in config.secrets: if config.secrets[fingerprint].policy == 'protect': if policy not in ('unprotect', 'display'): result['error'] = _('That key is managed by Mailpile,' ' it cannot be changed directly.') return self._error(_('Protected secret'), result=result) if self.data.get('_method', None) == 'POST': password = self.data.get('password', [None])[0] update_ms = self.data.get('update_mailsources', [False])[0] update_mr = self.data.get('update_mailroutes', [False])[0] else: password = self.session.ui.get_password(pass_prompt + ': ') update_ms = update_mr = (account is not None) if update_ms or update_mr: safe_assert(account is not None) if not pass_check(password, account=account, fingerprint=fingerprint): result['error'] = _('Password incorrect! Try again?') return self._error(_('Incorrect password'), result=result) def _account_matches(cfg): return (account == cfg.username or account == '%s@%s' % (cfg.username, cfg.host)) def happy(msg, refresh=True, changed=True): if changed: # Fun side effect: changing the passphrase invalidates the # message cache import mailpile.mailutils.emails mailpile.mailutils.emails.ClearParseCache(full=True) indirect_pwd = '_SECRET_:%s:%s' % (fingerprint, time.time()) if update_ms: for msid, source in config.sources.iteritems(): if _account_matches(source): source.password = indirect_pwd if update_mr: for msid, route in config.routes.iteritems(): if _account_matches(route): route.password = indirect_pwd self._background_save(config=True) redirect = self.data.get('redirect', [None])[0] if redirect: raise UrlRedirectException(redirect) result['op_completed'] = policy if refresh: fp, r = self._prepare_result(account=account, keyid=keyid) result.update(r) return self._success(msg, result) if policy == 'display': if fingerprint in config.passphrases: pwd = config.passphrases[fingerprint].get_passphrase() elif fingerprint in config.secrets: pwd = config.secrets[fingerprint].password else: return self._error(_('No password found'), result=result) result['stored_password'] = pwd return happy(_('Retrieved stored password'), refresh=False, changed=False) if policy == 'forget': if fingerprint in config.passphrases: del config.passphrases[fingerprint] if fingerprint in config.secrets: config.secrets[fingerprint] = {'policy': 'fail'} del config.secrets[fingerprint] return happy(_('Password forgotten!')) if policy == 'fail': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = {'policy': policy} return happy(_('Password will never be stored')) if policy == 'store': if fingerprint in config.passphrases: del config.passphrases[fingerprint] config.secrets[fingerprint] = { 'password': password, 'policy': policy} return happy(_('Password remembered!')) elif policy == 'cache-only' and password: sps = SecurePassphraseStorage(password) if ttl > 0: sps.expiration = time.time() + ttl config.passphrases[fingerprint] = sps if fingerprint in config.secrets: config.secrets[fingerprint] = {'policy': 'fail'} del config.secrets[fingerprint] return happy(_('The password has been stored temporarily')) else: return self._error(_('Invalid password policy'), result=result)