Sunday, January 06, 2008

GPG Encryption for TextMate

Here is a wxPython based encryption script for TextMate, it presents a dialog box for selection of the key. Set default_gpg_user to the user you normally use for encryption.


#!/usr/bin/env python
import os, sys, tempfile, traceback
from subprocess import *
import wx

default_gpg_user = "brianlane"

exit_discard = 200
exit_show_tooltip = 206

def GetRecipient():
keys = GetGpgKeys()
key_list = []
user_idx = 0
i=0
for k in keys:
if k[0] == "uid":
s = " %s %s" % (k[9],k[5])
else:
s = "%s %s %s" % (k[9],k[5],k[4])
key_list += [s]
if k[9].find(default_gpg_user) > -1:
user_idx = i
i += 1

dialog = wx.SingleChoiceDialog(None, "Select a GPG Key", "Encrypt Text with GPG", key_list)
dialog.SetSelection(user_idx)
dialog.SetSize((400,200))
key_info = None
if dialog.ShowModal() == wx.ID_OK:
key_info = keys[dialog.GetSelection()]
dialog.Destroy()

return key_info


def GpgEncryptFile( gpg_file, gpg_recipient ):
cmd = 'gpg -qeaR "%s" --batch --output - %s' % (gpg_recipient, gpg_file)
p = Popen( cmd, shell=True, stdout=PIPE, stderr=PIPE )
output = ""
for line in p.stdout:
output += line
stderr = ""
for line in p.stderr:
stderr += line

return output, stderr


def rmfile( file_path ):
if os.path.exists(file_path):
os.unlink(file_path)

def GetGpgKeys():
cmd = "gpg --list-keys --with-colons"
p = Popen( cmd, shell=True, stdout=PIPE, stderr=PIPE )
key_list = []
for k in p.stdout:
key_args = k.strip().split(':')
if key_args[0] in ['pub']:
key_list += [key_args]
return key_list


app = wx.PySimpleApp()

key_info = GetRecipient()
if not key_info:
exit(exit_discard)

# Get the input for gpg
gpg_input = sys.stdin.read()

# Write it to a secure file
(out_fp, out_path) = tempfile.mkstemp()
os.write(out_fp,gpg_input)
os.close(out_fp)

try:
gpg_armour, gpg_error = GpgEncryptFile(out_path, key_info[4])
if not gpg_armour:
rmfile(out_path)
sys.stdout.write(gpg_error)
exit(exit_show_tooltip)
sys.stdout.write(gpg_armour)
except:
rmfile(out_path)
traceback.print_exc(file=sys.stdout)
exit(exit_show_tooltip)

rmfile(out_path)

No comments: