From: Daniel Kahn Gillmor Date: Tue, 17 Oct 2017 19:09:55 +0000 (-0400) Subject: crypto: move into libnotmuch_util X-Git-Tag: 0.26_rc0~105 X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=commitdiff_plain;h=197d67959bf459fc0f1f63a202d162a569535bf3 crypto: move into libnotmuch_util This prepares us for using the crypto object in both libnotmuch and the client. --- diff --git a/Makefile.local b/Makefile.local index 9d9c52c2..9505b7fe 100644 --- a/Makefile.local +++ b/Makefile.local @@ -246,7 +246,6 @@ notmuch_client_srcs = \ sprinter-text.c \ query-string.c \ mime-node.c \ - crypto.c \ tag-util.c notmuch_client_modules = $(notmuch_client_srcs:.c=.o) diff --git a/crypto.c b/crypto.c deleted file mode 100644 index 4c1b7eec..00000000 --- a/crypto.c +++ /dev/null @@ -1,137 +0,0 @@ -/* notmuch - Not much of an email program, (just index and search) - * - * Copyright © 2012 Jameson Rollins - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see https://www.gnu.org/licenses/ . - * - * Authors: Jameson Rollins - */ - -#include "notmuch-client.h" -#if (GMIME_MAJOR_VERSION < 3) -/* Create a GPG context (GMime 2.6) */ -static GMimeCryptoContext * -create_gpg_context (_notmuch_crypto_t *crypto) -{ - GMimeCryptoContext *gpgctx; - - if (crypto->gpgctx) - return crypto->gpgctx; - - /* TODO: GMimePasswordRequestFunc */ - gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg"); - if (! gpgctx) { - fprintf (stderr, "Failed to construct gpg context.\n"); - return NULL; - } - crypto->gpgctx = gpgctx; - - g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, true); - g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, false); - - return gpgctx; -} - -/* Create a PKCS7 context (GMime 2.6) */ -static GMimeCryptoContext * -create_pkcs7_context (_notmuch_crypto_t *crypto) -{ - GMimeCryptoContext *pkcs7ctx; - - if (crypto->pkcs7ctx) - return crypto->pkcs7ctx; - - /* TODO: GMimePasswordRequestFunc */ - pkcs7ctx = g_mime_pkcs7_context_new (NULL); - if (! pkcs7ctx) { - fprintf (stderr, "Failed to construct pkcs7 context.\n"); - return NULL; - } - crypto->pkcs7ctx = pkcs7ctx; - - g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx, - false); - - return pkcs7ctx; -} -static const struct { - const char *protocol; - GMimeCryptoContext *(*get_context) (_notmuch_crypto_t *crypto); -} protocols[] = { - { - .protocol = "application/pgp-signature", - .get_context = create_gpg_context, - }, - { - .protocol = "application/pgp-encrypted", - .get_context = create_gpg_context, - }, - { - .protocol = "application/pkcs7-signature", - .get_context = create_pkcs7_context, - }, - { - .protocol = "application/x-pkcs7-signature", - .get_context = create_pkcs7_context, - }, -}; - -/* for the specified protocol return the context pointer (initializing - * if needed) */ -GMimeCryptoContext * -_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol) -{ - GMimeCryptoContext *cryptoctx = NULL; - size_t i; - - if (! protocol) { - fprintf (stderr, "Cryptographic protocol is empty.\n"); - return cryptoctx; - } - - /* As per RFC 1847 section 2.1: "the [protocol] value token is - * comprised of the type and sub-type tokens of the Content-Type". - * As per RFC 1521 section 2: "Content-Type values, subtypes, and - * parameter names as defined in this document are - * case-insensitive." Thus, we use strcasecmp for the protocol. - */ - for (i = 0; i < ARRAY_SIZE (protocols); i++) { - if (strcasecmp (protocol, protocols[i].protocol) == 0) - return protocols[i].get_context (crypto); - } - - fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n", - protocol); - - return NULL; -} - -void -_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto) -{ - if (crypto->gpgctx) { - g_object_unref (crypto->gpgctx); - crypto->gpgctx = NULL; - } - - if (crypto->pkcs7ctx) { - g_object_unref (crypto->pkcs7ctx); - crypto->pkcs7ctx = NULL; - } -} -#else -void _notmuch_crypto_cleanup (unused(_notmuch_crypto_t *crypto)) -{ -} -#endif diff --git a/notmuch-client.h b/notmuch-client.h index bdcfd893..d17cdf01 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -32,9 +32,6 @@ #include "gmime-extra.h" -/* This is automatically included only since gmime 2.6.10 */ -#include - #include "notmuch.h" /* This is separate from notmuch-private.h because we're trying to @@ -54,6 +51,7 @@ #include #include "talloc-extra.h" +#include "crypto.h" #define unused(x) x __attribute__ ((unused)) @@ -71,16 +69,6 @@ typedef struct notmuch_show_format { const struct notmuch_show_params *params); } notmuch_show_format_t; -typedef struct _notmuch_crypto { - bool verify; - bool decrypt; -#if (GMIME_MAJOR_VERSION < 3) - GMimeCryptoContext* gpgctx; - GMimeCryptoContext* pkcs7ctx; - const char *gpgpath; -#endif -} _notmuch_crypto_t; - typedef struct notmuch_show_params { bool entire_thread; bool omit_excluded; @@ -180,14 +168,6 @@ typedef struct _notmuch_config notmuch_config_t; void notmuch_exit_if_unsupported_format (void); -#if (GMIME_MAJOR_VERSION <3) -GMimeCryptoContext * -_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol); -#endif - -void -_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto); - int notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]); diff --git a/util/Makefile.local b/util/Makefile.local index 3027880b..ba03230e 100644 --- a/util/Makefile.local +++ b/util/Makefile.local @@ -5,7 +5,7 @@ extra_cflags += -I$(srcdir)/$(dir) libnotmuch_util_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \ $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c \ - $(dir)/util.c $(dir)/gmime-extra.c + $(dir)/util.c $(dir)/gmime-extra.c $(dir)/crypto.c libnotmuch_util_modules := $(libnotmuch_util_c_srcs:.c=.o) diff --git a/util/crypto.c b/util/crypto.c new file mode 100644 index 00000000..c51d67ed --- /dev/null +++ b/util/crypto.c @@ -0,0 +1,142 @@ +/* notmuch - Not much of an email program, (just index and search) + * + * Copyright © 2012 Jameson Rollins + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see https://www.gnu.org/licenses/ . + * + * Authors: Jameson Rollins + */ + +#include "crypto.h" +#include +#define unused(x) x __attribute__ ((unused)) + +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0])) + +#if (GMIME_MAJOR_VERSION < 3) +/* Create a GPG context (GMime 2.6) */ +static GMimeCryptoContext * +create_gpg_context (_notmuch_crypto_t *crypto) +{ + GMimeCryptoContext *gpgctx; + + if (crypto->gpgctx) + return crypto->gpgctx; + + /* TODO: GMimePasswordRequestFunc */ + gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg"); + if (! gpgctx) { + fprintf (stderr, "Failed to construct gpg context.\n"); + return NULL; + } + crypto->gpgctx = gpgctx; + + g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, true); + g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, false); + + return gpgctx; +} + +/* Create a PKCS7 context (GMime 2.6) */ +static GMimeCryptoContext * +create_pkcs7_context (_notmuch_crypto_t *crypto) +{ + GMimeCryptoContext *pkcs7ctx; + + if (crypto->pkcs7ctx) + return crypto->pkcs7ctx; + + /* TODO: GMimePasswordRequestFunc */ + pkcs7ctx = g_mime_pkcs7_context_new (NULL); + if (! pkcs7ctx) { + fprintf (stderr, "Failed to construct pkcs7 context.\n"); + return NULL; + } + crypto->pkcs7ctx = pkcs7ctx; + + g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx, + false); + + return pkcs7ctx; +} +static const struct { + const char *protocol; + GMimeCryptoContext *(*get_context) (_notmuch_crypto_t *crypto); +} protocols[] = { + { + .protocol = "application/pgp-signature", + .get_context = create_gpg_context, + }, + { + .protocol = "application/pgp-encrypted", + .get_context = create_gpg_context, + }, + { + .protocol = "application/pkcs7-signature", + .get_context = create_pkcs7_context, + }, + { + .protocol = "application/x-pkcs7-signature", + .get_context = create_pkcs7_context, + }, +}; + +/* for the specified protocol return the context pointer (initializing + * if needed) */ +GMimeCryptoContext * +_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol) +{ + GMimeCryptoContext *cryptoctx = NULL; + size_t i; + + if (! protocol) { + fprintf (stderr, "Cryptographic protocol is empty.\n"); + return cryptoctx; + } + + /* As per RFC 1847 section 2.1: "the [protocol] value token is + * comprised of the type and sub-type tokens of the Content-Type". + * As per RFC 1521 section 2: "Content-Type values, subtypes, and + * parameter names as defined in this document are + * case-insensitive." Thus, we use strcasecmp for the protocol. + */ + for (i = 0; i < ARRAY_SIZE (protocols); i++) { + if (strcasecmp (protocol, protocols[i].protocol) == 0) + return protocols[i].get_context (crypto); + } + + fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n", + protocol); + + return NULL; +} + +void +_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto) +{ + if (crypto->gpgctx) { + g_object_unref (crypto->gpgctx); + crypto->gpgctx = NULL; + } + + if (crypto->pkcs7ctx) { + g_object_unref (crypto->pkcs7ctx); + crypto->pkcs7ctx = NULL; + } +} +#else +void _notmuch_crypto_cleanup (unused(_notmuch_crypto_t *crypto)) +{ +} +#endif diff --git a/util/crypto.h b/util/crypto.h new file mode 100644 index 00000000..80628dc5 --- /dev/null +++ b/util/crypto.h @@ -0,0 +1,28 @@ +#ifndef _CRYPTO_H +#define _CRYPTO_H + +#include +#if (GMIME_MAJOR_VERSION < 3) +#include "gmime-extra.h" +#endif + +typedef struct _notmuch_crypto { + bool verify; + bool decrypt; +#if (GMIME_MAJOR_VERSION < 3) + GMimeCryptoContext* gpgctx; + GMimeCryptoContext* pkcs7ctx; + const char *gpgpath; +#endif +} _notmuch_crypto_t; + + +#if (GMIME_MAJOR_VERSION < 3) +GMimeCryptoContext * +_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol); +#endif + +void +_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto); + +#endif