From 8f2e6092df5e9579668511350dad4eb268f697c7 Mon Sep 17 00:00:00 2001 From: Brian Dolbec Date: Wed, 26 Jun 2013 01:31:00 -0700 Subject: [PATCH] Work in progress changes to get add_key coded & working. --- gkeys/cli.py | 106 +++++++++++++++++++++++++++++++++++++++--------- gkeys/config.py | 2 +- gkeys/lib.py | 55 ++++++++++++++++++++++--- gkeys/seed.py | 7 +++- 4 files changed, 143 insertions(+), 27 deletions(-) diff --git a/gkeys/cli.py b/gkeys/cli.py index 743b622..3c9bc49 100644 --- a/gkeys/cli.py +++ b/gkeys/cli.py @@ -22,6 +22,7 @@ from gkeys.log import logger from gkeys.config import GKeysConfig, GKEY from gkeys.seed import Seeds +from gkeys.lib import GkeysGPG # set debug level to min @@ -41,6 +42,7 @@ class Main(object): self.config = config or GKeysConfig(root=root) self.print_results = print_results self.args = None + self.seeds = None def __call__(self, args=None): @@ -114,6 +116,7 @@ class Main(object): # now make it load the config file self.config.read_config() + # run the action func = getattr(self, '_action_%s' % args.action) logger.debug('Main: run; Found action: %s' % args.action) results = func(args) @@ -121,13 +124,18 @@ class Main(object): print("No results found. Check your configuration and that the", "seed file exists.") return - # super simple output for the time being - if self.print_results: - print('\n\nGkey results:') - print("\n".join([str(x) for x in results])) + if self.print_results and 'done' not in list(results): + self.output_results(results, '\n Gkey task results:') print() + @staticmethod + def output_results(results, header): + # super simple output for the time being + print(header) + print("\n".join([str(x) for x in results])) + + @staticmethod def build_gkeydict(args): keyinfo = {} @@ -167,9 +175,10 @@ class Main(object): '''Action listseed method''' kwargs = self.build_gkeydict(args) logger.debug("MAIN: _action_listseed; kwargs: %s" % str(kwargs)) - seeds = self._load_seeds(args.seeds) - if seeds: - results = seeds.list(**kwargs) + if not self.seeds: + self.seeds = self._load_seeds(args.seeds) + if self.seeds: + results = self.seeds.list(**kwargs) return results return None @@ -179,13 +188,12 @@ class Main(object): parts = self.build_gkeylist(args) gkey = GKEY._make(parts) logger.debug("MAIN: _action_addseed; new gkey: %s" % str(gkey)) - seeds = self._load_seeds(args.seeds) gkeys = self._action_listseed(args) if len(gkeys) == 0: logger.debug("MAIN: _action_addkey; now adding gkey: %s" % str(gkey)) - success = seeds.add(gkey) + success = self.seeds.add(gkey) if success: - success = seeds.save() + success = self.seeds.save() return ["Successfully Added new seed: %s" % str(success), gkey] else: messages = ["Matching seeds found in seeds file", @@ -199,13 +207,12 @@ class Main(object): parts = self.build_gkeylist(args) searchkey = GKEY._make(parts) logger.debug("MAIN: _action_removeseed; gkey: %s" % str(searchkey)) - seeds = self._load_seeds(args.seeds) gkeys = self._action_listseed(args) if len(gkeys) == 1: logger.debug("MAIN: _action_removeseed; now deleting gkey: %s" % str(gkeys[0])) - success = seeds.delete(gkeys[0]) + success = self.seeds.delete(gkeys[0]) if success: - success = seeds.save() + success = self.seeds.save() return ["Successfully Removed seed: %s" % str(success), gkeys[0]] elif len(gkeys): @@ -221,9 +228,10 @@ class Main(object): parts = self.build_gkeylist(args) searchkey = GKEY._make(parts) logger.debug("MAIN: _action_moveseed; gkey: %s" % str(searchkey)) - seeds = self._load_seeds(args.seeds) + if not self.seeds: + self.seeds = self._load_seeds(args.seeds) kwargs = self.build_gkeydict(args) - sourcekeys = seeds.list(**kwargs) + sourcekeys = self.seeds.list(**kwargs) dest = self._load_seeds(args.destination) destkeys = dest.list(**kwargs) messages = [] @@ -233,11 +241,11 @@ class Main(object): success = dest.add(sourcekeys[0]) logger.debug("MAIN: _action_moveseed; success: %s" %str(success)) logger.debug("MAIN: _action_moveseed; now deleting sourcekey: %s" % str(sourcekeys[0])) - success = seeds.delete(sourcekeys[0]) + success = self.seeds.delete(sourcekeys[0]) if success: success = dest.save() logger.debug("MAIN: _action_moveseed; destination saved... %s" %str(success)) - success = seeds.save() + success = self.seeds.save() messages.extend(["Successfully Moved %s seed: %s" % (args.seeds, str(success)), sourcekeys[0]]) return messages @@ -262,7 +270,59 @@ class Main(object): def _action_addkey(self, args): '''Action addkey method''' - pass + kwargs = self.build_gkeydict(args) + logger.debug("MAIN: _action_listseed; kwargs: %s" % str(kwargs)) + self.seeds = self._load_seeds(args.seeds) + if self.seeds: + # get the desired seed + keyresults = self.seeds.list(**kwargs) + if keyresults and not args.nick == '*': + self.output_results(keyresults, "\n Found GKEY seeds:") + elif keyresults: + self.output_results(['all'], "\n Installing seeds:") + else: + logger.info("MAIN: _action_addkey; " + "Matching seed entry not found") + if args.nick: + return {"Search failed for: %s" % args.nick: False} + elif args.name: + return {"Search failed for: %s" % args.name: False} + else: + return {"Search failed for search term": False} + # get confirmation + # fill in code here + keydir = self.config.get_key(args.seeds + "-keydir") + logger.debug("MAIN: _action_addkey; keysdir = %s" % keydir) + self.gpg = GkeysGPG(self.config, keydir) + results = {} + failed = [] + for key in keyresults: + if not key.keyid and not key.longkeyid and not args.nick == '*': + logger.debug("MAIN: _action_addkey; NO key id's to add... Ignoring") + return {"Failed: No keyid's found for %s" % key.name : ''} + elif not key.keyid and not key.longkeyid: + print("No keyid's found for:", key.nick, key.name, "Skipping...") + failed.append(key) + continue + logger.debug("MAIN: _action_addkey; adding key:") + logger.debug("MAIN: " + str(key)) + results[key.name] = self.gpg.add_key(key) + for result in results[key.name]: + logger.debug("MAIN: _action_addkey; result.failed = " + + str(result.failed)) + if self.print_results: + for result in results[key.name]: + print("key desired:", key.name, ", key added:", + result.username, ", succeeded:", + not result.failed, ", keyid:", result.keyid, + ", fingerprint:", result.fingerprint) + logger.debug("stderr_out: " + str(result.stderr_out)) + if result.failed: + failed.append(key) + if failed: + self.output_results(failed, "\n Failed to install:") + return {'Completed'} + return {"No seeds to search or install": False} def _action_removekey(self, args): @@ -275,7 +335,15 @@ class Main(object): pass + def user_confirm(self, message): + '''Get input from the user to confirm to proceed + with the desired action + @param message: string, user promt message to display + @return boolean: confirmation to proceed or abort + ''' + pass - + def output_failed(self, failed): + pass diff --git a/gkeys/config.py b/gkeys/config.py index 8b8360f..e78f487 100644 --- a/gkeys/config.py +++ b/gkeys/config.py @@ -170,4 +170,4 @@ class GKEY(namedtuple('GKEY', ['nick', 'name', 'keyid', 'longkeyid', @param packed_string: string of data separated by field_separator @return new GKEY instance containing the data ''' - return self._make(self._unpack_string(packed_string)) + return GKEY._make(self._unpack_string(packed_string)) diff --git a/gkeys/lib.py b/gkeys/lib.py index bbd126c..cae7f07 100644 --- a/gkeys/lib.py +++ b/gkeys/lib.py @@ -16,6 +16,7 @@ with gentoo-keys specific convienience functions. ''' +from os.path import join as pjoin from pygpg.gpg import GPG from gkeys.log import logger @@ -25,25 +26,67 @@ class GkeysGPG(GPG): '''Gentoo-keys primary gpg class''' - def __init__(self, config, keyring): + def __init__(self, config, keydir): '''class init function @param config: GKeysConfig config instance to use - @param keyring: string, the path to the keyring to be used + @param keyring: string, the path to the keydir to be used for all operations. ''' GPG.__init__(self, config) self.config = config - self.keyring = keyring + self.keydir = keydir def add_key(self, gkey): '''Add the specified key to the specified keyring - @param gkey: GKEY namedtuple with (name, keyid/longkeyid, fingerprint) + @param gkey: GKEY namedtuple with + (name, keyid/longkeyid, keyring, fingerprint,) ''' - - pass + logger.debug("keydir: %s, keyring: %s" % (self.keydir, gkey.keyring)) + keypath = pjoin(self.keydir, gkey.keyring) + # --keyring file | Note that this adds a keyring to the current list. + # If the intent is to use the specified keyring alone, + # use --keyring along with --no-default-keyring. + self.config['tasks']['recv-keys'] = [ + '--no-default-keyring', '--keyring', keypath, + ] + # prefer the longkeyid if available + #logger.debug("LIB: add_key; keyids %s, %s" + # % (str(gkey.longkeyid), str(gkey.keyid))) + if gkey.longkeyid != []: + keyids = gkey.longkeyid + # logger.debug("LIB: add_key; found gkey.longkeyid", keyids, type(gkey.longkeyid) + elif gkey.keyid != []: + keyids = gkey.keyid + # logger.debug("LIB: add_key; found gkey.keyid" + str(keyids)) + results = [] + for keyid in keyids: + logger.debug("LIB: add_key; final keyids" + keyid) + logger.debug("** Calling runGPG with Running 'gpg %s --recv-keys %s' for: %s" + % (' '.join(self.config['tasks']['recv-keys']), + keyid, gkey.name) + ) + result = self.runGPG(task='recv-keys', inputfile=keyid) + logger.info('GPG return code: ' + str(result.returncode)) + if result.fingerprint in gkey.fingerprint: + result.failed = False + message = "Fingerprints match... Import successful: " + message += "key: %s" %keyid + message += "\n result len: %s, %s" %(len(result.fingerprint), result.fingerprint) + message += "\n gkey len: %s, %s" %(len(gkey.fingerprint[0]), gkey.fingerprint[0]) + logger.info(message) + else: + result.failed = True + message = "Fingerprints do not match... Import failed for " + message += "key: %s" %keyid + message += "\n result: %s" %(result.fingerprint) + message += "\n gkey..: %s" %(str(gkey.fingerprint)) + logger.error(message) + results.append(result) + print result.stderr_out + return results def del_key(self, gkey, keyring): diff --git a/gkeys/seed.py b/gkeys/seed.py index ba3614f..1dd8fc4 100644 --- a/gkeys/seed.py +++ b/gkeys/seed.py @@ -51,10 +51,12 @@ class Seeds(object): self._error(err) return False + # initialize a dummy instance, so it can make new ones + gkey = GKEY._make([None,None,None,None,None,None]) for seed in seedlines: #try: seed = seed.strip('\n') - self.seeds.append(GKEY.make_packed(seed)) + self.seeds.append(gkey.make_packed(seed)) #except Exception as err: #logger.debug("Seed: load; Error splitting seed: %s" % seed) #logger.debug("Seed: load; ...............parts: %s" % str(parts)) @@ -115,6 +117,9 @@ class Seeds(object): ''' if not kwargs: return self.seeds + if kwargs['nick'] == '*': + return self.seeds[:] + # proceed with the search # discard any invalid keys keys = set(list(kwargs)).intersection(GKEY._fields) result = self.seeds[:] -- 2.26.2