def _getkey(self, email, key): error = None key_data = None for url_base in self.KEY_SERVER_BASE_URLS: url = self._getkey_url(url_base, email, key) if 'keylookup' in self.session.config.sys.debug: self.session.ui.debug('Fetching: %s' % url) try: key_data = secure_urlget(self.session, url, maxbytes=self.MAX_KEY_SIZE + 1) error = None break except urllib2.HTTPError as e: error = e if e.code == 404: # If a server reports the key was not found, let's stop # because the servers are supposed to be in sync. break except (IOError, urllib2.URLError, ssl.SSLError, ssl.CertificateError) as e: error = e if not key_data: error = 'No key data!' if not error and len(key_data) > self.MAX_KEY_SIZE: error = "Key too big (>%d bytes), ignoring" % self.MAX_KEY_SIZE if 'keylookup' in self.session.config.sys.debug: self.session.ui.debug(error) if error: raise ValueError(str(error)) return self._gnupg().import_keys(key_data, filter_uid_emails=[email])
def _lookup(self, address, strict_email_match=False): error = None for url_base in self.KEY_SERVER_BASE_URLS: url = self._lookup_url(url_base, address) if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug('[%s] Fetching: %s' % (self.NAME, url)) try: raw_result = secure_urlget(self.session, url, maxbytes=self.MAX_KEY_SIZE + 1) error = None break except urllib2.HTTPError as e: error = str(e) if e.code == 404: # If a server reports the key was not found, let's stop # because the servers are supposed to be in sync. break except (IOError, urllib2.URLError, ssl.SSLError, ssl.CertificateError) as e: error = str(e) if not error and len(raw_result) > self.MAX_KEY_SIZE: error = "Response too big (>%d bytes), ignoring" % self.MAX_KEY_SIZE if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug('[%s] %s' % (self.NAME, error)) if error: if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug('Error: %s' % error) if 'Error 404' in error: return {} raise ValueError(error) if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug('[%s] DATA: %s' % (self.NAME, raw_result[:200])) results = self._gnupg().parse_hpk_response(raw_result.split('\n')) if strict_email_match: for key in results.keys(): match = [ u for u in results[key].get('uids', []) if u['email'].lower() == address ] if not match: if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug( '[%s] No UID for %s, ignoring key' % (self.NAME, address)) del results[key] if 'keyservers' in self.session.config.sys.debug: self.session.ui.debug('[%s] Results=%d' % (self.NAME, len(results))) return results
def _lookup(self, address, strict_email_match=True): local, _, domain = address.partition("@") if domain.lower() in self.DOMAIN_BLACKLIST: # FIXME: Maybe make this dynamic; check for the WKD policy file and # if it is present remove the provider from the blacklist. self.session.ui.debug('[%s] Blacklisted domain, skipping: %s' % (self.NAME, domain)) return {} # FIXMEs: # - Check the spec and make sure we are doing the right thing when # comes to redirects. Probably switch off. But Linus! They seem # broken now, wah, wah, wah. # - Check the policy file, if it doesn't exist don't leak the # e-mail address to the server? Cache this? Counter-argument, # shame if user has no policy file but has a published key. # - Check content-type, because some sites return weird crap. local_part_encoded = _zbase_encode( hashlib.sha1(local.lower().encode('utf-8')).digest()) error = None keyinfo = None for url in WebKeyDirectoryURLs(address): try: if 'keylookup' in self.session.config.sys.debug: self.session.ui.debug('[%s] Fetching %s' % (self.NAME, url)) key_data = secure_urlget(self.session, url, maxbytes=self.MAX_KEY_SIZE + 1, timeout=int(self.TIMEOUT / 3)) if key_data: keyinfo = get_keyinfo(key_data, key_source=(self.SHORTNAME, url), key_info_class=MailpileKeyInfo)[0] error = None break else: error = 'Key not found' except urllib.request.HTTPError as e: if e.code == 404 and '+' not in address: error = '404: %s' % e # Since we are testing openpgpkey.* first, if we actually get a # valid response back we should treat that as authoritative and # not waste cycles checking the bare domain too. break else: error = str(e) except ssl.CertificateError as e: error = 'TLS: %s' % e except (urllib.request.URLError, ValueError, KeyError) as e: error = 'FAIL: %s' % e if not error and len(key_data) > self.MAX_KEY_SIZE: error = "Key too big (>%d bytes), ignoring" % self.MAX_KEY_SIZE if 'keylookup' in self.session.config.sys.debug: self.session.ui.debug(error) if error and 'keylookup' in self.session.config.sys.debug: self.session.ui.debug('[%s] Error: %s' % (self.NAME, error)) if not error: self.key_cache[keyinfo["fingerprint"]] = key_data elif error[:3] in ('TLS', 'FAI', '404'): return {} # Suppress these errors, they are common. else: raise ValueError(error) # FIXME: Key refreshes will need to know where this key came # from, we should record this somewhere. Should WKD # keys be considered ephemeral? What about revocations? # What about signatures? What if we get back multiple # keys/certs? What if we get back a revocation? return {keyinfo["fingerprint"]: keyinfo}
def _get(self, url): self.session.ui.mark('Getting: {0!s}'.format(url)) return secure_urlget(self.session, url, timeout=5, anonymous=self.config.anonymous)
def _get(self, url): self.session.ui.mark('Getting: %s' % url) return secure_urlget(self.session, url, timeout=5, anonymous=self.config.anonymous)