? g-e-gpg.diff
Index: Makefile.am
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/Makefile.am,v
retrieving revision 1.43
diff -u -d -b -w -r1.43 Makefile.am
--- Makefile.am	27 Feb 2006 02:46:46 -0000	1.43
+++ Makefile.am	26 Jul 2006 14:47:13 -0000
@@ -4,11 +4,17 @@
 
 encrypt_la_LDFLAGS = -module -avoid-version
 
-encrypt_la_LIBADD = $(NSS_LIBS)
+encrypt_la_LIBADD = $(NSS_LIBS) $(LIBCRYPTUI_LIBS)
 
 encrypt_LTLIBRARIES = encrypt.la
 noinst_LIBRARIES =
 
+if WITH_CRYPTUI
+OPENPGP_SRCS = gpg.c \
+               gpg.h
+else
+OPENPGP_SRCS = 
+endif
 
 EXTRA_DIST	= \
 	Makefile.mingw \
@@ -38,8 +44,6 @@
 	cryptutil.h              \
 	encrypt.c                \
 	encrypt.h                \
-	gpg.c                    \
-	gpg.h                    \
 	icon_capable.xpm         \
 	icon_in_lock.xpm         \
 	icon_in_unlock.xpm       \
@@ -69,7 +73,8 @@
 	state_ui.c               \
    state_ui.h               \
    ge_ui.c                  \
-   ge_ui.h
+   ge_ui.h                  \
+   $(OPENPGP_SRCS)
 
 encryptpixdir = $(GAIM_DATADIR)/pixmaps/gaim/gaim-encryption
 encryptpix_DATA = crypto.png
@@ -84,7 +89,8 @@
 	-DGAIM_DATADIR=\"$(GAIM_DATADIR)\" \
 	$(GLIB_CFLAGS)                     \
 	$(GAIM_CFLAGS)                     \
-	$(NSS_CFLAGS)
+	$(NSS_CFLAGS)                      \
+	$(LIBCRYPTUI_CFLAGS)
 
 
 BUILT_SOURCES = gaim-encryption-config.h
Index: config_ui.c
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/config_ui.c,v
retrieving revision 1.44
diff -u -d -b -w -r1.44 config_ui.c
--- config_ui.c	22 Jan 2006 03:31:26 -0000	1.44
+++ config_ui.c	26 Jul 2006 14:47:13 -0000
@@ -65,6 +65,11 @@
    regen_window = NULL;
 }
 
+static void config_sensitive_button (GtkTreeSelection *selection, GtkWidget *button) 
+{    
+    gtk_widget_set_sensitive(button, gtk_tree_selection_get_selected(selection, NULL, NULL));
+}
+
 static void config_do_regen(GtkWidget* hitbutton, GtkWidget *key_list_view) {
    GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(key_list_view));
    GtkListStore *key_list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(key_list_view)));
@@ -148,8 +153,6 @@
 /* Display the Regenerate Key popup, and set up the above callbacks */
 /* (used as a callback from the main Config dialog, below)          */
 static void config_regen_key(GtkWidget* hitbutton, GtkWidget* key_list_view) {
-   GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(key_list_view));
-   
    GtkWidget *vbox, *hbox, *label, *table, *button;
    GList *proto_list = NULL;
    key_ring* iter;
@@ -157,7 +160,6 @@
    if (regen_window != NULL) return;
   
    GAIM_DIALOG(regen_window);
-   gtk_widget_set_size_request(regen_window, 300, 150);
    gtk_window_set_title(GTK_WINDOW(regen_window), _("Generate Keys"));
    g_signal_connect(G_OBJECT(regen_window), "destroy", 
                     GTK_SIGNAL_FUNC(config_cancel_regen), NULL);
@@ -167,25 +169,6 @@
    gtk_container_add(GTK_CONTAINER(regen_window), vbox);
    gtk_widget_show (vbox);
    
-   if (!gtk_tree_selection_get_selected(selection, NULL, NULL)) {
-      label = gtk_label_new(_("No key selected to re-generate!"));
-      gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
-      gtk_widget_show(label);
-      
-      hbox = gtk_hbox_new(FALSE, 2);
-      gtk_box_pack_end(GTK_BOX(vbox), hbox, 0, 0, 0);
-      gtk_widget_show(hbox);
-
-      button = gtk_button_new_with_label(_("OK"));
-      g_signal_connect(G_OBJECT(button), "clicked",
-                         GTK_SIGNAL_FUNC(config_cancel_regen), NULL);
-      gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
-      gtk_widget_set_size_request(button, 100, -1);
-      gtk_widget_show(button);
-      gtk_widget_show(regen_window);
-      return;
-   }
-
    /* Start 2 x 2 table */
    table = gtk_table_new(2, 2, FALSE);
    gtk_box_pack_start(GTK_BOX(vbox), table, 0, 0, 0);
@@ -215,13 +198,13 @@
    for( iter = crypt_proto_list; iter != NULL; iter = iter->next ) {
       proto_list = g_list_append(proto_list,
                                  ((crypt_proto *)iter->data)->name);
+      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "appending crypt_proto->name:'%s'\n", ((crypt_proto *)iter->data)->name);                         
    }
    gtk_combo_set_popdown_strings(GTK_COMBO (proto_combo), proto_list);
    g_list_free(proto_list);
    gtk_table_attach(GTK_TABLE(table), proto_combo, 1, 2, 0, 1,
                     0, 0, 0, 0);
 
-   gtk_widget_set_size_request(proto_combo, 85, -1);
    gtk_widget_show(proto_combo);
 
    key_size_entry = gtk_entry_new();
@@ -229,7 +212,6 @@
    gtk_entry_set_text(GTK_ENTRY(key_size_entry), "1024");
    gtk_table_attach(GTK_TABLE(table), key_size_entry, 1, 2, 1, 2,
                     0, 0, 0, 0);
-   gtk_widget_set_size_request(key_size_entry, 85, -1);
    gtk_widget_show(key_size_entry);
    /* End of 2x2 table */
    
@@ -237,22 +219,21 @@
    gtk_box_pack_start(GTK_BOX(vbox), regen_err_label, 0, 0, 0);
    gtk_widget_show(regen_err_label);
 
-   hbox = gtk_hbox_new(FALSE, 2);
+   hbox = gtk_hbutton_box_new();
    gtk_box_pack_end(GTK_BOX(vbox), hbox, 0, 0, 0);
    gtk_widget_show(hbox);
 
-   button = gtk_button_new_with_label(_("Cancel"));
+   button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(config_cancel_regen), NULL);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
-   gtk_widget_set_size_request(button, 100, -1);
    gtk_widget_show(button);
    
-   button = gtk_button_new_with_label(_("Ok"));
+   button = gtk_button_new_with_label(_("Generate Key"));
+   gtk_button_set_image(GTK_BUTTON (button), gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(config_do_regen), key_list_view);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
-   gtk_widget_set_size_request(button, 100, -1);
    gtk_widget_show(button);
    
    gtk_widget_show(regen_window);
@@ -471,6 +452,7 @@
    GtkWidget *button;
    GtkWidget *notebook;
    GtkWidget *checkbox_vbox;
+   GtkTreeSelection *selection;
 
    config_vbox = gtk_vbox_new(FALSE, 2);
 
@@ -538,6 +520,7 @@
    assert(Local_keylist_view == NULL);
    keybox = GE_create_key_vbox(&Local_keylist_view);
    GE_populate_key_list_view(GE_my_priv_ring, TRUE, GTK_TREE_VIEW(Local_keylist_view));
+   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (Local_keylist_view));
 
    hbox = gtk_hbox_new(FALSE, 2);
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
@@ -546,23 +529,34 @@
    gtk_widget_show(hbox);
 
    button = gtk_button_new_with_label(_("Delete Key"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(delete_local_key), Local_keylist_view);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
    
    button = gtk_button_new_with_label(_("Regenerate Key"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(config_regen_key), Local_keylist_view);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
 
    button = gtk_button_new_with_label(_("Copy Fingerprint to Clipboard"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(copy_fp_to_clipboard), Local_keylist_view);
    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
 
@@ -574,6 +568,7 @@
 
    keybox = GE_create_key_vbox(&Saved_keylist_view);
    GE_populate_key_list_view(GE_saved_buddy_ring, FALSE, GTK_TREE_VIEW(Saved_keylist_view));
+   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (Saved_keylist_view));
 
    hbox = gtk_hbox_new(FALSE, 2);
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
@@ -581,16 +576,24 @@
    gtk_widget_show(hbox);
 
    button = gtk_button_new_with_label(_("Delete Key"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(delete_buddy_key), Saved_keylist_view);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
    
    button = gtk_button_new_with_label(_("Copy Fingerprint to Clipboard"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(copy_fp_to_clipboard), Saved_keylist_view);
    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
 
@@ -602,6 +605,7 @@
 
    keybox = GE_create_key_vbox(&InMem_keylist_view);   
    GE_populate_key_list_view(GE_buddy_ring, FALSE, GTK_TREE_VIEW(InMem_keylist_view));
+   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (InMem_keylist_view));
 
    hbox = gtk_hbox_new(FALSE, 2);
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 2);
@@ -609,16 +613,24 @@
    gtk_widget_show(hbox);
 
    button = gtk_button_new_with_label(_("Delete Key"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(delete_buddy_key), InMem_keylist_view);
    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
    
    button = gtk_button_new_with_label(_("Copy Fingerprint to Clipboard"));
+   gtk_widget_set_sensitive (button, FALSE);
+   gtk_button_set_image (GTK_BUTTON (button), 
+                         gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_BUTTON));
    g_signal_connect(G_OBJECT(button), "clicked",
                     GTK_SIGNAL_FUNC(copy_fp_to_clipboard), InMem_keylist_view);
    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
+   g_signal_connect(G_OBJECT (selection), "changed", GTK_SIGNAL_FUNC(config_sensitive_button), button);
 
    gtk_widget_show(button);
 
Index: configure.ac
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/configure.ac,v
retrieving revision 1.30
diff -u -d -b -w -r1.30 configure.ac
--- configure.ac	25 Jun 2006 03:53:25 -0000	1.30
+++ configure.ac	26 Jul 2006 14:47:13 -0000
@@ -413,6 +413,84 @@
 CPPFLAGS="$GTK_CFLAGS $CPPFLAGS"
 
 
+dnl ****************************************************************************
+dnl DBUS
+dnl ****************************************************************************
+
+DBUS_GLIB_REQUIRED=0.35
+
+# Allow DBUS to be disabled
+AC_ARG_ENABLE(dbus, 
+        AC_HELP_STRING([--disable-dbus],
+        [Don't compile in key sharing]))
+
+if test "x$enable_dbus" = "xno"; then
+    echo "disabling dbus"
+else
+
+    PKG_CHECK_MODULES([DBUS], [dbus-glib-1 >= $DBUS_GLIB_REQUIRED],
+                      [enable_dbus=yes],[enable_dbus=no])
+    if test "$enable_dbus" = "yes"; then
+        AC_SUBST([DBUS_CFLAGS])
+        AC_SUBST([DBUS_LIBS])
+
+        AC_PATH_PROG([DBUS_BINDING_TOOL], [dbus-binding-tool], [no])
+
+        if test x$DBUS_BINDING_TOOL = "xno" ; then
+            AC_MSG_ERROR([dbus-binding-tool executable not found in your path - should be installed with dbus glib bindings])
+        fi
+
+        AC_DEFINE([WITH_DBUS],[1],[Define if DBUS support is enabled])
+    fi
+fi
+
+AM_CONDITIONAL(WITH_DBUS, test "$enable_dbus" != "no")
+
+dnl ***************
+dnl APPLET
+dnl ***************
+
+CRYPTUI_REQUIRED=0.0
+
+enable_openpgp=""
+with_cryptui="no"
+
+if test "$enable_dbus" != "yes"; then
+    echo "disabling OpenPGP Plugin: no dbus support"
+    
+else
+
+    # Allow applet to be disabled
+    AC_ARG_ENABLE(openpgp, 
+            AC_HELP_STRING([--disable-openpgp],
+            [Don't compile in openpgp support]))
+
+    # Applet tests 
+    if test "$enable_openpgp" = "no"; then
+        echo "disabling openpgp"
+    else
+        echo "checking for supported versions of libcryptui..."
+        
+        PKG_CHECK_MODULES([LIBCRYPTUI], [cryptui-0.0 >= $CRYPTUI_REQUIRED],
+                [enable_openpgp=yes],
+                [enable_openpgp=no])
+
+        if test "$enable_openpgp" = "yes"; then
+            echo "enabling OpenPGP Support..."
+            LIBCRYPTUI_CFLAGS="$LIBCRYPTUI_CFLAGS $DBUS_CFLAGS"
+            LIBCRYPTUI_LIBS="$LIBCRYPTUI_LIBS $DBUS_LIBS" 
+                
+            AC_SUBST(LIBCRYPTUI_CFLAGS)
+            AC_SUBST(LIBCRYPTUI_LIBS)
+            
+            AC_DEFINE(WITH_CRYPTUI, 1, [Build with OpenPGP Support])
+            with_cryptui=yes
+        fi
+    fi
+fi
+
+AM_CONDITIONAL(WITH_CRYPTUI, test "$enable_openpgp" = "yes")
+
 #
 # A little tomfoolery to make this buildable both in the gaim
 # structure and standalone
Index: cryptproto.h
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/cryptproto.h,v
retrieving revision 1.27
diff -u -d -b -w -r1.27 cryptproto.h
--- cryptproto.h	19 Dec 2005 03:39:22 -0000	1.27
+++ cryptproto.h	26 Jul 2006 14:47:13 -0000
@@ -23,6 +23,9 @@
 
 #include "rsa_nss.h"
 
+#if WITH_CRYPTUI
+#include "gpg.h"
+#endif
 
 
 /* Defined so that keys.h can use it: */
@@ -30,6 +33,9 @@
 /*   rsa_crypt_key rsa; */
 /*   RSA* rsa_ssl;      */
    RSA_NSS_KEY rsa_nss;
+#if WITH_CRYPTUI   
+   OPEN_PGP_KEY open_pgp;
+#endif   
 } proto_union;
 
 struct crypt_key;
Index: encrypt.c
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/encrypt.c,v
retrieving revision 1.153
diff -u -d -b -w -r1.153 encrypt.c
--- encrypt.c	25 Jun 2006 03:53:25 -0000	1.153
+++ encrypt.c	26 Jul 2006 14:47:13 -0000
@@ -1208,6 +1208,14 @@
       return FALSE;
    }
 
+#if WITH_CRYPTUI   
+   if (!open_pgp_init()) {
+      gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Loading OpenPGP protocol failed\n");
+   }
+#else
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP support is not  compiled in.\n");
+#endif
+
    GE_key_rings_init();
    GE_nonce_map_init();
    GE_state_ui_init();
Index: gpg.c
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/gpg.c,v
retrieving revision 1.9
diff -u -d -b -w -r1.9 gpg.c
--- gpg.c	19 Dec 2005 03:39:23 -0000	1.9
+++ gpg.c	26 Jul 2006 14:47:13 -0000
@@ -15,64 +15,520 @@
 /*   To compile and use:                                                  */
 /*     See INSTALL file.                                                  */
 
+#include <dbus/dbus-glib-bindings.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gi18n.h>
+
 #include "cryptproto.h"
 #include "gpg.h"
 #include "cryptutil.h"
 #include "keys.h"
 
+#define TYPE_G_STRING_VALUE_HASHTABLE \
+    (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
 
-char* gpg_proto_string="GPG 1.00";
+char* open_pgp_proto_string="OpenPGP 1.00";
 
-crypt_proto* gpg_proto;
+crypt_proto* open_pgp_proto;
 
 /*Functions exported through crypt_proto structure */
-static int              gpg_encrypt(unsigned char** encrypted, unsigned char* msg, int msg_len,
+static int                  open_pgp_encrypt(unsigned char** encrypted, unsigned char* msg, int msg_len,
                                     crypt_key* inkey);
-static int              gpg_decrypt(unsigned char** decrypted, unsigned char* msg, int msg_len,
+static int                  open_pgp_decrypt(unsigned char** decrypted, unsigned char* msg, int msg_len,
                                     crypt_key* inkey);
-static int              gpg_sign(unsigned char** signedmsg, unsigned char* msg, int msg_len,
+static int                  open_pgp_sign(unsigned char** signedmsg, unsigned char* msg, int msg_len,
                                  crypt_key* key, crypt_key* tokey);
-static int              gpg_auth(unsigned char** authed, unsigned char* msg, int msg_len,
+static int                  open_pgp_auth(unsigned char** authed, unsigned char* msg, int msg_len,
                                  crypt_key* key, const char* name);
-static crypt_key*       gpg_make_key_from_str(char *key_str);
-static GString*         gpg_key_to_gstr(crypt_key* inkey);
-static char*            gpg_parseable(char* key);
 
-void gpg_init(int isdefault) {
-	gpg_proto = g_malloc(sizeof(crypt_proto));
-	crypt_proto_list = g_slist_prepend(crypt_proto_list, gpg_proto);
+static int                  open_pgp_calc_unencrypted_size(struct crypt_key* key, int size);
+static int                  open_pgp_calc_unsigned_size(struct crypt_key* key, int size);
 
-   gpg_proto->encrypt = gpg_encrypt;
-   gpg_proto->decrypt = gpg_decrypt;
-   gpg_proto->sign = gpg_sign;
-   gpg_proto->auth = gpg_auth;
-   gpg_proto->make_key_from_str = gpg_make_key_from_str;
-   gpg_proto->key_to_gstr = gpg_key_to_gstr;
-	gpg_proto->parseable = gpg_parseable;
-   gpg_proto->name = gpg_proto_string;
+static crypt_key*           open_pgp_make_key_from_str(char *key_str);
+static GString*             open_pgp_key_to_gstr(crypt_key* inkey);
+static char*                open_pgp_parseable(char* key);
+static struct crypt_key*    open_pgp_parse_sent_key(char *);
+static GString*             open_pgp_make_sendable_key(struct crypt_key* key, const char* name);
+
+static gchar*               open_pgp_make_key_id(struct crypt_key* key);
+
+
+static struct crypt_key*    open_pgp_make_pub_from_priv(struct crypt_key* priv_key);
+static void                 open_pgp_free(struct crypt_key*);
+static void                 open_pgp_gen_key_pair(struct crypt_key **, struct crypt_key **,
+                                              const char* name, int keysize);
+
+/* -----------------------------------------------------------------------------
+ * Initialize Crypto 
+ */
+ 
+ /* Setup in init_crypt */
+DBusGConnection *dbus_connection = NULL;
+DBusGProxy      *dbus_key_proxy = NULL;
+DBusGProxy      *dbus_crypto_proxy = NULL;
+DBusGProxy      *dbus_remote_key_proxy = NULL;
+CryptUIKeyset   *dbus_keyset = NULL;
+
+static gboolean
+init_crypt ()
+{
+    GError *error = NULL;
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Initializing D-BUS Crypt Interface.\n");
+    
+    if (!dbus_connection) {
+        dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+        if (!dbus_connection) {
+            g_clear_error (&error);
+            return FALSE;
 }
 
-static int  gpg_encrypt(unsigned char** encrypted, unsigned char* msg, int msg_len,
+        dbus_key_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
+                                               "/org/gnome/seahorse/keys",
+                                               "org.gnome.seahorse.KeyService");
+        
+        dbus_crypto_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
+                                                       "/org/gnome/seahorse/crypto",
+                                                       "org.gnome.seahorse.CryptoService");
+                                               
+        dbus_remote_key_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse", 
+                                                           "/org/gnome/seahorse/keys/openpgp", 
+                                                           "org.gnome.seahorse.Keys");
+                                                           
+        dbus_keyset = cryptui_keyset_new ("openpgp");
+    }
+    
+    return TRUE;
+}
+
+/* -----------------------------------------------------------------------------
+ * Initialize Plugin 
+ */
+ 
+gboolean 
+open_pgp_init() {
+    gboolean open_pgp_loaded_ok = FALSE;
+    
+    open_pgp_loaded_ok = init_crypt ();
+    
+    if (open_pgp_loaded_ok != FALSE) {
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Loading OpenPGP protocol.\n");
+    	open_pgp_proto = g_new0 (crypt_proto, 1);
+    	crypt_proto_list = g_slist_prepend (crypt_proto_list, open_pgp_proto);
+
+        open_pgp_proto->encrypt = open_pgp_encrypt;
+        open_pgp_proto->decrypt = open_pgp_decrypt;
+        open_pgp_proto->sign = open_pgp_sign;
+        open_pgp_proto->auth = open_pgp_auth;
+
+        open_pgp_proto->calc_unencrypted_size = open_pgp_calc_unencrypted_size;
+        open_pgp_proto->calc_unsigned_size = open_pgp_calc_unsigned_size;
+
+        open_pgp_proto->make_key_from_str = open_pgp_make_key_from_str;
+        open_pgp_proto->key_to_gstr = open_pgp_key_to_gstr;
+        open_pgp_proto->parseable = open_pgp_parseable;
+        open_pgp_proto->parse_sent_key = open_pgp_parse_sent_key;
+        open_pgp_proto->make_sendable_key = open_pgp_make_sendable_key;
+        open_pgp_proto->make_key_id = open_pgp_make_key_id;
+        
+        open_pgp_proto->gen_key_pair = open_pgp_gen_key_pair;
+        open_pgp_proto->free = open_pgp_free;
+        open_pgp_proto->make_pub_from_priv = open_pgp_make_pub_from_priv;
+        
+        open_pgp_proto->name = open_pgp_proto_string;
+    }
+    
+    return open_pgp_loaded_ok;
+}
+
+static int  
+open_pgp_encrypt(unsigned char** encrypted, unsigned char* msg, int msg_len,
                         crypt_key* inkey)
-{ return 0;}
+{ 
+    gchar *keys[2];
+    gboolean ret;
+    GError *error = NULL;
 
-static int gpg_decrypt(unsigned char** decrypted, unsigned char* msg, int msg_len,
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP Encrypt to %s.\n", inkey->store.open_pgp.key);
+    
+    keys[1] = g_strdup(inkey->store.open_pgp.key);
+    keys[2] = NULL;
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Before OpenPGP Encryption.\n");
+    
+    ret = dbus_g_proxy_call (dbus_crypto_proxy, "EncryptText", &error, 
+                             G_TYPE_STRV, keys, 
+                             G_TYPE_STRING, NULL, 
+                             G_TYPE_INT, 0,
+                             G_TYPE_STRING, msg,
+                             G_TYPE_INVALID,
+                             G_TYPE_STRING, encrypted,
+                             G_TYPE_INVALID);
+                             
+    g_free(keys[1]);
+    
+    if (ret == TRUE) {
+        fprintf(stderr, "OpenPGP Encrypted text: %s.\n", *encrypted);
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP Encrypted text: %s.\n", *encrypted);
+        
+        fprintf(stderr, "Length of encrypted text: %d", strlen(*encrypted));
+        
+        return strlen (*encrypted);
+    } else {
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP Encryption Failed!\n", error ? error->message : "");
+        g_clear_error (&error);
+        
+        g_free (*encrypted);
+        *encrypted = NULL;
+        
+        return 0;
+    }
+}
+
+static int 
+open_pgp_decrypt(unsigned char** decrypted, unsigned char* msg, int msg_len,
                        crypt_key* inkey)
-{ return 0;}
+{ 
+    gchar *signer = NULL;
+    gboolean ret;
 
-static int gpg_sign(unsigned char** signedmsg, unsigned char* msg, int msg_len, crypt_key* key, crypt_key* tokey)
-{ return 0;}
+    ret = dbus_g_proxy_call (dbus_crypto_proxy, "DecryptText", NULL,
+                             G_TYPE_STRING, "openpgp",
+                             G_TYPE_INT, 0,
+                             G_TYPE_STRING, msg,
+                             G_TYPE_INVALID, 
+                             G_TYPE_STRING, decrypted,
+                             G_TYPE_STRING, &signer,
+                             G_TYPE_INVALID);
+    g_free (signer);
 
-static int gpg_auth(unsigned char** authed, unsigned char* msg, int msg_len, crypt_key* key, const char* name)
-{ return 0;}
+    if (ret == TRUE)
+        return strlen (*decrypted);
+    else {
+        g_free (*decrypted);
+        *decrypted = NULL;
+        return 0;
+    }
+}
 
-static crypt_key* gpg_make_key_from_str(char *key_str)
- { return 0;}
-static GString* gpg_key_to_gstr(crypt_key* key)
- { return 0;}
-static char* gpg_parseable(char* key)
- { return 0; }
+static int 
+open_pgp_sign(unsigned char** signedmsg, unsigned char* msg, int msg_len, crypt_key* key, crypt_key* tokey)
+{ 
+    gchar *signer = g_strdup(key->store.open_pgp.key);
+    gboolean ret;
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Before OpenPGP Signing.\n");
+    
+    ret = dbus_g_proxy_call (dbus_crypto_proxy, "SignText", NULL,
+                             G_TYPE_STRING, signer,
+                             G_TYPE_INT, 0,
+                             G_TYPE_STRING, msg,
+                             G_TYPE_INVALID, 
+                             G_TYPE_STRING, signedmsg,
+                             G_TYPE_INVALID);
+    g_free (signer);
+    
+    if (ret == TRUE) {
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP Signed Text: %s\n", *signedmsg);
+        return strlen (*signedmsg);
+    } else {
+        g_free (*signedmsg);
+        *signedmsg = NULL;
+        return 0;
+    }
+}
+
+static int open_pgp_auth(unsigned char** authed, unsigned char* msg, int msg_len, crypt_key* key, const char* name)
+{ 
+    gboolean ret;
+    gchar *signer = NULL;
+
+    ret = dbus_g_proxy_call (dbus_crypto_proxy, "VerifyText", NULL,
+                             G_TYPE_STRING, "openpgp",
+                             G_TYPE_INT, 0,
+                             G_TYPE_STRING, msg,
+                             G_TYPE_INVALID, 
+                             G_TYPE_STRING, &authed,
+                             G_TYPE_STRING, &signer,
+                             G_TYPE_INVALID);
+    
+    if (ret == TRUE) {
+        /* Not interested in the signer */
+        g_free (signer);
+        return strlen (*authed);
+        
+    } else {
+        g_free (*authed);
+        *authed = NULL;
+        return 0;
+    }
+}
+
+static int
+open_pgp_calc_unencrypted_size(struct crypt_key* key, int size)
+{
+    return 1024;
+}
+
+static int
+open_pgp_calc_unsigned_size(struct crypt_key* key, int size)
+{
+    return 1024;
+}
+
+static crypt_key*
+open_pgp_build_key (char *key_str)
+{
+    gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Start building key %s.\n", key_str);
+    crypt_key *key = NULL;
+    gboolean ret;
+    const gchar* fields[] = {
+        "fingerprint",
+        "display-id",
+        "trust",
+        "enc-type", 
+        "flags",
+        "length",
+        NULL
+    };
+    GHashTable *props = NULL;
+    GValue *value;
+    GError *error = NULL;
+        
+    ret = dbus_g_proxy_call (dbus_remote_key_proxy, "GetKeyFields", &error,
+                            G_TYPE_STRING, key_str,
+                            G_TYPE_STRV, fields,
+                            G_TYPE_INVALID,
+                            TYPE_G_STRING_VALUE_HASHTABLE, &props,
+                            G_TYPE_INVALID);
+    
+    gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Fields retreived. props: %s, ret: %s\n", (props != NULL)? "NOT NULL":"NULL", ret ? "TRUE":"FALSE");
+                            
+    if ((ret == TRUE) && (props != NULL)) {
+        key = g_new0 (crypt_key, 1);
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Key Struct created.\n");
+        
+        key->proto = open_pgp_proto;
+        
+        key->store.open_pgp.key = g_strdup (key_str);
+        
+        value = g_hash_table_lookup (props, fields[0]);
+        if G_VALUE_HOLDS (value, G_TYPE_STRING)
+            strncpy (key->fingerprint, g_value_dup_string (value), KEY_FINGERPRINT_LENGTH);
+        
+        value = g_hash_table_lookup (props, fields[1]);
+        if G_VALUE_HOLDS (value, G_TYPE_STRING)
+            strncpy (key->digest, g_value_dup_string (value), KEY_DIGEST_LENGTH);
+            
+        value = g_hash_table_lookup (props, fields[2]);
+        if G_VALUE_HOLDS (value, G_TYPE_UINT)
+            key->store.open_pgp.validity = (CryptUIValidity) g_value_get_uint (value);
+        
+        value = g_hash_table_lookup (props, fields[3]);
+        if G_VALUE_HOLDS (value, G_TYPE_INT)
+            key->store.open_pgp.enc_type = (CryptUIEncType) g_value_get_int (value);
+            
+        value = g_hash_table_lookup (props, fields[4]);
+        if G_VALUE_HOLDS (value, G_TYPE_UINT)
+            key->store.open_pgp.flags = (CryptUIKeyFlags) g_value_get_uint (value);
+        
+        value = g_hash_table_lookup (props, fields[5]);
+        if G_VALUE_HOLDS (value, G_TYPE_UINT) {
+            key->store.open_pgp.length = g_value_get_uint (value);
+            gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Length set: %u.\n", key->store.open_pgp.length);
+            snprintf (key->length, sizeof (key->length), "%u", key->store.open_pgp.length);
+        }
+
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Key Struct creation finished.\n");
+        
+        g_hash_table_destroy (props);
+    } else {
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "dbus call to get key fields failed: %s\n", error ? error->message : "");
+        g_clear_error (&error);
+    }
+    
+    return key;
+}
+
+static crypt_key* 
+open_pgp_make_key_from_str (char *key_str)
+{
+    crypt_key *key = NULL;
+    gboolean ret;
+    gchar *keyids[2], **keys;
+    
+    if (!strncmp ("openpgp:", key_str, 7))
+        key = open_pgp_build_key (key_str);
+    else {
+        keyids[0] = g_strdup (key_str);
+        keyids[1] = NULL;
+        
+        ret = dbus_g_proxy_call (dbus_key_proxy, "DiscoverKeys", NULL,
+                                 G_TYPE_STRV, keyids,
+                                 G_TYPE_INT, 0,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRV, &keys,
+                                 G_TYPE_INVALID);
+                                 
+        if ((ret == TRUE) && (*keys[1] != '\0')) {
+            key = open_pgp_build_key (keys[1]);
+            g_strfreev (keys);
+        }
+        
+        g_free(keyids[1]);
+    }
+    
+    return key;
+}
+
+static GString* 
+open_pgp_key_to_gstr (crypt_key* key)
+{ 
+    GString *outString = g_string_new("");
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP Before GStr generated\n");
+    
+    g_string_append(outString, key->store.open_pgp.key);
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "OpenPGP GStr generated\n");
+    
+    return outString;
+}
+
+static char* 
+open_pgp_parseable (char* key)
+{ 
+    /* If the key is ours, return a pointer to the ':' after our token 
+     * otherwise return 0                                              
+     * if we were more sophisticated, we could look for older versions 
+     * of our protocol here, and accept them too.                      
+     */
+    
+    if (strncmp(open_pgp_proto_string, key, strlen(open_pgp_proto_string)) == 0) {
+        return key + strlen(open_pgp_proto_string);
+    } else {
+        return 0;
+    }
+}
+
+static struct crypt_key*
+open_pgp_parse_sent_key (char *key_str)
+{
+    gchar** split_key = g_strsplit(key_str, ",", 2);
+    crypt_key* key;
+
+    if ((split_key[0] == 0) || (split_key[1] == 0)) {
+        gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error parsing OpenPGP nonce/key\n");
+        return 0;
+    }
+
+    gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Before making key from string: %s\n", split_key[1]);
+
+    key = open_pgp_make_key_from_str(split_key[1]);
+
+    if (key != NULL) {
+        GE_str_to_nonce(&key->store.open_pgp.nonce, split_key[0]);
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Received Nonce with key: %s\n", split_key[0]);
+    } else {
+        gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Making key from string failed: %s\n", split_key[1]);
+    }
 
+    g_strfreev(split_key);
 
+    return key;
+}
 
+    static GString*
+open_pgp_make_sendable_key (struct crypt_key* key, const char* name)
+{
+    GString *outString = NULL;
+    gchar* nonce_str;
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Begin making sendable OpenPGP key.\n");
+    
+    outString = g_string_new("");
+    
+    nonce_str = GE_new_incoming_nonce (name);
+    g_string_append (outString, nonce_str);
+
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Sending Nonce with key: %s\n", nonce_str);
+
+    g_free (nonce_str);
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "nonce_str freed\n");
+    
+    g_string_append (outString, ",");
+    
+    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Sending Keyid: %s\n", key->store.open_pgp.key + strlen("openpgp:") + 8);
+    
+    g_string_append (outString, key->store.open_pgp.key);
+    
+    return outString;
+}
 
+static gchar*
+open_pgp_make_key_id (struct crypt_key* inkey)
+{
+    return GE_nonce_to_str(&inkey->store.rsa_nss.nonce);
+}
+
+static struct crypt_key*    
+open_pgp_make_pub_from_priv (struct crypt_key* priv_key)
+{
+    crypt_key *pub_key = NULL;
+    
+    if (priv_key->store.open_pgp.enc_type == CRYPTUI_ENCTYPE_PRIVATE) {
+        pub_key = g_new0 (crypt_key, 1);
+        
+        pub_key->proto = open_pgp_proto;
+        strcpy (pub_key->length, priv_key->length);
+        strncpy (pub_key->digest, priv_key->digest, KEY_DIGEST_LENGTH);
+        strncpy (pub_key->fingerprint, priv_key->fingerprint, KEY_FINGERPRINT_LENGTH);
+
+        pub_key->store.open_pgp.key = g_strdup (priv_key->store.open_pgp.key);
+        pub_key->store.open_pgp.validity = priv_key->store.open_pgp.validity;
+        pub_key->store.open_pgp.enc_type = priv_key->store.open_pgp.enc_type;
+        pub_key->store.open_pgp.flags = priv_key->store.open_pgp.flags;
+    }
+    
+    return pub_key;
+}
+
+static void
+open_pgp_free (struct crypt_key *key)
+{    
+    g_free (key->store.open_pgp.key);
+    key->store.open_pgp.key = NULL;
+}
+
+static void
+open_pgp_gen_key_pair (struct crypt_key **pub_key, struct crypt_key **priv_key,
+                 const char* name, int keysize)
+{
+    gchar *key = cryptui_prompt_signer (dbus_keyset, _("Choose a key to use for signing messages."));
+    
+    gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Selected key: %s\n", key);
+    
+    *pub_key = open_pgp_build_key (key);
+    
+    if (*pub_key != NULL) {
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Public Key:\n\tlength: %s\n\tdigest: %s\n\tfingerprint: %s\n", 
+                                     (*pub_key)->length,
+                                     (*pub_key)->digest,
+                                     (*pub_key)->fingerprint);
+    } else {
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Creation of public key failed.\n");
+    }
+                                     
+    *priv_key = open_pgp_build_key (key);
+    
+    if (*priv_key != NULL) {
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Private Key:\n\tlength: %s\n\tdigest: %s\n\tfingerprint: %s\n", 
+                                     (*priv_key)->length,
+                                     (*priv_key)->digest,
+                                     (*priv_key)->fingerprint);
+    } else {
+        gaim_debug (GAIM_DEBUG_INFO, "gaim-encryption", "Creation of private key failed.\n");
+    }
+}
Index: gpg.h
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/gpg.h,v
retrieving revision 1.2
diff -u -d -b -w -r1.2 gpg.h
--- gpg.h	7 Jul 2003 01:36:51 -0000	1.2
+++ gpg.h	26 Jul 2006 14:47:13 -0000
@@ -1,5 +1,5 @@
-/*     Fake wrapper to illustrate using a different encryption protocol   */
-/*             Copyright (C) 2001-2003 William Tompkins                   */
+/*           OpenPGP keys for the Gaim encryption plugin                  */
+/*                Copyright (C) 2006 Adam Schreiber                       */
 
 /* This plugin is free software, distributed under the GNU General Public */
 /* License.                                                               */
@@ -18,10 +18,20 @@
 #ifndef GPG_H
 #define GPG_H
 
-struct gpg_crypt_key { };
+#include <libcryptui/cryptui.h>
 
-typedef struct gpg_crypt_key gpg_crypt_key;
+#include "gaim-encryption-config.h"
+#include "nonce.h"
 
-void gpg_init(int isdefault);
+typedef struct { 
+    gchar *key;
+    CryptUIValidity validity;
+    CryptUIEncType  enc_type;
+    CryptUIKeyFlags flags;
+    guint           length;
+    Nonce           nonce;
+} OPEN_PGP_KEY;
+
+extern gboolean open_pgp_init(void);
 
 #endif
Index: keys.c
===================================================================
RCS file: /cvsroot/gaim-encryption/encrypt/keys.c,v
retrieving revision 1.76
diff -u -d -b -w -r1.76 keys.c
--- keys.c	25 Jun 2006 03:53:25 -0000	1.76
+++ keys.c	26 Jul 2006 14:47:13 -0000
@@ -412,6 +412,8 @@
 
    g_snprintf(path, sizeof(path), "%s%s%s", get_base_key_path(), G_DIR_SEPARATOR_S, filename);
 
+   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Path created: %s\n", path);
+
    fd = g_open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    if (fd == -1) {
       gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error opening key file %s for write\n", path);
@@ -451,6 +453,8 @@
    } 
 #endif
 
+   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Before generating saved text\n");
+
    line_str = g_string_new(key->name);
    GE_escape_name(line_str);
    if (key->account) {
@@ -458,8 +462,15 @@
    } else {
       g_string_append(line_str, ",");
    }
+   
+   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Before adding protocol name. %s\n", key->key->proto->name);
+   
    g_string_append_printf(line_str, " %s ", key->key->proto->name);
+   
+   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Before generating key text\n");
+   
    key_str = GE_key_to_gstr(key->key);
+   
    g_string_append(line_str, key_str->str);
 
    gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "here\n");
