Package common :: Module GnuPGInterface
[hide private]
[frames] | no frames]

Module GnuPGInterface

source code

Interface to GNU Privacy Guard (GnuPG)

GnuPGInterface is a Python module to interface with GnuPG. It concentrates on interacting with GnuPG via filehandles, providing access to control GnuPG via versatile and extensible means.

This module is based on GnuPG::Interface, a Perl module by the same author.

Normally, using this module will involve creating a GnuPG object, setting some options in it's 'options' data member (which is of type Options), creating some pipes to talk with GnuPG, and then calling the run() method, which will connect those pipes to the GnuPG process. run() returns a Process object, which contains the filehandles to talk to GnuPG with.

Example code:

>>> import GnuPGInterface
>>>
>>> plaintext  = "Three blind mice"
>>> passphrase = "This is the passphrase"
>>>
>>> gnupg = GnuPGInterface.GnuPG()
>>> gnupg.options.armor = 1
>>> gnupg.options.meta_interactive = 0
>>> gnupg.options.extra_args.append('--no-secmem-warning')
>>>
>>> # Normally we might specify something in
>>> # gnupg.options.recipients, like
>>> # gnupg.options.recipients = [ '0xABCD1234', 'bob@foo.bar' ]
>>> # but since we're doing symmetric-only encryption, it's not needed.
>>> # If you are doing standard, public-key encryption, using
>>> # --encrypt, you will need to specify recipients before
>>> # calling gnupg.run()
>>>
>>> # First we'll encrypt the test_text input symmetrically
>>> p1 = gnupg.run(['--symmetric'],
...                create_fhs=['stdin', 'stdout', 'passphrase'])
>>>
>>> p1.handles['passphrase'].write(passphrase)
>>> p1.handles['passphrase'].close()
>>>
>>> p1.handles['stdin'].write(plaintext)
>>> p1.handles['stdin'].close()
>>>
>>> ciphertext = p1.handles['stdout'].read()
>>> p1.handles['stdout'].close()
>>>
>>> # process cleanup
>>> p1.wait()
>>>
>>> # Now we'll decrypt what we just encrypted it,
>>> # using the convience method to get the
>>> # passphrase to GnuPG
>>> gnupg.passphrase = passphrase
>>>
>>> p2 = gnupg.run(['--decrypt'], create_fhs=['stdin', 'stdout'])
>>>
>>> p2.handles['stdin'].write(ciphertext)
>>> p2.handles['stdin'].close()
>>>
>>> decrypted_plaintext = p2.handles['stdout'].read()
>>> p2.handles['stdout'].close()
>>>
>>> # process cleanup
>>> p2.wait()
>>>
>>> # Our decrypted plaintext:
>>> decrypted_plaintext
'Three blind mice'
>>>
>>> # ...and see it's the same as what we orignally encrypted
>>> assert decrypted_plaintext == plaintext,           "GnuPG decrypted output does not match original input"
>>>
>>>
>>> ##################################################
>>> # Now let's trying using run()'s attach_fhs paramter
>>>
>>> # we're assuming we're running on a unix...
>>> input = open('/etc/motd')
>>>
>>> p1 = gnupg.run(['--symmetric'], create_fhs=['stdout'],
...                                 attach_fhs={'stdin': input})
>>>
>>> # GnuPG will read the stdin from /etc/motd
>>> ciphertext = p1.handles['stdout'].read()
>>>
>>> # process cleanup
>>> p1.wait()
>>>
>>> # Now let's run the output through GnuPG
>>> # We'll write the output to a temporary file,
>>> import tempfile
>>> temp = tempfile.TemporaryFile()
>>>
>>> p2 = gnupg.run(['--decrypt'], create_fhs=['stdin'],
...                               attach_fhs={'stdout': temp})
>>>
>>> # give GnuPG our encrypted stuff from the first run
>>> p2.handles['stdin'].write(ciphertext)
>>> p2.handles['stdin'].close()
>>>
>>> # process cleanup
>>> p2.wait()
>>>
>>> # rewind the tempfile and see what GnuPG gave us
>>> temp.seek(0)
>>> decrypted_plaintext = temp.read()
>>>
>>> # compare what GnuPG decrypted with our original input
>>> input.seek(0)
>>> input_data = input.read()
>>>
>>> assert decrypted_plaintext == input_data,            "GnuPG decrypted output does not match original input"

To do things like public-key encryption, simply pass do something like:

gnupg.passphrase = 'My passphrase' gnupg.options.recipients = [ 'bob@foobar.com' ] gnupg.run( ['--sign', '--encrypt'], create_fhs=..., attach_fhs=...)

Here is an example of subclassing GnuPGInterface.GnuPG, so that it has an encrypt_string() method that returns ciphertext.

>>> import GnuPGInterface
>>>
>>> class MyGnuPG(GnuPGInterface.GnuPG):
...
...     def __init__(self):
...         GnuPGInterface.GnuPG.__init__(self)
...         self.setup_my_options()
...
...     def setup_my_options(self):
...         self.options.armor = 1
...         self.options.meta_interactive = 0
...         self.options.extra_args.append('--no-secmem-warning')
...
...     def encrypt_string(self, string, recipients):
...        gnupg.options.recipients = recipients   # a list!
...
...        proc = gnupg.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
...
...        proc.handles['stdin'].write(string)
...        proc.handles['stdin'].close()
...
...        output = proc.handles['stdout'].read()
...        proc.handles['stdout'].close()
...
...        proc.wait()
...        return output
...
>>> gnupg = MyGnuPG()
>>> ciphertext = gnupg.encrypt_string("The secret", ['0x260C4FA3'])
>>>
>>> # just a small sanity test here for doctest
>>> import types
>>> assert isinstance(ciphertext, types.StringType),            "What GnuPG gave back is not a string!"

Here is an example of generating a key: >>> import GnuPGInterface >>> gnupg = GnuPGInterface.GnuPG() >>> gnupg.options.meta_interactive = 0 >>> >>> # We will be creative and use the logger filehandle to capture >>> # what GnuPG says this time, instead stderr; no stdout to listen to, >>> # but we capture logger to surpress the dry-run command. >>> # We also have to capture stdout since otherwise doctest complains; >>> # Normally you can let stdout through when generating a key. >>> >>> proc = gnupg.run(['--gen-key'], create_fhs=['stdin', 'stdout', ... 'logger']) >>> >>> proc.handles['stdin'].write('''Key-Type: DSA ... Key-Length: 1024 ... # We are only testing syntax this time, so dry-run ... %dry-run ... Subkey-Type: ELG-E ... Subkey-Length: 1024 ... Name-Real: Joe Tester ... Name-Comment: with stupid passphrase ... Name-Email: joe@foo.bar ... Expire-Date: 2y ... Passphrase: abc ... %pubring foo.pub ... %secring foo.sec ... ''') >>> >>> proc.handles['stdin'].close() >>> >>> report = proc.handles['logger'].read() >>> proc.handles['logger'].close() >>> >>> proc.wait()


Version: 0.3.2

Author: Frank J. Tobin, ftobin@neverending.org

Classes [hide private]
  GnuPG
Class instances represent GnuPG
  Pipe
Simple struct holding stuff about pipes we use
  Options
Objects of this class encompass options passed to GnuPG.
  Process
Objects of this class encompass properties of a GnuPG process spawned by GnuPG.run()
  GnuPGInterface
Class instances represent GnuPG
Functions [hide private]
 
_run_doctests() source code
Variables [hide private]
  __revision__ = '$Id: GnuPGInterface.py,v 1.22 2002/01/11 20:22...
  _stds = ['stdin', 'stdout', 'stderr']
  _fd_modes = {'command': 'w', 'logger': 'r', 'passphrase': 'w',...
  _fd_options = {'command': '--command-fd', 'logger': '--logger-...

Imports: os, sys, fcntl


Function Details [hide private]

_run_doctests()

source code 

Variables Details [hide private]

__revision__

Value:
'$Id: GnuPGInterface.py,v 1.22 2002/01/11 20:22:04 ftobin Exp $'

_stds

Value:
['stdin', 'stdout', 'stderr']

_fd_modes

Value:
{'command': 'w',
 'logger': 'r',
 'passphrase': 'w',
 'status': 'r',
 'stderr': 'r',
 'stdin': 'w',
 'stdout': 'r'}

_fd_options

Value:
{'command': '--command-fd',
 'logger': '--logger-fd',
 'passphrase': '--passphrase-fd',
 'status': '--status-fd'}