def _check_password(self, password, account=None, fingerprint=None): if account: # We're going to keep punting on this for a while... return True elif fingerprint: sps = SecurePassphraseStorage(password) gpg = GnuPG(self.session.config) status, sig = gpg.sign('OK', fromkey=fingerprint, passphrase=sps) return (status == 0) else: return True
def _do_login(self, user, password, load_index=False, redirect=False): session, config = self.session, self.session.config session_id = self.session.ui.html_variables.get('http_session') # This prevents folks from sending us a DEFAULT user (upper case), # which is an internal security bypass below. user = user and user.lower() if not user: from mailpile.config import SecurePassphraseStorage sps = SecurePassphraseStorage(password) password = '' try: # Verify the passphrase gpg = GnuPG(use_agent=False) if gpg.is_available(): gpg.passphrase = sps.get_reader() assert(gpg.sign('Sign This!')[0] == 0) # Store the varified passphrase config.gnupg_passphrase.data = sps.data # Load the config and index, if necessary if not config.loaded_config: self._config() if load_index: self._idx() else: pass # FIXME: Start load in background session.ui.debug('Good passphrase for %s' % session_id) return self._logged_in(redirect=redirect) else: session.ui.debug('No GnuPG, checking DEFAULT user') # No GnuPG, see if there is a DEFAULT user in the config user = '******' except (AssertionError, IOError): session.ui.debug('Bad passphrase for %s' % session_id) return self._error(_('Invalid passphrase, please try again')) if user in config.logins or user == 'DEFAULT': # FIXME: Salt and hash the password, check if it matches # the entry in our user/password list (TODO). # NOTE: This hack effectively disables auth without GnUPG if user == 'DEFAULT': session.ui.debug('FIXME: Unauthorized login allowed') return self._logged_in(redirect=redirect) raise Exception('FIXME') self._error(_('Incorrect username or password'))
def VerifyAndStorePassphrase(config, passphrase=None, sps=None): if passphrase and not sps: from mailpile.config import SecurePassphraseStorage sps = SecurePassphraseStorage(passphrase) passphrase = 'this probably does not really overwrite :-( ' assert(sps is not None) gpg = GnuPG(use_agent=False) if gpg.is_available(): gpg.passphrase = sps.get_reader() gpgr = config.prefs.gpg_recipient gpgr = gpgr if (gpgr not in (None, '', '!CREATE')) else None assert(gpg.sign('Sign This!', fromkey=gpgr)[0] == 0) return sps
def VerifyAndStorePassphrase(config, passphrase=None, sps=None, key=None): if passphrase and not sps: from mailpile.config import SecurePassphraseStorage sps = SecurePassphraseStorage(passphrase) passphrase = 'this probably does not really overwrite :-( ' assert (sps is not None) gpg = GnuPG(use_agent=False) if gpg.is_available(): gpg.passphrase = sps.get_reader() gpgr = config.prefs.gpg_recipient gpgr = key or (gpgr if (gpgr not in (None, '', '!CREATE')) else None) assert (gpg.sign('Sign This!', fromkey=gpgr)[0] == 0) return sps
def VerifyAndStorePassphrase(config, passphrase=None, sps=None, key=None): if passphrase and not sps: from mailpile.config import SecurePassphraseStorage sps = SecurePassphraseStorage(passphrase) passphrase = 'this probably does not really overwrite :-( ' assert (sps is not None) gpg = GnuPG(None, use_agent=False) if gpg.is_available(): gpg.passphrase = sps.get_reader() gpgr = config.prefs.gpg_recipient gpgr = key or (gpgr if (gpgr not in (None, '', '!CREATE')) else None) assert (gpg.sign('Sign This!', fromkey=gpgr)[0] == 0) # Fun side effect: changing the passphrase invalidates the message cache import mailpile.mailutils mailpile.mailutils.ClearParseCache(full=True) return sps
def VerifyAndStorePassphrase(config, passphrase=None, sps=None, key=None): if passphrase and not sps: from mailpile.config import SecurePassphraseStorage sps = SecurePassphraseStorage(passphrase) passphrase = 'this probably does not really overwrite :-( ' assert(sps is not None) gpg = GnuPG(None, use_agent=False) if gpg.is_available(): gpg.passphrase = sps.get_reader() gpgr = config.prefs.gpg_recipient gpgr = key or (gpgr if (gpgr not in (None, '', '!CREATE')) else None) assert(gpg.sign('Sign This!', fromkey=gpgr)[0] == 0) # Fun side effect: changing the passphrase invalidates the message cache import mailpile.mailutils mailpile.mailutils.ClearParseCache(full=True) return sps
def PrepareMail(config, mailobj, sender=None, rcpts=None): if not sender or not rcpts: tree = mailobj.get_message_tree() sender = sender or tree['headers_lc']['from'] if not rcpts: rcpts = ExtractEmails(tree['headers_lc'].get('to', '')) rcpts += ExtractEmails(tree['headers_lc'].get('cc', '')) rcpts += ExtractEmails(tree['headers_lc'].get('bcc', '')) if not rcpts: raise NoRecipientError() rcpts += [sender] # Cleanup... sender = ExtractEmails(sender)[0] sender_keyid = None if config.prefs.openpgp_header: try: gnupg = GnuPG() seckeys = dict([(x["email"], y["fingerprint"]) for y in gnupg.list_secret_keys().values() for x in y["uids"]]) sender_keyid = seckeys[sender] except: pass rcpts, rr = [sender], rcpts for r in rr: for e in ExtractEmails(r): if e not in rcpts: rcpts.append(e) msg = copy.deepcopy(mailobj.get_msg()) # Remove headers we don't want to expose for bcc in ('bcc', 'Bcc', 'BCc', 'BCC', 'BcC', 'bcC'): if bcc in msg: del msg[bcc] if 'date' not in msg: msg['Date'] = email.utils.formatdate() if sender_keyid and config.prefs.openpgp_header: msg["OpenPGP"] = "id=%s; preference=%s" % (sender_keyid, config.prefs.openpgp_header) # Sign and encrypt signatureopt = bool(int(tree['headers_lc'].get('do_sign', 0))) encryptopt = bool(int(tree['headers_lc'].get('do_encrypt', 0))) gnupg = GnuPG() if signatureopt: signingstring = MessageAsString(msg) signature = gnupg.sign(signingstring, fromkey=sender, armor=True) # FIXME: Create attachment, attach signature. if signature[0] == 0: # sigblock = MIMEMultipart(_subtype="signed", # protocol="application/pgp-signature") # sigblock.attach(msg) msg.set_type("multipart/signed") msg.set_param("micalg", "pgp-sha1") # need to find this! msg.set_param("protocol", "application/pgp-signature") sigblock = MIMEText(str(signature[1]), _charset=None) sigblock.set_type("application/pgp-signature") sigblock.set_param("name", "signature.asc") sigblock.add_header("Content-Description", "OpenPGP digital signature") sigblock.add_header("Content-Disposition", "attachment; filename=\"signature.asc\"") msg.attach(sigblock) else: # Raise stink about signing having failed. pass #print signature #if encryptopt: # encrypt_to = tree['headers_lc'].get('encrypt_to') # newmsg = gnupg.encrypt(msg.as_string(), encrypt_to) # # TODO: Replace unencrypted message # When a mail has been signed or encrypted, it should be saved as such. del(msg["do_sign"]) del(msg["do_encrypt"]) del(msg["encrypt_to"]) return (sender, set(rcpts), msg)