[gmime] Fixed gpg unit tests to pass again



commit 978274d953470700d9e2d55f294f13f65e6c5509
Author: Jeffrey Stedfast <fejj gnome org>
Date:   Sat Dec 10 01:11:23 2016 -0500

    Fixed gpg unit tests to pass again

 ChangeLog                 |    9 ++++
 gmime/gmime-gpg-context.c |   91 +++++++++++++++++++++++++++++++++++++++-----
 gmime/gmime-gpg-context.h |    2 +
 tests/test-pgp.c          |    6 ++-
 tests/test-pgpmime.c      |   10 +++--
 tests/test-smime.c        |    4 +-
 tests/testsuite.c         |   85 ++++++++---------------------------------
 tests/testsuite.h         |    4 +-
 8 files changed, 123 insertions(+), 88 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 586cf82..5342127 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-12-10  Jeffrey Stedfast  <fejj gnome org>
+
+       * gmime/gmime-gpg-context.c (gpg_ctx_get_argv): Add back --batch
+       and --yes to fix the unit tests for GnuPG 1.4.x.
+       (gpg_ctx_get_argv): Now also takes a path argument to gpg to use
+       as the first argument instead of hard-coding "gpg".
+       (g_mime_gpg_context_new): Updated to query the GnuPG version in
+       case we need that information (turns out we don't at the moment).
+
 2016-12-09  Jeffrey Stedfast  <fejj gnome org>
 
        * gmime/gmime-crypto-context.c (g_mime_crypto_context_set_retrieve_session_key):
diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c
index 9d54458..6df00e6 100644
--- a/gmime/gmime-gpg-context.c
+++ b/gmime/gmime-gpg-context.c
@@ -615,8 +615,16 @@ gpg_digest_str (GMimeDigestAlgo digest)
        }
 }
 
+static const char *
+filename (const char *path)
+{
+       const char *slash = strrchr (path, '/');
+       
+       return slash != NULL ? slash + 1 : path;
+}
+
 static char **
-gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, int secret_fd, char ***strv)
+gpg_ctx_get_argv (struct _GpgCtx *gpg, const char *path, int status_fd, int secret_fd, char ***strv)
 {
        const char *digest_str;
        char **argv, *buf;
@@ -627,13 +635,21 @@ gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, int secret_fd, char ***str
        *strv = g_new (char *, 3);
        
        args = g_ptr_array_new ();
-       g_ptr_array_add (args, "gpg");
+       g_ptr_array_add (args, (char *) filename (path));
        
        g_ptr_array_add (args, "--verbose");
        g_ptr_array_add (args, "--no-secmem-warning");
        g_ptr_array_add (args, "--no-greeting");
        g_ptr_array_add (args, "--no-tty");
-       g_ptr_array_add (args, "--batch");
+       
+       if (!gpg->need_passwd) {
+               /* only use batch mode if we don't intend on using the
+                   interactive --command-fd option to send it the
+                   user's password */
+               g_ptr_array_add (args, "--batch");
+               g_ptr_array_add (args, "--yes");
+       }
+       
        g_ptr_array_add (args, "--charset=UTF-8");
        
        (*strv)[v++] = buf = g_strdup_printf ("--status-fd=%d", status_fd);
@@ -757,7 +773,7 @@ gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, int secret_fd, char ***str
 }
 
 static int
-gpg_ctx_op_start (struct _GpgCtx *gpg)
+gpg_ctx_op_start (struct _GpgCtx *gpg, const char *path)
 {
        int i, maxfd, errnosave, fds[10];
        char **argv, **strv = NULL;
@@ -776,7 +792,7 @@ gpg_ctx_op_start (struct _GpgCtx *gpg)
                        goto exception;
        }
        
-       argv = gpg_ctx_get_argv (gpg, fds[7], fds[8], &strv);
+       argv = gpg_ctx_get_argv (gpg, path, fds[7], fds[8], &strv);
        
        if (!(gpg->pid = fork ())) {
                /* child process */
@@ -1904,7 +1920,7 @@ gpg_sign (GMimeCryptoContext *context, const char *userid, GMimeDigestAlgo diges
        gpg_ctx_set_istream (gpg, istream);
        gpg_ctx_set_ostream (gpg, ostream);
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -1966,7 +1982,7 @@ gpg_verify (GMimeCryptoContext *context, GMimeDigestAlgo digest,
        gpg_ctx_set_istream (gpg, istream);
        gpg_ctx_set_digest (gpg, digest);
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -2039,7 +2055,7 @@ gpg_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid,
        for (i = 0; i < recipients->len; i++)
                gpg_ctx_add_recipient (gpg, recipients->pdata[i]);
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -2110,7 +2126,7 @@ gpg_decrypt_session (GMimeCryptoContext *context, const char *session_key,
        if (session_key)
                gpg->override_session_key = TRUE;
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -2179,7 +2195,7 @@ gpg_import_keys (GMimeCryptoContext *context, GMimeStream *istream, GError **err
        gpg_ctx_set_mode (gpg, GPG_CTX_MODE_IMPORT);
        gpg_ctx_set_istream (gpg, istream);
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -2238,7 +2254,7 @@ gpg_export_keys (GMimeCryptoContext *context, GPtrArray *keys, GMimeStream *ostr
                gpg_ctx_add_recipient (gpg, keys->pdata[i]);
        }
        
-       if (gpg_ctx_op_start (gpg) == -1) {
+       if (gpg_ctx_op_start (gpg, ctx->path) == -1) {
                g_set_error (err, GMIME_ERROR, errno,
                             _("Failed to execute gpg: %s"),
                             errno ? g_strerror (errno) : _("Unknown"));
@@ -2280,6 +2296,57 @@ gpg_export_keys (GMimeCryptoContext *context, GPtrArray *keys, GMimeStream *ostr
 #endif /* ENABLE_CRYPTOGRAPHY */
 }
 
+int
+_g_mime_get_gpg_version (const char *path)
+{
+       const char vheader[] = "gpg (GnuPG) ";
+       int v, n = 0, version = 0;
+       const char *inptr;
+       char buffer[128];
+       char *command;
+       FILE *gpg;
+       
+       g_return_val_if_fail (path != NULL, -1);
+       
+       command = g_strdup_printf ("%s --version", path);
+       gpg = popen (command, "r");
+       g_free (command);
+       
+       if (gpg == NULL)
+               return -1;
+       
+       inptr = fgets (buffer, 128, gpg);
+       pclose (gpg);
+       
+       if (strncmp (inptr, vheader, sizeof (vheader) - 1) != 0)
+               return -1;
+       
+       inptr += sizeof (vheader) - 1;
+       while (*inptr >= '0' && *inptr <= '9' && n < 4) {
+               v = 0;
+               
+               while (*inptr >= '0' && *inptr <= '9' && (v < 25 || (v == 25 && *inptr < '6'))) {
+                       v = (v * 10) + (*inptr - '0');
+                       inptr++;
+               }
+               
+               version = (version << 8) + v;
+               n++;
+               
+               if (*inptr != '.')
+                       break;
+               
+               inptr++;
+       }
+       
+       if (n == 0)
+               return -1;
+       
+       if (n < 4)
+               version = version << ((4 - n) * 8);
+       
+       return version;
+}
 
 /**
  * g_mime_gpg_context_new:
@@ -2300,6 +2367,8 @@ g_mime_gpg_context_new (GMimePasswordRequestFunc request_passwd, const char *pat
        ctx = g_object_newv (GMIME_TYPE_GPG_CONTEXT, 0, NULL);
        ctx->path = g_strdup (path ? path : "gpg");
        
+       ctx->version = _g_mime_get_gpg_version (ctx->path);
+       
        crypto = (GMimeCryptoContext *) ctx;
        crypto->request_passwd = request_passwd;
        
diff --git a/gmime/gmime-gpg-context.h b/gmime/gmime-gpg-context.h
index 8625d33..1218ffa 100644
--- a/gmime/gmime-gpg-context.h
+++ b/gmime/gmime-gpg-context.h
@@ -45,6 +45,7 @@ typedef struct _GMimeGpgContextClass GMimeGpgContextClass;
  * @use_agent: %TRUE if gpg should use the gpg-agent for requesting passphrases
  * @path: path to gpg
  * @retrieve_session_key: %TRUE if session keys should be retrieved when decrypting
+ * @version: The GnuPG version.
  *
  * A GnuPG crypto context.
  **/
@@ -55,6 +56,7 @@ struct _GMimeGpgContext {
        gboolean use_agent;
        char *path;
        gboolean retrieve_session_key;
+       int version;
 };
 
 struct _GMimeGpgContextClass {
diff --git a/tests/test-pgp.c b/tests/test-pgp.c
index 81a4b9d..9740b92 100644
--- a/tests/test-pgp.c
+++ b/tests/test-pgp.c
@@ -34,6 +34,8 @@
 
 #include "testsuite.h"
 
+#define GPG_PATH "/usr/bin/gpg2"
+
 extern int verbose;
 
 #define v(x) if (verbose > 3) x
@@ -288,7 +290,7 @@ int main (int argc, char **argv)
        
        testsuite_init (argc, argv);
        
-       if (testsuite_setup_gpghome () != 0)
+       if (testsuite_setup_gpghome (GPG_PATH) != 0)
                return EXIT_FAILURE;
        
        for (i = 1; i < argc; i++) {
@@ -303,7 +305,7 @@ int main (int argc, char **argv)
        
        testsuite_start ("GnuPG crypto context");
        
-       ctx = g_mime_gpg_context_new (request_passwd, NULL);
+       ctx = g_mime_gpg_context_new (request_passwd, GPG_PATH);
        g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) ctx, TRUE);
        
        testsuite_check ("GMimeGpgContext::import");
diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c
index cfd2d81..695293f 100644
--- a/tests/test-pgpmime.c
+++ b/tests/test-pgpmime.c
@@ -35,6 +35,8 @@
 
 #include "testsuite.h"
 
+#define GPG_PATH "/usr/bin/gpg"
+
 extern int verbose;
 
 #define v(x) if (verbose > 3) x
@@ -450,7 +452,7 @@ int main (int argc, char *argv[])
        
        testsuite_init (argc, argv);
        
-       if (testsuite_setup_gpghome () != 0)
+       if (testsuite_setup_gpghome (GPG_PATH) != 0)
                return EXIT_FAILURE;
        
        for (i = 1; i < argc; i++) {
@@ -465,7 +467,7 @@ int main (int argc, char *argv[])
        
        testsuite_start ("PGP/MIME implementation");
        
-       ctx = g_mime_gpg_context_new (request_passwd, NULL);
+       ctx = g_mime_gpg_context_new (request_passwd, GPG_PATH);
        g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) ctx, TRUE);
        if (g_mime_crypto_context_set_retrieve_session_key (ctx, TRUE, &err) != 0) {
                fprintf (stderr, "Failed to set retrieve_session_key on GMimeGpgContext: %s\n",
@@ -507,7 +509,7 @@ int main (int argc, char *argv[])
        try {
                create_encrypted_message (ctx, FALSE, &cleartext, &stream);
                session_key = test_multipart_encrypted (ctx, FALSE, cleartext, stream, NULL);
-               if (testsuite_can_safely_override_session_key ())
+               if (testsuite_can_safely_override_session_key (GPG_PATH))
                        g_free (test_multipart_encrypted (ctx, FALSE, cleartext, stream, session_key));
                testsuite_check_passed ();
        } catch (ex) {
@@ -528,7 +530,7 @@ int main (int argc, char *argv[])
        try {
                create_encrypted_message (ctx, TRUE, &cleartext, &stream);
                session_key = test_multipart_encrypted (ctx, TRUE, cleartext, stream, NULL);
-               if (testsuite_can_safely_override_session_key ())
+               if (testsuite_can_safely_override_session_key (GPG_PATH))
                        g_free (test_multipart_encrypted (ctx, TRUE, cleartext, stream, session_key));
                testsuite_check_passed ();
        } catch (ex) {
diff --git a/tests/test-smime.c b/tests/test-smime.c
index fa838e8..6f37d62 100644
--- a/tests/test-smime.c
+++ b/tests/test-smime.c
@@ -36,6 +36,8 @@
 
 #include "testsuite.h"
 
+#define GPG_PATH "/usr/bin/gpg"
+
 extern int verbose;
 
 #define v(x) if (verbose > 3) x
@@ -420,7 +422,7 @@ int main (int argc, char *argv[])
        
        testsuite_init (argc, argv);
        
-       if (testsuite_setup_gpghome () != 0)
+       if (testsuite_setup_gpghome (GPG_PATH) != 0)
                return EXIT_FAILURE;
        
        for (i = 1; i < argc; i++) {
diff --git a/tests/testsuite.c b/tests/testsuite.c
index 4e6cdc2..8e1d5b1 100644
--- a/tests/testsuite.c
+++ b/tests/testsuite.c
@@ -350,58 +350,6 @@ g_throw (Exception *ex)
        longjmp (env->env, 1);
 }
 
-static const char *
-get_gpg_version (void)
-{
-       static gboolean found = FALSE;
-       static char version[1024];
-       const char vheader[] = "gpg (GnuPG) ";
-       char *vstring = NULL;
-       size_t vlen = 0;
-       FILE *vpipe;
-       int ret;
-       
-       if (found)
-               return version;
-       
-       if ((vpipe = popen ("gpg --version", "r")) == NULL)
-               return NULL;
-       
-       if (getline (&vstring, &vlen, vpipe) == -1) {
-               free (vstring);
-               pclose (vpipe);
-               return NULL;
-       }
-       
-       pclose (vpipe);
-       
-       if (strncmp (vstring, vheader, sizeof (vheader) - 1)) {
-               free (vstring);
-               return NULL;
-       }
-       
-       strncpy (version, vstring + sizeof (vheader) - 1, sizeof (version) - 1);
-       version[sizeof (version) - 1] = '\0';
-       free (vstring);
-       found = TRUE;
-       
-       return version;
-}
-
-static int
-is_gpg_modern (void)
-{
-       const char *ver = get_gpg_version ();
-
-       if (!ver)
-               return 0;
-       
-       return (ver[0] > '2') ||
-               (ver[0] == '2' &&
-                ver[1] == '.' &&
-                ver[2] >= '1');
-}
-
 /* in versions of gpg before 2.1.16, the only mechanism to override
    the session key was --override-session-key, which leaks its
    argument to the process table.
@@ -410,25 +358,21 @@ is_gpg_modern (void)
    gmime uses to be safe.
 */
 
+#define v2_1_16 ((2 << 24) | (1 << 16) | (16 << 8))
+
+int _g_mime_get_gpg_version (const char *gpg);
+
 int
-testsuite_can_safely_override_session_key (void)
+testsuite_can_safely_override_session_key (const char *gpg)
 {
-       const char *ver = get_gpg_version ();
-       
-       if (!ver)
-               return 0;
-       
-       return (ver[0] > '2') ||
-               ((ver[0] == '2' && ver[1] == '.' ) &&
-                ((ver[2] > '1') ||
-                 ((ver[2] == '1' && ver[3] == '.') &&
-                  (atoi(ver+4) >= 16))));
+       return _g_mime_get_gpg_version (gpg) >= v2_1_16;
 }
 
 int
-testsuite_setup_gpghome (void)
+testsuite_setup_gpghome (const char *gpg)
 {
        const char directive[] = "pinentry-mode loopback\n";
+       char *command;
        
        /* reset .gnupg config directory */
        if (system ("/bin/rm -rf ./tmp") != 0)
@@ -443,10 +387,15 @@ testsuite_setup_gpghome (void)
        g_unsetenv ("DISPLAY");
        g_unsetenv ("GPG_TTY");
        
-       if (system ("gpg --list-keys > /dev/null 2>&1") != 0)
+        command = g_strdup_printf ("%s --list-keys > /dev/null 2>&1", gpg);
+       if (system (command) != 0) {
+               g_free (command);
                return EXIT_FAILURE;
+       }
+       
+       g_free (command);
        
-       if (is_gpg_modern ()) {
+       if (_g_mime_get_gpg_version (gpg) >= ((2 << 24) | (1 << 16))) {
                FILE *fp;
                
                if ((fp = fopen ("./tmp/.gnupg/gpg.conf", "w")) == NULL)
@@ -467,8 +416,8 @@ testsuite_setup_gpghome (void)
 int
 testsuite_destroy_gpghome (void)
 {
-       if (system ("/bin/rm -rf ./tmp") != 0)
-               return EXIT_FAILURE;
+       //if (system ("/bin/rm -rf ./tmp") != 0)
+       //      return EXIT_FAILURE;
        return EXIT_SUCCESS;
 }
 
diff --git a/tests/testsuite.h b/tests/testsuite.h
index 87d3126..c2b0146 100644
--- a/tests/testsuite.h
+++ b/tests/testsuite.h
@@ -46,9 +46,9 @@ void testsuite_check_passed (void);
 int testsuite_total_errors (void);
 
 /* GnuPG test suite utility functions */
-int testsuite_setup_gpghome (void);
+int testsuite_setup_gpghome (const char *gpg);
 int testsuite_destroy_gpghome (void);
-int testsuite_can_safely_override_session_key (void);
+int testsuite_can_safely_override_session_key (const char *gpg);
 
 /*#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
 #define G_GNUC_NORETURN __attribute__((noreturn))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]