[PATCH] gpg2 support for seahorse

Deal with --data format of gpg-agent in version 2.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>

----

Index: configure.in
===================================================================
--- configure.in	(revision 1548)
+++ configure.in	(working copy)
@@ -83,8 +83,7 @@
 	DO_CHECK=$enableval, DO_CHECK=yes)
 	
 if test	"$DO_CHECK" = "yes"; then
-  major_versions="1"
-  minor_versions="2 4"
+  accepted_versions="1.2 1.4 2.0"
   AC_PATH_PROG(GNUPG, gpg, no)
   ok="no"
   if test "$GNUPG" != "no"; then
@@ -97,41 +96,21 @@
 	micro=`echo $gnupg_version | \
 		sed 's/^gpg (GnuPG) \([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
     
-    for ver in $major_versions; do
-      if test "$ver" = "$major"; then
-            
-        if test "1" = "$major"; then
-          AC_DEFINE(GPG_MAJOR, 1,[GPG Major Version])
-        fi
-        
-        # Check the minor version 
-        for ver2 in $minor_versions; do
-          if test "$ver2" = "$minor"; then
-                    
-            if test "2" = "$minor"; then
-              AC_DEFINE(GPG_MINOR,2,[GPG Minor Version])
-            fi
-            
-            if test "4" = "$minor"; then
-              AC_DEFINE(GPG_MINOR,4,[GPG Minor Version])
-            fi            
-            
-            ok="yes"
-            break
-                    
-          fi
-        done
+    for ver in $accepted_versions; do
+      if test "$ver" = "$major.$minor"; then
+        AC_DEFINE_UNQUOTED(GPG_MAJOR, [$major], [GPG Major Version])
+        AC_DEFINE_UNQUOTED(GPG_MINOR, [$minor], [GPG Minor Version])
+        ok="yes"
         break
-            
       fi
     done
     
   fi
   
   if test "$ok" = "yes"; then
-	AC_MSG_RESULT(yes)
+	AC_MSG_RESULT([yes])
   else
-	AC_MSG_ERROR(Appropriate version of GnuPG not found. Please install version 1.2.x or 1.4.x)
+	AC_MSG_ERROR([Appropriate version of GnuPG not found. Please install versions $accepted_versions])
   fi
 
 fi
Index: agent/seahorse-agent-actions.c
===================================================================
--- agent/seahorse-agent-actions.c	(revision 1548)
+++ agent/seahorse-agent-actions.c	(working copy)
@@ -98,7 +98,7 @@
 
 /* Called for the assuan GET_PASSPHRASE command */
 void
-seahorse_agent_actions_getpass (SeahorseAgentConn * rq, gchar * id,
+seahorse_agent_actions_getpass (SeahorseAgentConn * rq, gboolean pass_as_data, gchar * id,
                                 gchar * errmsg, gchar * prompt, gchar * desc)
 {
     SeahorseAgentPassReq *pr;
@@ -113,9 +113,15 @@
          * just reply now, without going to the queue.
          */
         if ((pass = seahorse_agent_cache_get (id)) != NULL) {
-            enc = encode_password (pass);
-            seahorse_agent_io_reply (rq, TRUE, enc);
-            seahorse_secure_memory_free (enc);
+	    if (pass_as_data) {
+                seahorse_agent_io_data (rq, pass);
+                seahorse_agent_io_reply (rq, TRUE, NULL);
+	    }
+	    else {
+                enc = encode_password (pass);
+                seahorse_agent_io_reply (rq, TRUE, enc);
+                seahorse_secure_memory_free (enc);
+	    }
             return;
         }
     }
@@ -123,6 +129,7 @@
     /* A new queue item */
     pr = g_chunk_new (SeahorseAgentPassReq, g_memory);
     memset (pr, 0, sizeof (*pr));
+    pr->pass_as_data = pass_as_data;
     pr->id = id ? g_strdup (id) : NULL;
     pr->errmsg = errmsg ? g_strdup (errmsg) : NULL;
     pr->prompt = g_strdup (prompt ? prompt : _("Passphrase:"));
@@ -183,9 +190,15 @@
     if (pass == NULL)
         seahorse_agent_io_reply (pr->request, FALSE, "111 cancelled");
     else {
-        enc = encode_password (pass);
-        seahorse_agent_io_reply (pr->request, TRUE, enc);
-        seahorse_secure_memory_free (enc);
+        if (pr->pass_as_data) {
+            seahorse_agent_io_data (pr->request, pass);
+            seahorse_agent_io_reply (pr->request, TRUE, NULL);
+	}
+	else {
+            enc = encode_password (pass);
+            seahorse_agent_io_reply (pr->request, TRUE, enc);
+            seahorse_secure_memory_free (enc);
+	}
     }
 
     free_passreq (pr);
Index: agent/seahorse-agent-io.c
===================================================================
--- agent/seahorse-agent-io.c	(revision 1548)
+++ agent/seahorse-agent-io.c	(working copy)
@@ -102,6 +102,7 @@
 /* Responses */
 #define ASS_OK      "OK "
 #define ASS_ERR     "ERR "
+#define ASS_DATA    "D "
 #define NL          "\n"
 
 /* -------------------------------------------------------------------------- */
@@ -369,10 +370,12 @@
     }
 
     else if (strcasecmp (string, ASS_GETPASS) == 0) {
+    	gchar *tmp;
         gchar *id;
         gchar *errmsg;
         gchar *prompt;
         gchar *description;
+	gboolean pass_as_data = FALSE;
 
         /* We don't answer this unless it's from the right terminal */
         if (!cn->terminal_ok) {
@@ -381,7 +384,13 @@
             return;
         }
                 
-        split_arguments (args, &id, &errmsg, &prompt, &description, NULL);
+	if (strstr (args, "--data") != NULL) {
+		pass_as_data = TRUE;
+	        split_arguments (args, &tmp, &tmp, &id, &errmsg, &prompt, &description, NULL);
+	}
+	else {
+	        split_arguments (args, &id, &errmsg, &prompt, &description, NULL);
+	}
 
         if (!id || !errmsg || !prompt || !description) {
             seahorse_agent_io_reply (cn, FALSE, "105 parameter error");
@@ -398,7 +407,7 @@
         if (is_null_argument (description))
             description = NULL;
 
-        seahorse_agent_actions_getpass (cn, id, errmsg, prompt, description);
+        seahorse_agent_actions_getpass (cn, pass_as_data, id, errmsg, prompt, description);
     }
 
     else if (strcasecmp (string, ASS_CLRPASS) == 0) {
@@ -554,6 +563,29 @@
     return;
 }
 
+void
+seahorse_agent_io_data (SeahorseAgentConn *cn, const gchar *data)
+{
+    int fd;
+
+    /* The connection could have closed in the meantime */
+    if (!is_valid_conn (cn))
+        return;
+
+    DEBUG_AGENTIO (("[agent-io] send data:\n%s%s\n", ASS_DATA, data));
+
+    fd = g_io_channel_unix_get_fd (cn->iochannel);
+
+    if (write_raw_data (fd, ASS_DATA, KL (ASS_DATA)) == -1 ||
+        write_raw_data (fd, data, -1) == -1 ||
+	write_raw_data (fd, NL, KL (NL)) == -1) {
+        /* error message already printed */
+        disconnect (cn);
+    }
+
+    return;
+}
+
 /* Callback for new incoming connections */
 static gboolean
 connect_handler (GIOChannel *source, GIOCondition cond, gpointer data)
Index: agent/seahorse-agent.h
===================================================================
--- agent/seahorse-agent.h	(revision 1548)
+++ agent/seahorse-agent.h	(working copy)
@@ -74,12 +74,14 @@
 int seahorse_agent_io_init ();
 void seahorse_agent_io_uninit ();
 void seahorse_agent_io_reply (SeahorseAgentConn *rq, gboolean ok, const gchar *response);
+void seahorse_agent_io_data (SeahorseAgentConn *cn, const gchar *data);
 
 /* -----------------------------------------------------------------------------
  * seahorse-agent-actions.c
  */
 
 typedef struct _SeahorseAgentPassReq {
+    gboolean pass_as_data;
     const gchar *id;
     const gchar *errmsg;
     const gchar *prompt;
@@ -89,8 +91,8 @@
 
 void seahorse_agent_actions_init ();
 void seahorse_agent_actions_uninit ();
-void seahorse_agent_actions_getpass (SeahorseAgentConn *rq, gchar *id, gchar *errmsg,
-                                     gchar *prompt, gchar *desc);
+void seahorse_agent_actions_getpass (SeahorseAgentConn * rq, gboolean pass_as_data, gchar * id,
+                                     gchar * errmsg, gchar * prompt, gchar * desc);
 void seahorse_agent_actions_clrpass (SeahorseAgentConn *rq, gchar *id);
 void seahorse_agent_actions_doneauth (SeahorseAgentPassReq *pr, gboolean authorized);
 void seahorse_agent_actions_donepass (SeahorseAgentPassReq *pr, const gchar *pass);
Index: libseahorse/seahorse-gpg-options.c
===================================================================
--- libseahorse/seahorse-gpg-options.c	(revision 1548)
+++ libseahorse/seahorse-gpg-options.c	(working copy)
@@ -32,7 +32,6 @@
 #include "seahorse-gpg-options.h"
 
 #define  GPG_CONF_HEADER    "# FILE CREATED BY SEAHORSE\n\n"
-#define  GPG_VERSION_PREFIX   "1."
 
 static gchar gpg_homedir[MAXPATHLEN];
 static gboolean gpg_options_inited = FALSE;
@@ -245,9 +244,11 @@
         /* 
          * Make sure it's the right version for us to be messing 
          * around with the configuration file.
+		 * Both 1.* and 2.* are suitable.
          */
         g_return_val_if_fail (engine && engine->version && engine->file_name &&
-                              g_str_has_prefix (engine->version, GPG_VERSION_PREFIX),
+                              (g_str_has_prefix (engine->version, "1.") ||
+                               g_str_has_prefix (engine->version, "2.")),
                               (seahorse_util_gpgme_to_error
                                (GPG_E (GPG_ERR_INV_ENGINE), err), FALSE));
 
