| #!/usr/bin/python |
| |
| import re |
| import os |
| from tempfile import mkdtemp |
| from subprocess import Popen, PIPE |
| from optparse import OptionParser |
| from shutil import rmtree |
| |
| from signing import findfiles |
| |
| supported_files_re = re.compile(r""" |
| (?: |
| \.gz |
| | \.bz2 |
| | \.exe |
| | \.zip |
| | \.cab |
| | \.dmg |
| | \.bundle |
| | \.iso |
| | MD5SUMS |
| | SHA1SUMS |
| ) $ |
| """, re.VERBOSE) |
| |
| |
| class GnuPG(object): |
| |
| def __init__(self, gpg_bin="gpg", homedir=None, args=None, verbose=False): |
| self.gpg_bin = gpg_bin |
| self.args = ['--batch', '-v'] |
| self.verbose = verbose |
| if isinstance(args, (list, tuple)): |
| self.args = self.args.extend(list(args)) |
| if homedir: |
| self.homedir = homedir |
| self.args.extend(['--homedir', self.homedir]) |
| self.setup_homedir() |
| |
| def setup_homedir(self): |
| if not os.path.exists(self.homedir): |
| os.makedirs(self.homedir) |
| |
| def import_key(self, keyfile): |
| cmd = [self.gpg_bin] |
| cmd.extend(self.args) |
| cmd.extend(['--import', keyfile]) |
| p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
| output = p.stderr.read() |
| retcode = p.wait() |
| if retcode != 0: |
| if self.verbose: |
| print output |
| raise OSError("Error running gpg import") |
| |
| def verify(self, file, signature_ext=".asc"): |
| signature = file + signature_ext |
| if not os.path.exists(signature): |
| raise OSError("Signature doesn't exist") |
| else: |
| cmd = [self.gpg_bin] |
| cmd.extend(self.args) |
| cmd.extend(['--verify', signature, file]) |
| p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
| output = p.stderr.read() |
| retcode = p.wait() |
| if retcode != 0: |
| if self.verbose: |
| print output |
| raise OSError("GPG verification FAILED") |
| |
| |
| def main(): |
| parser = OptionParser(usage="%prog -k keyfile dir [dir...]") |
| parser.add_option("-k", "--key-file", dest="keyfile", help="GPG key path") |
| parser.add_option("-x", "--exclude", dest="excludes", action="append", |
| help="exclude files") |
| parser.add_option("-v", "--verbose", dest="verbose", action="store_true", |
| default=False, help="print GPG output to stdout") |
| (options, args) = parser.parse_args() |
| |
| if not options.keyfile: |
| parser.error("Key path is reqiured") |
| |
| if len(args) < 1: |
| parser.error("At least one directory is required") |
| |
| tmphomedir = mkdtemp() |
| gpg = GnuPG(homedir=tmphomedir, verbose=options.verbose) |
| gpg.import_key(options.keyfile) |
| |
| errors = False |
| for dir in args: |
| files = findfiles(dir) |
| files = filter(supported_files_re.search, files) |
| if options.excludes: |
| for exclude in options.excludes: |
| exclude_re = re.compile(exclude) |
| files = filter(lambda x: not exclude_re.search(x), files) |
| for f in sorted(files): |
| try: |
| print "Verifying %s..." % f, |
| gpg.verify(f) |
| print "OK" |
| except OSError, e: |
| errors = True |
| print e |
| |
| rmtree(tmphomedir, ignore_errors=True) |
| |
| if errors: |
| raise SystemExit("FAILED") |
| |
| if __name__ == '__main__': |
| main() |