commit:     2b7d8753f01c72d88a243a1e0600b8d9726057ed
Author:     Pavlos Ratis <dastergon <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 11 10:17:35 2014 +0000
Commit:     Brian Dolbec <brian.dolbec <AT> gmail <DOT> com>
CommitDate: Mon Aug 11 10:17:35 2014 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/gentoo-keys.git;a=commit;h=2b7d8753

add file verification support

File verification support allows users to verify files by either URLs or local 
files.
These files are verified against their signature and the installed release keys.

---
 gkeys/actions.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 gkeys/cli.py     |  5 +++++
 gkeys/lib.py     | 32 +++++++++++++++++++++------
 3 files changed, 96 insertions(+), 7 deletions(-)

diff --git a/gkeys/actions.py b/gkeys/actions.py
index 5d65552..115007c 100644
--- a/gkeys/actions.py
+++ b/gkeys/actions.py
@@ -16,6 +16,7 @@ import os
 
 from json import load
 from shutil import rmtree
+from sslfetch.connections import Connector
 
 from gkeys.lib import GkeysGPG
 from gkeys.seedhandler import SeedHandler
@@ -23,7 +24,7 @@ from gkeys.config import GKEY
 
 Available_Actions = ['listseed', 'addseed', 'removeseed', 'moveseed', 
'fetchseed',
             'listseedfiles', 'listkey', 'installkey', 'removekey', 'movekey',
-            'installed', 'importkey']
+            'installed', 'importkey', 'verify']
 
 
 class Actions(object):
@@ -340,6 +341,69 @@ class Actions(object):
         '''
         pass
 
+    def verify(self, args):
+        '''File verification action'''
+        connector_output = {
+             'info': self.logger.debug,
+             'error': self.logger.error,
+             'kwargs-info': {},
+             'kwargs-error': {},
+        }
+        if not args.filename:
+            return ['Please provide a signed file.']
+        if not args.seeds:
+            return ['Please specifiy type of seed file.']
+        keys = self.installed(args)[1]
+        if not keys:
+            return ['No installed keys, try installkey action.']
+        keydir = self.config.get_key(args.seeds + "-keydir")
+        self.logger.debug("ACTIONS: verify; keysdir = %s" % keydir)
+        self.gpg = GkeysGPG(self.config, keydir)
+        filepath, signature  = args.filename, args.signature
+        isurl = success = False
+        if filepath.startswith('http'):
+            isurl = True
+            fetcher = Connector(connector_output, None, "Gentoo Keys")
+            self.logger.debug("ACTIONS: verify; fetching %s signed file " % 
filepath)
+            success, signedfile, timestamp = fetcher.fetch_file(filepath)
+        else:
+            filepath = os.path.abspath(filepath)
+            self.logger.debug("ACTIONS: verify; local file %s" % filepath)
+            success = os.path.isfile(filepath)
+        if not success:
+            messages = ["File %s cannot be retrieved." % filepath]
+        else:
+            if not signature:
+                EXTENSIONS = ['.asc','.sig','.gpgsig']
+                success_fetch = False
+                for ext in EXTENSIONS:
+                    signature = filepath + ext
+                    if isurl:
+                        self.logger.debug("ACTIONS: verify; fetching %s 
signature " % signature)
+                        success_fetch, sig, timestamp = 
fetcher.fetch_file(signature)
+                    else:
+                        signature = os.path.abspath(signature)
+                        self.logger.debug("ACTIONS: verify; checking %s 
signature " % signature)
+                        success_fetch = os.path.isfile(signature)
+                    if success_fetch:
+                        break
+            messages = []
+            #TODO: use file:// uri in the future
+            if isurl:
+                splitfile = filepath.split('/')[-1]
+                splitsig = signature.split('/')[-1]
+                filepath = os.path.abspath(splitfile)
+                signature = os.path.abspath(splitsig)
+            self.logger.info("Verifying file...")
+            for key in keys:
+                results = self.gpg.verify_file(key, signature, filepath)
+                keyid = key.keyid[0]
+                if results.verified[0]:
+                    messages = ["File %s has been successfully verified | %s 
(%s)." % (filepath, str(key.name), str(keyid))]
+                else:
+                    messages = ["File verification of %s failed | %s (%s)." % 
(filepath, str(key.name), str(keyid))]
+        return messages
+
 
     def listseedfiles(self, args):
         '''List seed files found in the configured seed directory'''

diff --git a/gkeys/cli.py b/gkeys/cli.py
index c8d5be7..dffda5c 100644
--- a/gkeys/cli.py
+++ b/gkeys/cli.py
@@ -84,6 +84,11 @@ class Main(object):
             help='The seeds file to use or update')
         parser.add_argument('-S', '--seedfile', dest='seedfile', default=None,
             help='The seedfile path to use')
+        parser.add_argument('-F', '--file', dest='filename', default=None,
+               help='The path/URL to use for the signed file')
+        parser.add_argument('-z','--signature', dest='signature', default=None,
+           help='The path/URL to use for the signature')
+
 
         subparsers = parser.add_subparsers(help='actions')
         for name in Available_Actions:

diff --git a/gkeys/lib.py b/gkeys/lib.py
index 4d150bb..0a23d2b 100644
--- a/gkeys/lib.py
+++ b/gkeys/lib.py
@@ -194,10 +194,9 @@ class GkeysGPG(GPG):
             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')
-
-        self.set_keydir(keydir, 'list-keys')
         logger.debug("** Calling runGPG with Running 'gpg %s --list-keys %s'"
             % (' '.join(self.config['tasks']['list-keys']), keydir)
             )
@@ -213,7 +212,7 @@ class GkeysGPG(GPG):
 
 
     def verify_key(self, gkey):
-        '''verify the specified key from the specified keydir
+        '''Verify the specified key from the specified keydir
 
         @param gkey: GKEY namedtuple with (name, keyid/longkeyid, fingerprint)
         '''
@@ -226,10 +225,31 @@ class GkeysGPG(GPG):
         pass
 
 
-    def verify_file(self, filepath):
-        '''Verify the file specified at filepath
+    def verify_file(self, gkey, signature, filepath):
+        '''Verify the file specified at filepath or url
+
+        @param signature: string with the signature file
+        @param filepath: string with the path or url of the signed file
         '''
-        pass
+        if signature:
+            self.set_keydir(gkey.keydir, 'verify', reset=True)
+            logger.debug("** Calling runGPG with Running 'gpg %s --verify %s 
and %s'"
+                    % (' '.join(self.config['tasks']['verify']), signature, 
filepath))
+            results = self.runGPG(task='verify', 
inputfile=[signature,filepath])
+        else:
+            self.set_keydir(gkey.keydir, 'decrypt', reset=True)
+            logger.debug("** Calling runGPG with Running 'gpg %s --decrypt %s 
and %s'"
+                    % (' '.join(self.config['tasks']['decrypt']), filepath))
+            results = self.runGPG(task='decrypt', inputfile=filepath)
+        keyid = gkey.keyid[0]
+        if results.verified[0]:
+            logger.info("GPG verification succeeded. Name: %s / Key: %s" % 
(str(gkey.name), str(keyid)))
+            logger.info("\tSignature result:" + str(results.verified))
+        else:
+            logger.debug("GPG verification failed. Name: %s / Key: %s" % 
(str(gkey.name), str(keyid)))
+            logger.debug("\t Signature result:"+ str(results.verified))
+            logger.debug("LIB: verify; stderr_out:" + str(results.stderr_out))
+        return results
 
 
     def set_keyseedfile(self):

Reply via email to