def command(self): args = list(self.args) if args: address, fprints, origins = args[0], args[1].split(','), args[2:] else: address = self.data.get('address', [''])[0] fprints = self.data.get('fingerprints', []) origins = self.data.get('origins', []) safe_assert(address or fprints or origins) result = lookup_crypto_keys(self.session, address, get=[f.strip() for f in fprints], origins=origins, event=self.event) if len(result) > 0: # Update the VCards! PGPKeysImportAsVCards(self.session, arg=[k['fingerprint'] for k in result] ).run() # Previous crypto evaluations may now be out of date, so we # clear the cache so users can see results right away. ClearParseCache(pgpmime=True) return self._success(_n('Imported %d encryption key', 'Imported %d encryption keys', len(result)) % len(result), result=result)
def command(self): key_files = self.data.get( "key_file", []) + [a for a in self.args if not '://' in a] key_urls = self.data.get("key_url", []) + [a for a in self.args if '://' in a] key_data = [] key_data.extend(self.data.get("key_data", [])) for key_file in key_files: with open(key_file) as file: key_data.append(file.read()) for key_url in key_urls: with ConnBroker.context(need=[ConnBroker.OUTGOING_HTTP]): uo = urllib2.urlopen(key_url) key_data.append(uo.read()) rv = self._gnupg().import_keys('\n'.join(key_data)) # Previous crypto evaluations may now be out of date, so we # clear the cache so users can see results right away. ClearParseCache(pgpmime=True) # Update the VCards! PGPKeysImportAsVCards(self.session, arg=([i['fingerprint'] for i in rv['updated']] + [i['fingerprint'] for i in rv['imported']])).run() return self._success(_("Imported %d keys") % len(key_data), rv)
def command(self): args = list(self.args) if args: pin_key = False address, fprints, origins = args[0], args[1].split(','), args[2:] else: pin_key = self.data.get('pinned', [''])[0].lower()[:1] in ('y', 't') address = self.data.get('address', [''])[0] fprints = self.data.get('fingerprints', []) origins = self.data.get('origins', []) safe_assert(address or fprints or origins) result = lookup_crypto_keys(self.session, address, get=[f.strip() for f in fprints], pin_key=pin_key, vcard=self._get_or_create_vcard(address), origins=origins, event=self.event) if len(result) > 0: # Update the VCards! PGPKeysImportAsVCards(self.session, arg=[k['fingerprint'] for k in result]).run() # The key was looked up based on the given address, so it must have # a user id containing that address, so when it is imported to # VCards, the VCard for that address will list the key. for k in result: k.in_vcards = True # Previous crypto evaluations may now be out of date, so we # clear the cache so users can see results right away. ClearParseCache(pgpmime=True) return self._success( _n('Imported %d encryption key', 'Imported %d encryption keys', len(result)) % len(result), result=result)
def command(self): emails = set(list(self.args)) | set(self.data.get('email', [])) safe_assert(emails) idx = self._idx() gnupg = self._gnupg(dry_run=True) missing, old, status = [], {}, {} for email in emails: vc = self.session.config.vcards.get_vcard(email) fp = vc.pgp_key if vc else None if vc and fp: if self._key_can_encrypt(gnupg, fp): old[email] = fp status[email] = 'Key is already on our key-chain' else: # FIXME: Should we remove the bad key from the vcard? # FIXME: Should we blacklist the bad key? missing.append(email) status[email] = 'Obsolete key is on our key-chain' else: missing.append(email) status[email] = 'We have no key for this person' should_import = {} for email in missing: if self._uses_crypto(idx, email): keys = lookup_crypto_keys(self.session, email, origins=self.TOFU_ORIGINS, strict_email_match=True, event=self.event) for keyinfo in (keys or []): if self._seen_enough_signatures(idx, email, keyinfo): should_import[email] = keyinfo['fingerprint'] break if keys and 'email' not in should_import: status[email] = 'Found keys, but none in active use' else: status[email] = 'Have not seen enough PGP messages' imported = {} for email, fingerprint in should_import.iteritems(): keys = lookup_crypto_keys( self.session, email, get=[fingerprint], origins=self.TOFU_ORIGINS, strict_email_match=True, event=self.event) if keys: imported[email] = keys status[email] = 'Imported key!' else: status[email] = 'Failed to import key' for email in imported: if email in missing: missing.remove(email) if len(imported) > 0: # Update the VCards! fingerprints = [] for keys in imported.values(): fingerprints.extend([k['fingerprint'] for k in keys]) PGPKeysImportAsVCards(self.session, arg=fingerprints).run() # Previous crypto evaluations may now be out of date, so we # clear the cache so users can see results right away. ClearParseCache(pgpmime=True) # i18n note: Not translating things here, since messages are not # generally use-facing and we want to reduce load on our # translators. return self._success('Evaluated key TOFU', result={ 'missing_keys': missing, 'imported_keys': imported, 'status': status, 'on_keychain': old})
def command(self): tofu_cfg = self.session.config.prefs.key_tofu if not (tofu_cfg.autocrypt or tofu_cfg.historic): return self._success( 'Key TOFU disabled. Check prefs.key_tofu.* settings.') args = list(self.args) if args and (args[0] == '--dry'): dry_run = args.pop(0) else: dry_run = 'keytofudry' in self.session.config.sys.debug if args and (args[0] == '--should'): should_encrypt = args.pop(0) else: should_encrypt = self.data.get('should-encrypt', ['N'])[0] should_encrypt = should_encrypt.lower()[:1] in ('y', 't') emails = set(args) | set(self.data.get('email', [])) if not emails: return self._success('Nothing Happened') if tofu_cfg.autocrypt: from mailpile.plugins.crypto_autocrypt import get_Autocrypt_DB, save_Autocrypt_DB, AutocryptRecord, AutocryptKeyLookupHandler acState = get_Autocrypt_DB(self.session.config)['state'] else: acState = None idx = self._idx() gnupg = self._gnupg() known_keys_list = _mailpile_key_list(gnupg.list_keys()) missing, old, status = [], {}, {} for email in emails: vc = self.session.config.vcards.get_vcard(email) fp = vc.pgp_key if vc else None if vc and fp: if self._key_can_encrypt(gnupg, fp): old[email] = fp status[email] = 'Key is already on our key-chain' if vc.pgp_key_pinned: status[email] = 'Key is pinned' elif self._key_is_trusted(fp, known_keys_list): status[email] = 'Key is trusted by GnuPG' elif acState: acr = AutocryptRecord.Load(acState, email, _raise=None) if acr and acr.should_encrypt( ) and not acr.imported_ts: missing.append(email) status[email] = 'Obsolete key is on our key-chain' else: # FIXME: Should we remove the bad key from the vcard? # FIXME: Should we blacklist the bad key? # FIXME: Should this trigger a notification, per. #1869? missing.append(email) status[email] = 'Obsolete key is on our key-chain' else: missing.append(email) status[email] = 'We have no key for this person' global TOFU_CHECK_HISTORY now = time.time() interval_cutoff = now - tofu_cfg.min_interval for k in TOFU_CHECK_HISTORY.keys(): if TOFU_CHECK_HISTORY.get(k, now) < interval_cutoff: del TOFU_CHECK_HISTORY[k] should_import = {} hist_origins = [o.strip() for o in tofu_cfg.hist_origins.split(',')] for email in missing: checking = '%s/%s' % (email, tofu_cfg) last_check = TOFU_CHECK_HISTORY.get(checking, 0) if (not should_encrypt ) and last_check and last_check > interval_cutoff: status[email] += ' (checked recently)' continue elif not dry_run: TOFU_CHECK_HISTORY[checking] = now if tofu_cfg.autocrypt and acState: acr = AutocryptRecord.Load(acState, email, _raise=None) if acr and acr.should_encrypt() and not acr.imported_ts: should_import[email] = (acr.key_sig, AutocryptKeyLookupHandler.NAME) if tofu_cfg.historic and hist_origins and email not in should_import: count = self._recently_used_crypto(tofu_cfg, idx, email) if count or should_encrypt: keys = lookup_crypto_keys(self.session, email, origins=hist_origins, strict_email_match=True, known_keys_list=known_keys_list, event=self.event, only_good=True) or [] for keyinfo in keys: if should_encrypt or self._seen_enough_signatures( tofu_cfg, idx, email, keyinfo): should_import[email] = (keyinfo['fingerprint'], hist_origins) break if keys and 'email' not in should_import: status[email] = 'Found keys, but none in active use' else: status[email] = 'Have not seen enough PGP messages' imported = {} for email, (key_id, origins) in should_import.iteritems(): if 'keytofu' in self.session.config.sys.debug: self.session.ui.debug('keytofu(%s): importing %s from %s' % (email, key_id, origins)) if dry_run: status[email] = 'Should import %s from %s' % (key_id, origins) else: keys = lookup_crypto_keys( self.session, email, get=[key_id], vcard=self.session.config.vcards.get_vcard(email), strict_email_match=True, origins=origins, known_keys_list=known_keys_list, event=self.event) if keys: # FIXME: This should trigger a notification, per. #1869 imported[email] = keys status[email] = 'Imported key!' vc = self.session.config.vcards.get_vcard(email) if vc and key_id in keys: with vc: vc.pgp_key = keys[key_id].fingerprint vc.save() else: status[email] = 'Failed to import key' for email in imported: if email in missing: missing.remove(email) if len(imported) > 0: # Update the VCards! fingerprints = [] for keys in imported.values(): fingerprints.extend(k['fingerprint'] for k in keys) PGPKeysImportAsVCards(self.session, arg=fingerprints).run() # Previous crypto evaluations may now be out of date, so we # clear the cache so users can see results right away. ClearParseCache(pgpmime=True) # i18n note: Not translating things here, since messages are not # generally user-facing and we want to reduce load on # our translators. return self._success('Evaluated key TOFU', result={ 'missing_keys': missing, 'imported_keys': imported, 'status': status, 'on_keychain': old })