diff options
Diffstat (limited to 'gkeys/actions.py')
-rw-r--r-- | gkeys/actions.py | 182 |
1 files changed, 173 insertions, 9 deletions
diff --git a/gkeys/actions.py b/gkeys/actions.py index dc36f7c..a224372 100644 --- a/gkeys/actions.py +++ b/gkeys/actions.py @@ -22,27 +22,31 @@ from sslfetch.connections import Connector from gkeys.lib import GkeysGPG from gkeys.seedhandler import SeedHandler from gkeys.config import GKEY +from gkeys.checks import SPECCHECK_SUMMARY, convert_pf, convert_yn Available_Actions = ['listseed', 'addseed', 'removeseed', 'moveseed', 'fetchseed', 'listseedfiles', 'listkey', 'installkey', 'removekey', 'movekey', - 'installed', 'importkey', 'verify', 'checkkey', 'sign'] + 'installed', 'importkey', 'verify', 'checkkey', 'sign', 'speccheck'] + 'refreshkey'] Action_Options = { - 'listseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile', 'file'], + 'listseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile', '1file'], 'addseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile'], 'removeseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile'], 'moveseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile', 'dest'], 'fetchseed': ['nick', 'name', 'keydir', 'fingerprint', 'seedfile'], 'listseedfiles': [], 'listkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'gpgsearch', 'keyid'], - 'installkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'seedfile'], + 'installkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'seedfile', '1file'], 'removekey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring'], 'movekey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'dest'], 'installed': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring'], 'importkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring'], - 'verify': ['dest', 'nick', 'name', 'keydir', 'fingerprint', 'category', 'file', 'signature', 'keyring', 'timestamp'], + 'verify': ['dest', 'nick', 'name', 'keydir', 'fingerprint', 'category', '1file', 'signature', 'keyring', 'timestamp'], 'checkkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'keyid'], 'sign': ['nick', 'name', 'keydir', 'fingerprint', 'file', 'keyring'], + 'speccheck': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'keyid'], + 'refreshkey': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'keyid'], } @@ -77,7 +81,7 @@ class Actions(object): '''Download the selected seed file(s)''' self.logger.debug("ACTIONS: fetchseed; args: %s" % str(args)) handler = SeedHandler(self.logger, self.config) - success, messages = handler.fetch_seeds(args.category, args, self.verify) + success, messages = handler.fetch_seeds(args.seedfile, args, self.verify) messages.append("") messages.append("Fetch operation completed") @@ -311,7 +315,9 @@ class Actions(object): self.output('', '\n Checking keys...') for gkey in sorted(keyresults): self.logger.info("Checking key %s, %s" % (gkey.nick, gkey.keyid)) - self.output('', " %s: %s" % (gkey.name, ', '.join(gkey.keyid))) + self.output('', + "\n %s, %s: %s" % (gkey.nick, gkey.name, ', '.join(gkey.keyid)) + + "\n ==============================================") self.logger.debug("ACTIONS: checkkey; gkey = %s" % str(gkey)) for key in gkey.keyid: results[gkey.name] = self.gpg.check_keys(gkey.keydir, key) @@ -332,9 +338,137 @@ class Actions(object): if failed['sign']: self.output([failed['sign']], '\n No signing capable subkeys:\n') return (len(failed) <1, - ['\nFound:\n-------', 'Expired: %d\nRevoked: %d\nInvalid: %d\nNo signing capable subkeys: %d' - % (len(failed['expired']), len(failed['revoked']), - len(failed['invalid']), len(failed['sign'])) + ['\nFound:\n-------', 'Expired: %d' % len(failed['expired']), + 'Revoked: %d' % len(failed['revoked']), + 'Invalid: %d' % len(failed['invalid']), + 'No signing capable subkeys: %d' % len(failed['sign']) + ]) + + + def speccheck(self, args): + '''Check keys actions''' + if not args.category: + return (False, ["Please specify seeds type."]) + self.logger.debug("ACTIONS: speccheck; args: %s" % str(args)) + handler = SeedHandler(self.logger, self.config) + seeds = handler.load_category(args.category) + catdir = self.config.get_key(args.category + "-category") + self.logger.debug("ACTIONS: speccheck; catdir = %s" % catdir) + self.gpg = GkeysGPG(self.config, catdir) + results = {} + failed = defaultdict(list) + kwargs = handler.build_gkeydict(args) + keyresults = seeds.list(**kwargs) + self.output('', '\n Checking keys...') + for gkey in sorted(keyresults): + self.logger.info("Checking key %s, %s" % (gkey.nick, gkey.keyid)) + self.output('', + "\n %s, %s: %s" % (gkey.nick, gkey.name, ', '.join(gkey.keyid)) + + "\n ==============================================") + self.logger.debug("ACTIONS: speccheck; gkey = %s" % str(gkey)) + for key in gkey.keyid: + results = self.gpg.speccheck(gkey.keydir, key) + for g in results: + pub_pass = {} + for key in results[g]: + self.output('', key.pretty_print()) + + if key.key is "PUB": + pub_pass = { + 'key': key, + 'pub': key.passed_spec, + 'sign': False, + 'encrypt': False, + 'auth': False, + 'signs': [], + 'encrypts': [], + 'authens': [], + 'final': False, + } + if key.key is "SUB": + if key.sign_capable and key.passed_spec: + pub_pass['signs'].append(key.passed_spec) + pub_pass['sign'] = True + if key.encrypt_capable: + pub_pass['encrypts'].append(key.passed_spec) + pub_pass['encrypt'] = True + if key.capabilities == 'a': + pub_pass['authens'].append(key.passed_spec) + if key.passed_spec: + pub_pass['auth'] = True + validity = key.validity.split(',')[0] + if not key.expire and not 'r' in validity: + failed['expired'].append("%s <%s>: %s" % (gkey.name, gkey.nick, key.fingerprint)) + if 'r' in validity: + failed['revoked'].append("%s <%s>: %s" % (gkey.name, gkey.nick, key.fingerprint)) + if 'i' in validity: + failed['invalid'].append("%s <%s>: %s" % (gkey.name, gkey.nick, key.fingerprint)) + if key.capabilities not in ['a', 'e']: + if not key.algo: + failed['algo'].append("%s <%s>: %s" % (gkey.name, gkey.nick, key.fingerprint)) + if not key.bits: + failed['bits'].append("%s <%s>: %s" % (gkey.name, gkey.nick, key.fingerprint)) + if "Warning" in key.expire_reason: + failed['warn'].append("%s <%s>: %s " % (gkey.name, gkey.nick, key.fingerprint)) + if True in pub_pass['signs']: + pub_pass['sign'] = True + if True in pub_pass['encrypts']: + pub_pass['encrypt'] = True + if not pub_pass['sign']: + failed['sign'].append("%s <%s>: %s" % (gkey.name, gkey.nick, pub_pass['key'].fingerprint)) + if not pub_pass['encrypt']: + failed['encrypt'].append("%s <%s>: %s" % (gkey.name, gkey.nick, pub_pass['key'].fingerprint)) + spec = "%s <%s>: %s" % (gkey.name, gkey.nick, pub_pass['key'].fingerprint) + for k in ['pub', 'sign']: + if pub_pass[k]: + pub_pass['final'] = True + else: + pub_pass['final'] = False + break + if pub_pass['final']: + if spec not in failed['spec-approved']: + failed['spec-approved'].append(spec) + else: + if spec not in failed['spec']: + failed['spec'].append(spec) + sdata = convert_pf(pub_pass, ['pub', 'sign', 'final']) + sdata = convert_yn(sdata, ['auth', 'encrypt']) + self.output('', SPECCHECK_SUMMARY % sdata) + + if failed['revoked']: + self.output([sorted(set(failed['revoked']))], '\n Revoked keys:') + if failed['invalid']: + self.output([sorted(set(failed['invalid']))], '\n Invalid keys:') + if failed['sign']: + self.output([sorted(set(failed['sign']))], '\n No signing capable subkey:') + if failed['encrypt']: + self.output([sorted(set(failed['encrypt']))], '\n No Encryption capable subkey (Notice only):') + if failed['algo']: + self.output([sorted(set(failed['algo']))], '\n Incorrect Algorithm:') + if failed['bits']: + self.output([sorted(set(failed['bits']))], '\n Incorrect bit length:') + if failed['expired']: + self.output([sorted(set(failed['expired']))], '\n Expiry keys:') + if failed['warn']: + self.output([sorted(set(failed['warn']))], '\n Expiry Warnings:') + if failed['spec']: + self.output([sorted(set(failed['spec']))], '\n Failed to pass SPEC requirements:') + if failed['spec-approved']: + self.output([sorted(set(failed['spec-approved']))], '\n SPEC Approved:') + + return (len(failed) <1, + ['\nFound Failures:\n-------', + 'Revoked................: %d' % len(set(failed['revoked'])), + 'Invalid................: %d' % len(set(failed['invalid'])), + 'No Signing subkey......: %d' % len(set(failed['sign'])), + 'No Encryption subkey...: %d' % len(set(failed['encrypt'])), + 'Algorithm..............: %d' % len(set(failed['algo'])), + 'Bit length.............: %d' % len(set(failed['bits'])), + 'Expiry.................: %d' % len(set(failed['expired'])), + 'Expiry Warnings........: %d' % len(set(failed['warn'])), + 'SPEC requirements......: %d' % len(set(failed['spec'])), + '=============================', + 'SPEC Approved..........: %d' % len(set(failed['spec-approved'])), ]) @@ -525,6 +659,8 @@ class Actions(object): success_fetch = os.path.isfile(signature) if success_fetch: break + else: + sig_path = signature messages = [] self.logger.info("Verifying file...") verified = False @@ -601,3 +737,31 @@ class Actions(object): ) success.append(True) return (False not in success, ['', msgs]) + + + def refreshkey(self, args): + '''Calls gpg with the --refresh-keys option + for in place updates of the installed keys''' + if not args.category: + return (False, ["Please specify seeds type."]) + self.logger.debug("ACTIONS: refreshkey; args: %s" % str(args)) + handler = SeedHandler(self.logger, self.config) + seeds = handler.load_category(args.category) + catdir = self.config.get_key(args.category + "-category") + self.logger.debug("ACTIONS: refreshkey; catdir = %s" % catdir) + self.gpg = GkeysGPG(self.config, catdir) + results = {} + kwargs = handler.build_gkeydict(args) + keyresults = seeds.list(**kwargs) + self.output('', '\n Refreshig keys...') + for gkey in sorted(keyresults): + self.logger.info("Refreshig key %s, %s" % (gkey.nick, gkey.keyid)) + self.output('', " %s: %s" % (gkey.name, ', '.join(gkey.keyid))) + #self.output('', " ===============") + self.logger.debug("ACTIONS: refreshkey; gkey = %s" % str(gkey)) + results[gkey.keydir] = self.gpg.refresh_key(gkey) + return (True, ['Completed']) + + + + |