keyring-splitting program

Janusz A. Urbanowicz alex at bofh.torun.pl
Sun Mar 24 18:41:02 CET 2002


A non-text attachment was scrubbed...
Name: not available
Type: application/pgp
Size: 1025 bytes
Desc: not available
Url : /pipermail/attachments/20020324/000cb5d2/attachment.bin
-------------- next part --------------
#! /usr/bin/env python

'''Utility program for GNU Privacy Guard.

   This code runs under Python 1.5.2 on GNU/Linux. It should run on newer
   versions of Python as well. Some of the functions won't run on other
   architectures.

   Copyright 2002 Janusz A. Urbanowicz <alex at bofh.net.pl>

   $Id: gnupg.py,v 1.2.1.5 2002/03/24 17:16:07 alex Exp $

   This program is distributed under the terms opf GNU General Public License.
   Version 2 or later.

   When called as a program, exports every key in the public keyring to
   a file named by the key's 64 bit key ID in binary or ascii armored form.

   Optionally, binary mode and destination directory can be specified.
   For usage info, run the program with -h parameter.

   The program can be laso used as a Python module with following public
   functions: listkeys(), listkey(), simpledecrypt() and recipients().
   For description of those, refer to appropriate docstrings.
'''

import tempfile,os,re,popen2,sys,getopt,os.path


#
# Utility functions
#

def listkeys():
  "Returns a dictionary of long-keyid (key) and primary UID (value) for default keyring)"

  primaryre = re.compile('^pub:(?:-|u|r|f|d|m|q|e):[0-9]{3,4}?:(?:1|17):((?:[A-Z]|[0-9])+?):[0-9]{4}\-[0-9]{2}\-[0-9]{2}:(?:[0-9]{4}\-[0-9]{2}\-[0-9]{2})?:\w*?:\w*?:(.*?):\w*?:\w*?:')
  secondaryre = re.compile('^uid:(?:-|u|r|f|d|m|q|e)::::::::(.*?):')
  imagere = re.compile('^\[image of size [0-9]+?\]')

  klucze = {}
  
  gpghandle = os.popen('gpg --with-colons -k','r')
  gpgoutput = gpghandle.readlines()
  gpghandle.close()
  
  for i in range(len(gpgoutput)):
    result = primaryre.match(gpgoutput[i])
    try:
      keyid = result.groups()[0]
    except AttributeError:
      continue
    klucze[keyid] = result.groups()[1]
    if imagere.match(klucze[keyid]) == None:
      continue
    else:
      klucze[keyid] = None
      while primaryre.match(gpgoutput[i+1]) == None:
        i = i+1
        result = secondaryre.match(gpgoutput[i])
        try:
          klucze[keyid] = result.groups()[0]
          assert imagere.match(klucze[keyid]) == None
          break
        except AttributeError,AssertionError:
          pass
      if klucze[keyid] == None:
        del klucze[keyid]
        del keyid
        
  return klucze

def listkey(key):
  "Returns a dictionary of long-keyid (key) and primary UID (value) for a single key."

  primaryre = re.compile('^pub:(?:-|u|r|f|d|m|q|e):[0-9]{3,4}?:(?:1|17):((?:[A-Z]|[0-9])+?):[0-9]{4}\-[0-9]{2}\-[0-9]{2}:(?:[0-9]{4}\-[0-9]{2}\-[0-9]{2})?:\w*?:\w*?:(.*?):\w*?:\w*?:')
  secondaryre = re.compile('^uid:(?:-|u|r|f|d|m|q|e)::::::::(.*?):')
  imagere = re.compile('^\[image of size [0-9]+?\]')

  klucze = {}
  
  gpghandle = os.popen('gpg --with-colons -k %s' % key,'r')
  gpgoutput = gpghandle.readlines()
  gpghandle.close()
  
  for i in range(len(gpgoutput)):
    result = primaryre.match(gpgoutput[i])
    try:
      keyid = result.groups()[0]
    except AttributeError:
      continue
    klucze[keyid] = result.groups()[1]
    if imagere.match(klucze[keyid]) == None:
      continue
    else:
      klucze[keyid] = None
      while primaryre.match(gpgoutput[i+1]) == None:
        i = i+1
        result = secondaryre.match(gpgoutput[i])
        try:
          klucze[keyid] = result.groups()[0]
          assert imagere.match(klucze[keyid]) == None
          break
        except AttributeError,AssertionError:
          pass
      if klucze[keyid] == None:
        del klucze[keyid]
        del keyid
        
  return klucze

def simpledecrypt(passphrase,data):
  'Decrypt PGP encrypted data with supplied passphrase, the result is the return value'
  
  tempfilename = tempfile.mktemp()
  tempfile = open(tempfilename,'w')
  tempfile.write(data)
  tempfile.close()

  gpghandle = popen2.popen2('gpg --passphrase-fd 0 --batch --output - %s' % tempfilename)
  gpghandle[1].write(passphrase)
  gpghandle[1].close()
  data = gpghandle[0].read()
  gpghandle[0].close()

  os.unlink(tempfilename)
  
  return data

def recipients(data):
  "Returns a tuple of key IDs the message is encrypted to. Based on the code from GnuPG FAQ."

  gpghandle = popen2.popen2('gpg --batch --decrypt --list-only --status-fd 1')
  gpghandle[1].write(data)
  gpghandle[1].close()
  results = gpghandle[0].readlines()
  gpghandle[0].close()

  recipientre = re.compile('^\[GNUPG:\] ENC_TO ((?:[A-Z]|[0-9]){16}) .*$',re.MULTILINE)

  result = []

  for line in results:
    try:
      match = recipientre.search(line).groups()
    except AttributeError:
      continue

    result.append(match[0])

  return tuple(result)
  
#
# Splitkeyring code.
#

if __name__ == '__main__':

  dir = ''
  mode = '--armor'
  
  params,args = getopt.getopt(sys.argv[1:],'hd:b',['help','output-dir','binary'])
  
  for param in params:
    if '-h' in param or '--help' in param:
      print '%s $Revision: 1.2.1.5 $\n' % sys.argv[0]
      print 'Copyright 2002 Janusz A. Urbanowicz <alex at bofh.net.pl>.\n'
      print 'This program is distributed under the terms of GNU General Public License.'
      print 'Version 2 or later.\n'
      print 'Synopsis: %s [-d | --output-dir <output dir>] [-b | --binary]' % sys.argv[0]
      print '\nOptions: \n\n   -d, --output-dir   directtory to store the keys in (default: cwd)'
      print '   -b, --binary       export keys in binary form (default: off)'
      print '   -h, --help         this help message\n'
      sys.exit(0)

    if '-d' in param or '--output-dir' in param:
      try:
        dir = param[1]
      except:
        print 'No output directory supplied.'
        sys.exit(1)
      dir = os.path.abspath(dir)

    if '-b' in param or '--binary' in param:
      mode = ''

  lkeys = listkeys()

  for keyid in lkeys.keys():
    file = open(os.path.join(dir,keyid),'w+')
    if mode:
      file.write('%s\n\n' % lkeys[keyid])
    gpghandle = os.popen('gpg --quiet %s --batch --export %s' % (mode, keyid), 'r')
    data = gpghandle.readlines()
    gpghandle.close()
    file.writelines(data)
    file.close()


## Local Variables:
## mode: Python
## py-indent-offset: 2
## fill-column: 100
## End:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: gnupg.py.asc
Type: application/pgp
Size: 366 bytes
Desc: detached signature file
Url : /pipermail/attachments/20020324/000cb5d2/gnupg.py.bin


More information about the Gnupg-devel mailing list