aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'gkeys/gkeys/seedhandler.py')
-rw-r--r--gkeys/gkeys/seedhandler.py189
1 files changed, 189 insertions, 0 deletions
diff --git a/gkeys/gkeys/seedhandler.py b/gkeys/gkeys/seedhandler.py
new file mode 100644
index 0000000..cc797b9
--- /dev/null
+++ b/gkeys/gkeys/seedhandler.py
@@ -0,0 +1,189 @@
+#
+#-*- coding:utf-8 -*-
+
+"""
+ Gentoo-keys - seedhandler.py
+
+ Seed handling interface module
+
+ @copyright: 2012 by Brian Dolbec <dol-sen@gentoo.org>
+ @license: GNU GPL2, see COPYING for details.
+"""
+
+import os
+import re
+from json import load
+
+from gkeys.config import GKEY
+from gkeys.seed import Seeds
+from gkeys.fileops import ensure_dirs
+
+
+class SeedHandler(object):
+
+ def __init__(self, logger, config):
+ self.config = config
+ self.logger = logger
+ self.fingerprint_re = re.compile('[0-9A-Fa-f]{40}')
+ self.finerprint_re2 = re.compile('[0-9A-Fa-f]{4}( [0-9A-Fa-f]{4}){9}')
+
+
+ def new(self, args, checkgkey=False):
+ newgkey = self.build_gkeydict(args)
+ if checkgkey:
+ newgkey, is_good = self.check_gkey(newgkey)
+ if is_good:
+ newgkey = GKEY(**newgkey)
+ self.logger.debug("SeedHandler: new; new gkey: %s" % str(newgkey))
+ else:
+ return None
+ else:
+ newgkey = GKEY(**newgkey)
+ self.logger.debug("SeedHandler: new; NON-checked new gkey: %s" % str(newgkey))
+ return newgkey
+
+
+ @staticmethod
+ def build_gkeydict(args):
+ keyinfo = {}
+ for attr in GKEY._fields + ('keyid',):
+ try:
+ value = getattr(args, attr)
+ if attr == 'name' and value:
+ value = " ".join(value)
+ if value:
+ keyinfo[attr] = value
+ except AttributeError:
+ pass
+ return keyinfo
+
+ def load_seeds(self, seedfile=None, filepath=None):
+ '''Load seed file
+
+ @param seeds: string of the short name seed file
+ @param seedfile: string filepath of the file to load
+ @return Seeds class instance of the file loaded
+ '''
+ if not seedfile and not filepath:
+ self.logger.error("SeedHandler: load_seeds; no filename to load: "
+ "setting = %s. Please use the -S or -F option to indicate: which seed "
+ "file to use." % seedfile)
+ return False
+ if seedfile:
+ filepath = self.config.get_key('seeds', seedfile)
+ elif not filepath:
+ self.logger.error("SeedHandler: load_seeds; No filepath to load")
+ self.logger.debug("SeedHandler: load_seeds; seeds filepath to load: "
+ "%s" % filepath)
+ seeds = Seeds(config=self.config)
+ seeds.load(filepath)
+ return seeds
+
+ def load_category(self, category, nicks=None):
+ '''Loads the designated key directories
+
+ @param category: string
+ @param nicks: list of string nick ids to load
+ @return Seeds class object
+ '''
+ seeds = Seeds(config=self.config)
+ if category:
+ catdir = self.config.get_key(category + "-category")
+ else:
+ self.logger.debug("SeedHandler: load_category; Error invalid category: %s." % (str(category)))
+ return seeds
+ self.logger.debug("SeedHandler: load_category; catdir = %s" % catdir)
+ try:
+ if not nicks:
+ nicks = os.listdir(catdir)
+ for nick in nicks:
+ seed_path = os.path.join(catdir, nick)
+ gkey_path = os.path.join(seed_path, 'gkey.seeds')
+ seed = None
+ try:
+ with open(gkey_path, 'r') as fileseed:
+ seed = load(fileseed)
+ except IOError as error:
+ self.logger.debug("SeedHandler: load_category; IOError loading seed file %s." % gkey_path)
+ self.logger.debug("Error was: %s" % str(error))
+ if seed:
+ for nick in sorted(seed):
+ key = seed[nick]
+ seeds.add(nick, GKEY(**key))
+ except OSError as error:
+ self.logger.debug("SeedHandler: load_category; OSError for %s" % catdir)
+ self.logger.debug("Error was: %s" % str(error))
+ return seeds
+
+ def fetch_seeds(self, seeds, args, verified_dl=None):
+ '''Fetch new seed files
+
+ @param seeds: list of seed nicks to download
+ @param verified_dl: Function pointer to the Actions.verify()
+ instance needed to do the download and verification
+ '''
+ http_check = re.compile(r'^(http|https)://')
+ urls = []
+ messages = []
+ try:
+ for seed in [seeds]:
+ seedurl = self.config.get_key('seedurls', seed)
+ seedpath = self.config.get_key('seeds', seed)
+ if http_check.match(seedurl):
+ urls.extend([(seedurl, seedpath)])
+ else:
+ self.logger.info("Wrong seed file URLs... Switching to default URLs.")
+ urls.extend([(self.config['seedurls'][seed], seedpath)])
+ except KeyError:
+ pass
+ succeeded = []
+ seedsdir = self.config.get_key('seedsdir')
+ mode = int(self.config.get_key('permissions', 'directories'),0)
+ ensure_dirs(seedsdir, mode=mode)
+ for (url, filepath) in urls:
+ args.category = 'rel'
+ args.filename = url
+ args.signature = None
+ args.timestamp = True
+ args.destination = filepath
+ verified, messages_ = verified_dl(args)
+ succeeded.append(verified)
+ messages.append(messages_)
+ return (succeeded, messages)
+
+ def check_gkey(self, args):
+ # assume it's good until an error is found
+ is_good = True
+ try:
+ args['keydir'] = args.get('keydir', args['nick'])
+ fprs = []
+ if args['fingerprint']:
+ for fpr in args['fingerprint']:
+ is_good, fingerprint = self._check_fingerprint_integrity(fpr)
+ if is_good:
+ fprs.append(fingerprint)
+ else:
+ self.logger.error('Bad fingerprint from command line args: %s' % fpr)
+ if is_good:
+ args['fingerprint'] = fprs
+ except KeyError:
+ self.logger.error('GPG fingerprint not found.')
+ is_good = False
+ if not is_good:
+ self.logger.error('A valid fingerprint '
+ 'was not found for %s' % args['name'])
+ return args, is_good
+
+ def _check_fingerprint_integrity(self, fpr):
+ # assume it's good unti an error is found
+ is_good = True
+ fingerprint = fpr.replace(" ", "")
+ # check fingerprint integrity
+ if len(fingerprint) != 40:
+ self.logger.error(' GPGKey incorrect fingerprint ' +
+ 'length (%s) for fingerprint: %s' % (len(fingerprint), fingerprint))
+ is_good = False
+ if not self.fingerprint_re.match(fingerprint):
+ self.logger.error(' GPGKey: Non hexadecimal digits in ' + 'fingerprint for fingerprint: ' + fingerprint)
+ is_good = False
+ return is_good, fingerprint