commit:     adcf14d0464bf339541542338f32425f3b0dabae
Author:     Pavlos Ratis <dastergon <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 17 00:18:14 2014 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Sun Aug 17 00:20:35 2014 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/gentoo-keys.git;a=commit;h=adcf14d0

add support for gkey checks

Features:
    * Enable colons listing
    * Checks for expired, invalid and revoked keys
    * Checks for keys capabilities

---
 gkeys/actions.py | 38 +++++++++++++++++++++++++++++++++++++-
 gkeys/lib.py     | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/gkeys/actions.py b/gkeys/actions.py
index b80f203..030424f 100644
--- a/gkeys/actions.py
+++ b/gkeys/actions.py
@@ -14,6 +14,7 @@ from __future__ import print_function
 
 import os
 
+from collections import defaultdict
 from json import load
 from shutil import rmtree
 from sslfetch.connections import Connector
@@ -24,7 +25,7 @@ from gkeys.config import GKEY
 
 Available_Actions = ['listseed', 'addseed', 'removeseed', 'moveseed', 
'fetchseed',
             'listseedfiles', 'listkey', 'installkey', 'removekey', 'movekey',
-            'installed', 'importkey', 'verify']
+            'installed', 'importkey', 'verify', 'checkkey']
 
 
 class Actions(object):
@@ -232,6 +233,41 @@ class Actions(object):
             return ["Completed"]
         return ["No seeds to search or install"]
 
+    def checkkey(self, args):
+        '''Check keys actions'''
+        if not args.seeds:
+            return ["Please specify seeds type (-s)."]
+        self.logger.debug("ACTIONS: checkkey; args: %s" % str(args))
+        installed_keys = self.installed(args)[1]
+        keydir = self.config.get_key(args.seeds + "-keydir")
+        self.logger.debug("ACTIONS: checkkey; keysdir = %s" % keydir)
+        self.gpg = GkeysGPG(self.config, keydir)
+        results = {}
+        failed = defaultdict(list)
+        self.output('', '\n Checking keys...')
+        for gkey in installed_keys:
+            self.logger.debug("ACTIONS: checkkey; gkey = %s" % gkey)
+            for key in gkey.keyid:
+                results[gkey.name] = self.gpg.check_keys(gkey.keydir, key)
+                if results[gkey.name].expired:
+                    failed['expired'].append("%s(%s): %s" % (gkey.name, 
gkey.nick, key))
+                if results[gkey.name].revoked:
+                    failed['revoked'].append("%s(%s): %s" % (gkey.name, 
gkey.nick, key))
+                if results[gkey.name].invalid:
+                    failed['invalid'].append("%s(%s): %s" % (gkey.name, 
gkey.nick, key))
+                if not results[gkey.name].sign:
+                    failed['sign'].append("%s(%s): %s " % (gkey.name, 
gkey.nick, key))
+        if failed['expired']:
+            self.output([failed['expired']], '\nExpired keys:\n')
+        if failed['revoked']:
+            self.output([failed['revoked']], '\nRevoked keys:\n')
+        if failed['invalid']:
+            self.output([failed['invalid']], '\nInvalid keys:\n')
+        if failed['sign']:
+            self.output([failed['sign']], '\nNo signing capabilities keys:\n')
+        return ['\nFound:\n-------', 'Expired: %d\nRevoked: %d\nInvalid: 
%d\nNo signing capabilities: %d'
+                % (len(failed['expired']), len(failed['revoked']),
+                    len(failed['invalid']), len(failed['sign']))]
 
     def removekey(self, args):
         '''Remove an installed key'''

diff --git a/gkeys/lib.py b/gkeys/lib.py
index 0a23d2b..a8af408 100644
--- a/gkeys/lib.py
+++ b/gkeys/lib.py
@@ -24,6 +24,7 @@ from os.path import abspath, pardir
 from os.path import join as pjoin
 
 from pyGPG.gpg import GPG
+from gkeys.config import GKEY_CHECK
 from gkeys.fileops import ensure_dirs
 from gkeys.log import logger
 from gkeys.seed import Seeds
@@ -184,27 +185,74 @@ class GkeysGPG(GPG):
         return []
 
 
-    def list_keys(self, keydir):
+    def list_keys(self, keydir, colons=False):
         '''List all keys in the specified keydir or
         all keys in all keydir if keydir=None
 
         @param keydir: the keydir to list the keys for
+        @param colons: bool to enable colon listing
         '''
         if not keydir:
             logger.debug("LIB: list_keys(), invalid keydir parameter: %s"
                 % str(keydir))
             return []
         self.set_keydir(keydir, 'list-keys')
-        if '--with-colons' in self.config['tasks']['list-keys']:
-            self.config['tasks']['list-keys'].remove('--with-colons')
         logger.debug("** Calling runGPG with Running 'gpg %s --list-keys %s'"
             % (' '.join(self.config['tasks']['list-keys']), keydir)
             )
+        if colons:
+            task_value = ['--with-colons']
+            self.config.options['tasks']['list-keys'].extend(task_value)
         result = self.runGPG(task='list-keys', inputfile=keydir)
         logger.info('GPG return code: ' + str(result.returncode))
         return result
 
 
+    def check_keys(self, keydir, keyid):
+        '''Check specified or all keys based on the seed type
+
+        @param keydir: the keydir to list the keys for
+        @param keyid: the keyid to check
+        '''
+        result = self.list_keys(keydir, colons=True)
+        revoked = expired = invalid = False
+        sign = True
+        for data in result.status.data:
+            if data.name ==  "PUB":
+                if data.long_keyid == keyid[2:]:
+                    # check if revoked
+                    if 'r' in data.validity:
+                        revoked = True
+                        logger.debug("ERROR in key %s : revoked" % 
data.long_keyid)
+                        break
+                    # if primary key expired, all subkeys expire
+                    if 'e' in data.validity:
+                        expired = True
+                        logger.debug("ERROR in key %s : expired" % 
data.long_keyid)
+                        break
+                    # check if invalid
+                    if 'i' in data.validity:
+                        invalid = True
+                        logger.debug("ERROR in key %s : invalid" % 
data.long_keyid)
+                        break
+            if data.name == "SUB":
+                if data.long_keyid == keyid[2:]:
+                    # check if subkey has signing capabilities
+                    if 's' not in data.key_capabilities:
+                        sign = False
+                        logger.debug("ERROR in subkey %s : No signing 
capabilities" % data.long_keyid)
+                    # check if expired
+                    if 'e' in data.validity:
+                        logger.debug("WARNING in subkey %s : expired" % 
data.long_keyid)
+                     # check if revoked
+                    if 'r' in data.validity:
+                        logger.debug("WARNING in subkey %s : revoked" % 
data.long_keyid)
+                    # check if invalid
+                    if 'i' in data.validity:
+                        logger.debug("WARNING in subkey %s : invalid" % 
data.long_keyid)
+        return GKEY_CHECK(keyid, revoked, expired, invalid, sign)
+
+
     def list_keydirs(self):
         '''List all available keydirs
         '''

Reply via email to