[gmime-devel] [PATCH 2/6] Default to using "gpg"
There is no reason to require a full path to the gpg executable. We should be able to leave it as the default. --- gmime/gmime-gpg-context.c | 10 +- tests/test-pgp.c | 4 ++-- tests/test-pgpmime.c | 4 ++-- tests/test-smime.c| 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c index 0a05ed2..2ca280a 100644 --- a/gmime/gmime-gpg-context.c +++ b/gmime/gmime-gpg-context.c @@ -763,7 +763,7 @@ gpg_ctx_op_start (struct _GpgCtx *gpg) } /* run gpg */ - execvp (gpg->ctx->path, argv); + execvp (gpg->ctx->path ? gpg->ctx->path : "gpg", argv); _exit (255); } else if (gpg->pid < 0) { g_strfreev (strv); @@ -2190,7 +2190,7 @@ gpg_export_keys (GMimeCryptoContext *context, GPtrArray *keys, GMimeStream *ostr /** * g_mime_gpg_context_new: * @request_passwd: a #GMimePasswordRequestFunc - * @path: path to gpg binary + * @path: path to gpg binary, or NULL for the default * * Creates a new gpg crypto context object. * @@ -2203,10 +2203,10 @@ g_mime_gpg_context_new (GMimePasswordRequestFunc request_passwd, const char *pat GMimeCryptoContext *crypto; GMimeGpgContext *ctx; - g_return_val_if_fail (path != NULL, NULL); - ctx = g_object_newv (GMIME_TYPE_GPG_CONTEXT, 0, NULL); - ctx->path = g_strdup (path); + if (path) { + ctx->path = g_strdup (path); + } crypto = (GMimeCryptoContext *) ctx; crypto->request_passwd = request_passwd; diff --git a/tests/test-pgp.c b/tests/test-pgp.c index bfdae74..3e7a2a4 100644 --- a/tests/test-pgp.c +++ b/tests/test-pgp.c @@ -289,7 +289,7 @@ int main (int argc, char **argv) if (system ("/bin/mkdir ./tmp") != 0) return EXIT_FAILURE; setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("/usr/bin/gpg --list-keys > /dev/null 2>&1") != 0) + if (system ("gpg --list-keys > /dev/null 2>&1") != 0) return EXIT_FAILURE; for (i = 1; i < argc; i++) { @@ -304,7 +304,7 @@ int main (int argc, char **argv) testsuite_start ("GnuPG crypto context"); - ctx = g_mime_gpg_context_new (request_passwd, "/usr/bin/gpg"); + ctx = g_mime_gpg_context_new (request_passwd, NULL); 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 546df1b..b5a8b21 100644 --- a/tests/test-pgpmime.c +++ b/tests/test-pgpmime.c @@ -425,7 +425,7 @@ int main (int argc, char *argv[]) if (system ("/bin/mkdir ./tmp") != 0) return EXIT_FAILURE; setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("/usr/bin/gpg --list-keys > /dev/null 2>&1") != 0) + if (system ("gpg --list-keys > /dev/null 2>&1") != 0) return EXIT_FAILURE; for (i = 1; i < argc; i++) { @@ -440,7 +440,7 @@ int main (int argc, char *argv[]) testsuite_start ("PGP/MIME implementation"); - ctx = g_mime_gpg_context_new (request_passwd, "/usr/bin/gpg"); + ctx = g_mime_gpg_context_new (request_passwd, NULL); g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) ctx, TRUE); testsuite_check ("GMimeGpgContext::import"); diff --git a/tests/test-smime.c b/tests/test-smime.c index f4549c7..f05e03a 100644 --- a/tests/test-smime.c +++ b/tests/test-smime.c @@ -426,7 +426,7 @@ int main (int argc, char *argv[]) if (system ("/bin/mkdir ./tmp") != 0) return EXIT_FAILURE; g_setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("/usr/bin/gpg --list-keys > /dev/null 2>&1") != 0) + if (system ("gpg --list-keys > /dev/null 2>&1") != 0) return EXIT_FAILURE; for (i = 1; i < argc; i++) { -- 2.10.2 ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[gmime-devel] [PATCH 3/6] consolidate setup of GnuPG homedir for test suites
three different test suites all set up and tear down the GnuPG homedir in the same way. By consolidating that code in testsuite.c we can improve it in a single place. --- tests/test-pgp.c | 10 ++ tests/test-pgpmime.c | 10 ++ tests/test-smime.c | 10 ++ tests/testsuite.c| 21 + tests/testsuite.h| 3 +++ 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/tests/test-pgp.c b/tests/test-pgp.c index 3e7a2a4..8fc755c 100644 --- a/tests/test-pgp.c +++ b/tests/test-pgp.c @@ -283,13 +283,7 @@ int main (int argc, char **argv) testsuite_init (argc, argv); - /* reset .gnupg config directory */ - if (system ("/bin/rm -rf ./tmp") != 0) - return EXIT_FAILURE; - if (system ("/bin/mkdir ./tmp") != 0) - return EXIT_FAILURE; - setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("gpg --list-keys > /dev/null 2>&1") != 0) + if (testsuite_setup_gpghome ()) return EXIT_FAILURE; for (i = 1; i < argc; i++) { @@ -404,7 +398,7 @@ int main (int argc, char **argv) g_mime_shutdown (); - if (system ("/bin/rm -rf ./tmp") != 0) + if (testsuite_destroy_gpghome ()) return EXIT_FAILURE; return testsuite_exit (); diff --git a/tests/test-pgpmime.c b/tests/test-pgpmime.c index b5a8b21..4cead27 100644 --- a/tests/test-pgpmime.c +++ b/tests/test-pgpmime.c @@ -419,13 +419,7 @@ int main (int argc, char *argv[]) testsuite_init (argc, argv); - /* reset .gnupg config directory */ - if (system ("/bin/rm -rf ./tmp") != 0) - return EXIT_FAILURE; - if (system ("/bin/mkdir ./tmp") != 0) - return EXIT_FAILURE; - setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("gpg --list-keys > /dev/null 2>&1") != 0) + if (testsuite_setup_gpghome ()) return EXIT_FAILURE; for (i = 1; i < argc; i++) { @@ -489,7 +483,7 @@ int main (int argc, char *argv[]) g_mime_shutdown (); - if (system ("/bin/rm -rf ./tmp") != 0) + if (testsuite_destroy_gpghome ()) return EXIT_FAILURE; return testsuite_exit (); diff --git a/tests/test-smime.c b/tests/test-smime.c index f05e03a..f35fbb7 100644 --- a/tests/test-smime.c +++ b/tests/test-smime.c @@ -420,13 +420,7 @@ int main (int argc, char *argv[]) testsuite_init (argc, argv); - /* reset .gnupg config directory */ - if (system ("/bin/rm -rf ./tmp") != 0) - return EXIT_FAILURE; - if (system ("/bin/mkdir ./tmp") != 0) - return EXIT_FAILURE; - g_setenv ("GNUPGHOME", "./tmp/.gnupg", 1); - if (system ("gpg --list-keys > /dev/null 2>&1") != 0) + if (testsuite_setup_gpghome ()) return EXIT_FAILURE; for (i = 1; i < argc; i++) { @@ -490,7 +484,7 @@ int main (int argc, char *argv[]) g_mime_shutdown (); - if (system ("/bin/rm -rf ./tmp") != 0) + if (testsuite_destroy_gpghome ()) return EXIT_FAILURE; return testsuite_exit (); diff --git a/tests/testsuite.c b/tests/testsuite.c index 2b72301..acd36a5 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -346,6 +346,27 @@ g_throw (Exception *ex) longjmp (env->env, 1); } +int +testsuite_setup_gpghome () +{ + /* reset .gnupg config directory */ + if (system ("/bin/rm -rf ./tmp") != 0) + return EXIT_FAILURE; + if (system ("/bin/mkdir ./tmp") != 0) + return EXIT_FAILURE; + g_setenv ("GNUPGHOME", "./tmp/.gnupg", 1); + if (system ("gpg --list-keys > /dev/null 2>&1") != 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + +int +testsuite_destroy_gpghome () +{ + if (system ("/bin/rm -rf ./tmp") != 0) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} #ifdef BUILD int main (int argc, char **argv) diff --git a/tests/testsuite.h b/tests/testsuite.h index ece9014..6c92a5a 100644 --- a/tests/testsuite.h +++ b/tests/testsuite.h @@ -45,6 +45,9 @@ void testsuite_check_passed (void); int testsuite_total_errors (void); +/* for those parts of the test suite that use GnuPG */ +int testsuite_setup_gpghome (void); +int testsuite_destroy_gpghome (void); /*#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) #define G_GNUC_NORETURN __attribute__((noreturn)) -- 2.10.2 ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[gmime-devel] [PATCH 4/6] avoid trying to interact with the user session during test suites
--- tests/testsuite.c | 5 + 1 file changed, 5 insertions(+) diff --git a/tests/testsuite.c b/tests/testsuite.c index acd36a5..9422e93 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -355,6 +355,11 @@ testsuite_setup_gpghome () if (system ("/bin/mkdir ./tmp") != 0) return EXIT_FAILURE; g_setenv ("GNUPGHOME", "./tmp/.gnupg", 1); + /* disable the usual mechanisms gpg-agent uses for pinentry */ + g_unsetenv ("DISPLAY"); + g_unsetenv ("DBUS_SESSION_BUS_ADDRESS"); + g_unsetenv ("GPG_TTY"); + if (system ("gpg --list-keys > /dev/null 2>&1") != 0) return EXIT_FAILURE; return EXIT_SUCCESS; -- 2.10.2 ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[gmime-devel] [PATCH 5/6] Use pinentry-mode loopback in test suite when using "modern" GnuPG
The "Modern" GnuPG suite (2.1.x or higher) defaults to relying on the gpg-agent for secret key material access, which can prompt the user for a passphrase. The test suite uses callbacks to supply the passphrase, so in these modern versions it should use "pinentry-mode loopback". Many users of GMime are likely to avoid using the passphrase callback and instead to rely on permission from the cryptographic agent directly. We do not currently test these scenarios, though we could do so with a fake pinentry. If we do that, then those scenarios should *not* use the loopback pinentry-mode, and we'd need to adjust this setup. In the longer term, the right way to resolve all of this would be to use gpgme directly, instead of having our own wrapper that invokes gpg manually. --- tests/testsuite.c | 43 +++ 1 file changed, 43 insertions(+) diff --git a/tests/testsuite.c b/tests/testsuite.c index 9422e93..84079d1 100644 --- a/tests/testsuite.c +++ b/tests/testsuite.c @@ -27,6 +27,10 @@ #ifdef ENABLE_THREADS #include #endif +#include +#include +#include +#include #include "testsuite.h" @@ -346,9 +350,38 @@ g_throw (Exception *ex) longjmp (env->env, 1); } +static int +is_gpg_modern() +{ + const char vheader[] = "gpg (GnuPG) "; + FILE *vpipe; + char *vstring; + size_t vlen; + int ret; + + if ((vpipe = popen ("gpg --version", "r")) == NULL) + return 0; + vlen = 0; + vstring = NULL; + if (getline (, , vpipe) == -1) + return 0; + if (strncmp (vstring, vheader, sizeof (vheader) - 1)) + return 0; + ret = (vstring[sizeof (vheader) - 1] > '2') || + (vstring[sizeof (vheader) - 1] == '2' && +vstring[sizeof (vheader)] == '.' && +vstring[sizeof (vheader) + 1] >= '1'); + free (vstring); + pclose (vpipe); + return ret; +} + int testsuite_setup_gpghome () { + int gpgconf; + const char directive[] = "pinentry-mode loopback\n"; + /* reset .gnupg config directory */ if (system ("/bin/rm -rf ./tmp") != 0) return EXIT_FAILURE; @@ -362,6 +395,16 @@ testsuite_setup_gpghome () if (system ("gpg --list-keys > /dev/null 2>&1") != 0) return EXIT_FAILURE; + + if (is_gpg_modern()) { + if ((gpgconf = open ("./tmp/.gnupg/gpg.conf", O_WRONLY | O_CREAT | O_TRUNC, 0400)) == -1) + return EXIT_FAILURE; + if (write (gpgconf, directive, sizeof(directive) - 1) != sizeof(directive) - 1) + return EXIT_FAILURE; + if (close (gpgconf) != 0) + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } -- 2.10.2 ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[gmime-devel] [PATCH 1/6] Ship extra data for tests.
Running "make check" from the tarball currently doesn't run as many of the tests as it should, because the data files for the tests aren't shipped. This patch includes those files in the generated upstream tarball. --- tests/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 93e4150..d0c0be9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -112,7 +112,9 @@ test_smime_DEPENDENCIES = $(DEPS) test_smime_LDADD = $(LDADDS) endif -EXTRA_DIST = test1.eml test2.eml test3.eml +EXTRA_DIST = test1.eml test2.eml test3.eml $(wildcard \ + data/pgp*/gmime.gpg.* data/mbox/*put/substring.mbox \ + empty*.msg message-partial.* rfc2060.msg) VERBOSITY=-v -- 2.10.2 ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
Some message stores can be optimized by caching session keys of encrypted messages, rather than incurring asymmetric crypto operations on each subsequent decryption. This patch allows gmime to perform extraction of session keys during message decryption to support that use case. See the discussion starting here for more detail on the API/design choices: https://mail.gnome.org/archives/gmime-devel-list/2016-July/msg5.html --- gmime/gmime-crypto-context.c | 41 gmime/gmime-crypto-context.h | 4 gmime/gmime-gpg-context.c| 50 +++- gmime/gmime-gpg-context.h| 4 tests/test-pgp.c | 5 + tests/test-pgpmime.c | 9 +++- 6 files changed, 111 insertions(+), 2 deletions(-) diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c index 5269440..90fa390 100644 --- a/gmime/gmime-crypto-context.c +++ b/gmime/gmime-crypto-context.c @@ -573,6 +573,7 @@ g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass result->mdc = GMIME_DIGEST_ALGO_DEFAULT; result->recipients = NULL; result->signatures = NULL; + result->session_key = NULL; } static void @@ -586,6 +587,8 @@ g_mime_decrypt_result_finalize (GObject *object) if (result->signatures) g_object_unref (result->signatures); + g_free (result->session_key); + G_OBJECT_CLASS (result_parent_class)->finalize (object); } @@ -755,3 +758,41 @@ g_mime_decryption_result_get_mdc (GMimeDecryptResult *result) return result->mdc; } + + +/** + * g_mime_decrypt_result_set_session_key: + * @result: a #GMimeDecryptResult + * @session_key: a pointer to a null-terminated string representing the session key + * + * Set the session_key to be returned by this decryption result. + **/ +void +g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key) +{ + g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result)); + + g_free (result->session_key); + result->session_key = g_strdup(session_key); +} + + +/** + * g_mime_decrypt_result_get_session_key: + * @result: a #GMimeDecryptResult + * + * Get the session_key used for this decryption, if the underlying + * crypto context is capable of and (configured to) retrieve session + * keys during decryption. See, for example, + * g_mime_gpg_context_set_retrieve_session_key(). + * + * Returns: the session_key digest algorithm used, or NULL if no + * session key was requested or found. + **/ +const char* +g_mime_decryption_result_get_session_key (GMimeDecryptResult *result) +{ + g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT); + + return result->session_key; +} diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h index cd38760..72573ed 100644 --- a/gmime/gmime-crypto-context.h +++ b/gmime/gmime-crypto-context.h @@ -206,6 +206,7 @@ struct _GMimeDecryptResult { GMimeSignatureList *signatures; GMimeCipherAlgo cipher; GMimeDigestAlgo mdc; + char *session_key; }; struct _GMimeDecryptResultClass { @@ -229,6 +230,9 @@ GMimeCipherAlgo g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result); void g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc); GMimeDigestAlgo g_mime_decrypt_result_get_mdc (GMimeDecryptResult *result); +void g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key); +const char *g_mime_decrypt_result_get_session_key (GMimeDecryptResult *result); + G_END_DECLS #endif /* __GMIME_CRYPTO_CONTEXT_H__ */ diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c index 2ca280a..6f7d374 100644 --- a/gmime/gmime-gpg-context.c +++ b/gmime/gmime-gpg-context.c @@ -172,6 +172,7 @@ g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass) ctx->always_trust = FALSE; ctx->use_agent = FALSE; ctx->path = NULL; + ctx->retrieve_session_key = FALSE; } static void @@ -311,6 +312,7 @@ struct _GpgCtx { GMimeStream *diagnostics; GMimeCertificateList *encrypted_to; /* full list of encrypted-to recipients */ + char *session_key; GMimeSignatureList *signatures; GMimeSignature *signature; @@ -375,6 +377,7 @@ gpg_ctx_new (GMimeGpgContext *ctx) gpg->need_id = NULL; gpg->encrypted_to = NULL; + gpg->session_key = NULL; gpg->signatures = NULL; gpg->signature = NULL; @@ -555,6 +558,8 @@ gpg_ctx_free (struct _GpgCtx *gpg) if (gpg->encrypted_to) g_object_unref (gpg->encrypted_to); + g_free (gpg->session_key); + if (gpg->signatures) g_object_unref (gpg->signatures); @@ -691,6 +696,9 @@ gpg_ctx_get_argv (struct _GpgCtx *gpg, int