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 setup_command(self, session): # Stop the workers... want_daemons = session.config.cron_worker is not None session.config.stop_workers() # Perform any required migrations Migrate(session).run(before_setup=True, after_setup=False) # Create local mailboxes session.config.open_local_mailbox(session) # Create standard tags and filters created = [] for t in self.TAGS: if not session.config.get_tag_id(t): AddTag(session, arg=[t]).run(save=False) created.append(t) session.config.get_tag(t).update(self.TAGS[t]) for stype, statuses in (('sig', SignatureInfo.STATUSES), ('enc', EncryptionInfo.STATUSES)): for status in statuses: tagname = 'mp_%s-%s' % (stype, status) if not session.config.get_tag_id(tagname): AddTag(session, arg=[tagname]).run(save=False) created.append(tagname) session.config.get_tag(tagname).update({ 'type': 'attribute', 'display': 'invisible', 'label': False, }) if 'New' in created: session.ui.notify(_('Created default tags')) # Import all the basic plugins for plugin in PLUGINS: if plugin not in session.config.sys.plugins: session.config.sys.plugins.append(plugin) try: # If spambayes is not installed, this will fail import mailpile.plugins.autotag_sb if 'autotag_sb' not in session.config.sys.plugins: session.config.sys.plugins.append('autotag_sb') session.ui.notify(_('Enabling spambayes autotagger')) except ImportError: session.ui.warning(_('Please install spambayes ' 'for super awesome spam filtering')) session.config.save() session.config.load(session) vcard_importers = session.config.prefs.vcard.importers if not vcard_importers.gravatar: vcard_importers.gravatar.append({'active': True}) session.ui.notify(_('Enabling gravatar image importer')) gpg_home = os.path.expanduser('~/.gnupg') if os.path.exists(gpg_home) and not vcard_importers.gpg: vcard_importers.gpg.append({'active': True, 'gpg_home': gpg_home}) session.ui.notify(_('Importing contacts from GPG keyring')) if ('autotag_sb' in session.config.sys.plugins and len(session.config.prefs.autotag) == 0): session.config.prefs.autotag.append({ 'match_tag': 'spam', 'unsure_tag': 'maybespam', 'tagger': 'spambayes', 'trainer': 'spambayes' }) session.config.prefs.autotag[0].exclude_tags[0] = 'ham' # Assumption: If you already have secret keys, you want to # use the associated addresses for your e-mail. # If you don't already have secret keys, you should have # one made for you, if GnuPG is available. # If GnuPG is not available, you should be warned. gnupg = GnuPG() accepted_keys = [] if gnupg.is_available(): keys = gnupg.list_secret_keys() for key, details in keys.iteritems(): # Ignore revoked/expired keys. if ("revocation-date" in details and details["revocation-date"] <= date.today().strftime("%Y-%m-%d")): continue accepted_keys.append(key) for uid in details["uids"]: if "email" not in uid or uid["email"] == "": continue if uid["email"] in [x["email"] for x in session.config.profiles]: # Don't set up the same e-mail address twice. continue # FIXME: Add route discovery mechanism. profile = { "email": uid["email"], "name": uid["name"], } session.config.profiles.append(profile) if (not session.config.prefs.gpg_recipient and details["capabilities_map"][0]["encrypt"]): session.config.prefs.gpg_recipient = key session.ui.notify(_('Encrypting config to %s') % key) if session.config.prefs.crypto_policy == 'none': session.config.prefs.crypto_policy = 'openpgp-sign' if len(accepted_keys) == 0: # FIXME: Start background process generating a key once a user # has supplied a name and e-mail address. pass else: session.ui.warning(_('Oh no, PGP/GPG support is unavailable!')) if (session.config.prefs.gpg_recipient and not (self._idx() and self._idx().INDEX) and not session.config.prefs.obfuscate_index): randcrap = sha512b64(open('/dev/urandom').read(1024), session.config.prefs.gpg_recipient, '%s' % time.time()) session.config.prefs.obfuscate_index = randcrap session.config.prefs.index_encrypted = True session.ui.notify(_('Obfuscating search index and enabling ' 'indexing of encrypted e-mail. ')) # Perform any required migrations Migrate(session).run(before_setup=False, after_setup=True) session.config.save() session.config.prepare_workers(session, daemons=want_daemons) return self._success(_('Performed initial Mailpile setup'))
def command(self): session = self.session if session.config.sys.lockdown: return self._error(_('In lockdown, doing nothing.')) # Perform any required migrations Migrate(session).run(before_setup=True, after_setup=False) # Create local mailboxes session.config.open_local_mailbox(session) # Create standard tags and filters created = [] for t in self.TAGS: if not session.config.get_tag_id(t): AddTag(session, arg=[t]).run(save=False) created.append(t) session.config.get_tag(t).update(self.TAGS[t]) for stype, statuses in (('sig', SignatureInfo.STATUSES), ('enc', EncryptionInfo.STATUSES)): for status in statuses: tagname = 'mp_%s-%s' % (stype, status) if not session.config.get_tag_id(tagname): AddTag(session, arg=[tagname]).run(save=False) created.append(tagname) session.config.get_tag(tagname).update({ 'type': 'attribute', 'display': 'invisible', 'label': False, }) if 'New' in created: session.ui.notify(_('Created default tags')) # Import all the basic plugins for plugin in PLUGINS: if plugin not in session.config.sys.plugins: session.config.sys.plugins.append(plugin) try: # If spambayes is not installed, this will fail import mailpile.plugins.autotag_sb if 'autotag_sb' not in session.config.sys.plugins: session.config.sys.plugins.append('autotag_sb') session.ui.notify(_('Enabling spambayes autotagger')) except ImportError: session.ui.warning( _('Please install spambayes ' 'for super awesome spam filtering')) session.config.save() session.config.load(session) vcard_importers = session.config.prefs.vcard.importers if not vcard_importers.gravatar: vcard_importers.gravatar.append({'active': True}) session.ui.notify(_('Enabling gravatar image importer')) gpg_home = os.path.expanduser('~/.gnupg') if os.path.exists(gpg_home) and not vcard_importers.gpg: vcard_importers.gpg.append({'active': True, 'gpg_home': gpg_home}) session.ui.notify(_('Importing contacts from GPG keyring')) if ('autotag_sb' in session.config.sys.plugins and len(session.config.prefs.autotag) == 0): session.config.prefs.autotag.append({ 'match_tag': 'spam', 'unsure_tag': 'maybespam', 'tagger': 'spambayes', 'trainer': 'spambayes' }) session.config.prefs.autotag[0].exclude_tags[0] = 'ham' # Assumption: If you already have secret keys, you want to # use the associated addresses for your e-mail. # If you don't already have secret keys, you should have # one made for you, if GnuPG is available. # If GnuPG is not available, you should be warned. gnupg = GnuPG() accepted_keys = [] if gnupg.is_available(): keys = gnupg.list_secret_keys() for key, details in keys.iteritems(): # Ignore revoked/expired keys. if ("revocation-date" in details and details["revocation-date"] <= date.today().strftime("%Y-%m-%d")): continue accepted_keys.append(key) for uid in details["uids"]: if "email" not in uid or uid["email"] == "": continue if uid["email"] in [ x["email"] for x in session.config.profiles ]: # Don't set up the same e-mail address twice. continue # FIXME: Add route discovery mechanism. profile = { "email": uid["email"], "name": uid["name"], } session.config.profiles.append(profile) if (not session.config.prefs.gpg_recipient and details["capabilities_map"][0]["encrypt"]): session.config.prefs.gpg_recipient = key session.ui.notify(_('Encrypting config to %s') % key) if session.config.prefs.crypto_policy == 'none': session.config.prefs.crypto_policy = 'openpgp-sign' if len(accepted_keys) == 0: # FIXME: Start background process generating a key once a user # has supplied a name and e-mail address. pass else: session.ui.warning(_('Oh no, PGP/GPG support is unavailable!')) if (session.config.prefs.gpg_recipient and not (self._idx() and self._idx().INDEX) and not session.config.prefs.obfuscate_index): randcrap = sha512b64( open('/dev/urandom').read(1024), session.config.prefs.gpg_recipient, '%s' % time.time()) session.config.prefs.obfuscate_index = randcrap session.config.prefs.index_encrypted = True session.ui.notify( _('Obfuscating search index and enabling ' 'indexing of encrypted e-mail. ')) # Perform any required migrations Migrate(session).run(before_setup=False, after_setup=True) session.config.save() return self._success(_('Performed initial Mailpile setup'))
def setup_command(self, session, do_gpg_stuff=False): do_gpg_stuff = do_gpg_stuff or ('do_gpg_stuff' in self.args) # Stop the workers... want_daemons = session.config.cron_worker is not None session.config.stop_workers() # Perform any required migrations Migrate(session).run(before_setup=True, after_setup=False) # Basic app config, tags, plugins, etc. self.basic_app_config(session, save_and_update_workers=False, want_daemons=want_daemons) # Assumption: If you already have secret keys, you want to # use the associated addresses for your e-mail. # If you don't already have secret keys, you should have # one made for you, if GnuPG is available. # If GnuPG is not available, you should be warned. if do_gpg_stuff: gnupg = GnuPG(None) accepted_keys = [] if gnupg.is_available(): keys = gnupg.list_secret_keys() for key, details in keys.iteritems(): # Ignore revoked/expired keys. if ("revocation-date" in details and details["revocation-date"] <= date.today().strftime("%Y-%m-%d")): continue accepted_keys.append(key) for uid in details["uids"]: if "email" not in uid or uid["email"] == "": continue if uid["email"] in [x["email"] for x in session.config.profiles]: # Don't set up the same e-mail address twice. continue # FIXME: Add route discovery mechanism. profile = { "email": uid["email"], "name": uid["name"], } session.config.profiles.append(profile) if (session.config.prefs.gpg_recipient in (None, '', '!CREATE') and details["capabilities_map"][0]["encrypt"]): session.config.prefs.gpg_recipient = key session.ui.notify(_('Encrypting config to %s') % key) if session.config.prefs.crypto_policy == 'none': session.config.prefs.crypto_policy = 'openpgp-sign' if len(accepted_keys) == 0: # FIXME: Start background process generating a key once a user # has supplied a name and e-mail address. pass else: session.ui.warning(_('Oh no, PGP/GPG support is unavailable!')) # If we have a GPG key, but no master key, create it self.make_master_key() # Perform any required migrations Migrate(session).run(before_setup=False, after_setup=True) session.config.save() session.config.prepare_workers(session, daemons=want_daemons) return self._success(_('Performed initial Mailpile setup'))
def command(self): session = self.session if session.config.sys.lockdown: session.ui.warning(_("In lockdown, doing nothing.")) return False # Create local mailboxes session.config.open_local_mailbox(session) # Create standard tags and filters created = [] for t in self.TAGS: if not session.config.get_tag_id(t): AddTag(session, arg=[t]).run(save=False) created.append(t) session.config.get_tag(t).update(self.TAGS[t]) for stype, statuses in (("sig", SignatureInfo.STATUSES), ("enc", EncryptionInfo.STATUSES)): for status in statuses: tagname = "mp_%s-%s" % (stype, status) if not session.config.get_tag_id(tagname): AddTag(session, arg=[tagname]).run(save=False) created.append(tagname) session.config.get_tag(tagname).update({"type": "attribute", "display": "invisible", "label": False}) if "New" in created: Filter(session, arg=["new", "@incoming", "+Inbox", "+New", "Incoming mail filter"]).run(save=False) session.ui.notify(_("Created default tags")) # Import all the basic plugins for plugin in PLUGINS: if plugin not in session.config.sys.plugins: session.config.sys.plugins.append(plugin) try: # If spambayes is not installed, this will fail import mailpile.plugins.autotag_sb if "autotag_sb" not in session.config.sys.plugins: session.config.sys.plugins.append("autotag_sb") session.ui.notify(_("Enabling spambayes autotagger")) except ImportError: session.ui.warning(_("Please install spambayes " "for super awesome spam filtering")) session.config.save() session.config.load(session) vcard_importers = session.config.prefs.vcard.importers if not vcard_importers.gravatar: vcard_importers.gravatar.append({"active": True}) session.ui.notify(_("Enabling gravatar image importer")) gpg_home = os.path.expanduser("~/.gnupg") if os.path.exists(gpg_home) and not vcard_importers.gpg: vcard_importers.gpg.append({"active": True, "gpg_home": gpg_home}) session.ui.notify(_("Importing contacts from GPG keyring")) if "autotag_sb" in session.config.sys.plugins and len(session.config.prefs.autotag) == 0: session.config.prefs.autotag.append( {"match_tag": "spam", "unsure_tag": "maybespam", "tagger": "spambayes", "trainer": "spambayes"} ) session.config.prefs.autotag[0].exclude_tags[0] = "ham" # Assumption: If you already have secret keys, you want to # use the associated addresses for your e-mail. # If you don't already have secret keys, you should have # one made for you, if GnuPG is available. # If GnuPG is not available, you should be warned. gnupg = GnuPG() if gnupg.is_available(): keys = gnupg.list_secret_keys() if len(keys) == 0: # FIXME: Start background process generating a key once a user # has supplied a name and e-mail address. pass else: for key, details in keys.iteritems(): # Ignore revoked/expired keys. if "revocation-date" in details and details["revocation-date"] <= date.today().strftime("%Y-%m-%d"): continue for uid in details["uids"]: if "email" not in uid or uid["email"] == "": continue if uid["email"] in [x["email"] for x in session.config.profiles]: # Don't set up the same e-mail address twice. continue # FIXME: Add route discovery mechanism. profile = {"email": uid["email"], "name": uid["name"]} session.config.profiles.append(profile) if not session.config.prefs.gpg_recipient: session.config.prefs.gpg_recipient = key session.ui.notify(_("Encrypting config to %s") % key) if session.config.prefs.crypto_policy == "none": session.config.prefs.crypto_policy = "openpgp-sign" else: session.ui.warning(_("Oh no, PGP/GPG support is unavailable!")) if ( session.config.prefs.gpg_recipient and not (self._idx() and self._idx().INDEX) and not session.config.prefs.obfuscate_index ): randcrap = sha512b64( open("/dev/urandom").read(1024), session.config.prefs.gpg_recipient, "%s" % time.time() ) session.config.prefs.obfuscate_index = randcrap session.config.prefs.index_encrypted = True session.ui.notify(_("Obfuscating search index and enabling " "indexing of encrypted e-mail. ")) session.config.save() return True