Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 1A7966DE1B1C for ; Sun, 31 Jan 2016 12:40:15 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vkPz5K4UqHMl for ; Sun, 31 Jan 2016 12:40:12 -0800 (PST) Received: from che.mayfirst.org (che.mayfirst.org [209.234.253.108]) by arlo.cworth.org (Postfix) with ESMTP id E51046DE0C5F for ; Sun, 31 Jan 2016 12:40:08 -0800 (PST) Received: from fifthhorseman.net (ip-64-134-185-108.public.wayport.net [64.134.185.108]) by che.mayfirst.org (Postfix) with ESMTPSA id 8B562F993 for ; Sun, 31 Jan 2016 15:40:05 -0500 (EST) Received: by fifthhorseman.net (Postfix, from userid 1000) id 30F5920388; Sun, 31 Jan 2016 15:40:06 -0500 (EST) From: Daniel Kahn Gillmor To: Notmuch Mail Subject: [PATCH v3 02/16] Move crypto.c into libutil Date: Sun, 31 Jan 2016 15:39:47 -0500 Message-Id: <1454272801-23623-3-git-send-email-dkg@fifthhorseman.net> X-Mailer: git-send-email 2.7.0.rc3 In-Reply-To: <1454272801-23623-1-git-send-email-dkg@fifthhorseman.net> References: <1454272801-23623-1-git-send-email-dkg@fifthhorseman.net> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Jan 2016 20:40:15 -0000 This prepares us for using the crypto object in both the library and the client. i've prefixed notmuch_crypto with _ to indicate that while this can be built into the library when needed, it's not something to be exported or used externally. --- Makefile.local | 1 - crypto.c | 134 -------------------------------------------------- mime-node.c | 12 ++--- notmuch-client.h | 23 ++------- notmuch-reply.c | 2 +- notmuch-show.c | 2 +- util/Makefile.local | 2 +- util/crypto.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++ util/crypto.h | 25 ++++++++++ 9 files changed, 175 insertions(+), 164 deletions(-) delete mode 100644 crypto.c create mode 100644 util/crypto.c create mode 100644 util/crypto.h diff --git a/Makefile.local b/Makefile.local index 066ecf2..6206771 100644 --- a/Makefile.local +++ b/Makefile.local @@ -293,7 +293,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 3dabc97..0000000 --- a/crypto.c +++ /dev/null @@ -1,134 +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 http://www.gnu.org/licenses/ . - * - * Authors: Jameson Rollins - */ - -#include "notmuch-client.h" - -/* Create a GPG context (GMime 2.6) */ -static notmuch_crypto_context_t * -create_gpg_context (notmuch_crypto_t *crypto) -{ - notmuch_crypto_context_t *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 notmuch_crypto_context_t * -create_pkcs7_context (notmuch_crypto_t *crypto) -{ - notmuch_crypto_context_t *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; - notmuch_crypto_context_t *(*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) */ -notmuch_crypto_context_t * -notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol) -{ - notmuch_crypto_context_t *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; -} - -int -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; - } - - return 0; -} diff --git a/mime-node.c b/mime-node.c index e96e663..a8f5670 100644 --- a/mime-node.c +++ b/mime-node.c @@ -33,7 +33,7 @@ typedef struct mime_node_context { GMimeMessage *mime_message; /* Context provided by the caller. */ - notmuch_crypto_t *crypto; + _notmuch_crypto_t *crypto; } mime_node_context_t; static int @@ -56,7 +56,7 @@ _mime_node_context_free (mime_node_context_t *res) notmuch_status_t mime_node_open (const void *ctx, notmuch_message_t *message, - notmuch_crypto_t *crypto, mime_node_t **root_out) + _notmuch_crypto_t *crypto, mime_node_t **root_out) { const char *filename = notmuch_message_get_filename (message); mime_node_context_t *mctx; @@ -151,7 +151,7 @@ set_signature_list_destructor (mime_node_t *node) /* Verify a signed mime node (GMime 2.6) */ static void node_verify (mime_node_t *node, GMimeObject *part, - notmuch_crypto_context_t *cryptoctx) + GMimeCryptoContext *cryptoctx) { GError *err = NULL; @@ -172,7 +172,7 @@ node_verify (mime_node_t *node, GMimeObject *part, /* Decrypt and optionally verify an encrypted mime node (GMime 2.6) */ static void node_decrypt_and_verify (mime_node_t *node, GMimeObject *part, - notmuch_crypto_context_t *cryptoctx) + GMimeCryptoContext *cryptoctx) { GError *err = NULL; GMimeDecryptResult *decrypt_result = NULL; @@ -207,7 +207,7 @@ static mime_node_t * _mime_node_create (mime_node_t *parent, GMimeObject *part) { mime_node_t *node = talloc_zero (parent, mime_node_t); - notmuch_crypto_context_t *cryptoctx = NULL; + GMimeCryptoContext *cryptoctx = NULL; /* Set basic node properties */ node->part = part; @@ -244,7 +244,7 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part) || (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) { GMimeContentType *content_type = g_mime_object_get_content_type (part); const char *protocol = g_mime_content_type_get_parameter (content_type, "protocol"); - cryptoctx = notmuch_crypto_get_context (node->ctx->crypto, protocol); + cryptoctx = _notmuch_crypto_get_gmime_context (node->ctx->crypto, protocol); } /* Handle PGP/MIME parts */ diff --git a/notmuch-client.h b/notmuch-client.h index 18e6c60..a41e90a 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -30,10 +30,6 @@ #include -typedef GMimeCryptoContext notmuch_crypto_context_t; -/* 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 @@ -53,6 +49,7 @@ typedef GMimeCryptoContext notmuch_crypto_context_t; #include #include "talloc-extra.h" +#include "crypto.h" #define unused(x) x __attribute__ ((unused)) @@ -70,21 +67,13 @@ typedef struct notmuch_show_format { const struct notmuch_show_params *params); } notmuch_show_format_t; -typedef struct notmuch_crypto { - notmuch_crypto_context_t* gpgctx; - notmuch_crypto_context_t* pkcs7ctx; - notmuch_bool_t verify; - notmuch_bool_t decrypt; - const char *gpgpath; -} notmuch_crypto_t; - typedef struct notmuch_show_params { notmuch_bool_t entire_thread; notmuch_bool_t omit_excluded; notmuch_bool_t output_body; notmuch_bool_t raw; int part; - notmuch_crypto_t crypto; + _notmuch_crypto_t crypto; notmuch_bool_t include_html; } notmuch_show_params_t; @@ -167,12 +156,6 @@ typedef struct _notmuch_config notmuch_config_t; void notmuch_exit_if_unsupported_format (void); -notmuch_crypto_context_t * -notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol); - -int -notmuch_crypto_cleanup (notmuch_crypto_t *crypto); - int notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]); @@ -423,7 +406,7 @@ struct mime_node { */ notmuch_status_t mime_node_open (const void *ctx, notmuch_message_t *message, - notmuch_crypto_t *crypto, mime_node_t **node_out); + _notmuch_crypto_t *crypto, mime_node_t **node_out); /* Return a new MIME node for the requested child part of parent. * parent will be used as the talloc context for the returned child diff --git a/notmuch-reply.c b/notmuch-reply.c index 6df54fc..eccfb32 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -862,7 +862,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) if (reply_format_func (config, config, query, ¶ms, reply_all, sp) != 0) return EXIT_FAILURE; - notmuch_crypto_cleanup (¶ms.crypto); + _notmuch_crypto_cleanup (¶ms.crypto); notmuch_query_destroy (query); notmuch_database_destroy (notmuch); diff --git a/notmuch-show.c b/notmuch-show.c index 87e52bb..3c91ece 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1171,7 +1171,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) ret = do_show (config, query, format, sprinter, ¶ms); } - notmuch_crypto_cleanup (¶ms.crypto); + _notmuch_crypto_cleanup (¶ms.crypto); notmuch_query_destroy (query); notmuch_database_destroy (notmuch); diff --git a/util/Makefile.local b/util/Makefile.local index 8b2b91b..7590618 100644 --- a/util/Makefile.local +++ b/util/Makefile.local @@ -5,7 +5,7 @@ extra_cflags += -I$(srcdir)/$(dir) libutil_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)/search-path.c + $(dir)/util.c $(dir)/search-path.c $(dir)/crypto.c libutil_modules := $(libutil_c_srcs:.c=.o) diff --git a/util/crypto.c b/util/crypto.c new file mode 100644 index 0000000..eab12a3 --- /dev/null +++ b/util/crypto.c @@ -0,0 +1,138 @@ +/* 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 http://www.gnu.org/licenses/ . + * + * Authors: Jameson Rollins + * Daniel Kahn Gillmor + */ + +#include "notmuch.h" +#include "crypto.h" +#include + +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0])) + +/* 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 crypto->gpgctx; +} + +/* Create a PKCS7 context (GMime 2.6) */ +static notmuch_crypto_context_t * +create_pkcs7_context (notmuch_crypto_t *crypto) +{ + notmuch_crypto_context_t *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 crypto->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; + } +} diff --git a/util/crypto.h b/util/crypto.h new file mode 100644 index 0000000..d4a51e8 --- /dev/null +++ b/util/crypto.h @@ -0,0 +1,25 @@ +#ifndef _CRYPTO_H +#define _CRYPTO_H + +#include "notmuch.h" +#include +/* This is automatically included only since gmime 2.6.10 */ +#include + +typedef struct _notmuch_crypto { + GMimeCryptoContext* gpgctx; + GMimeCryptoContext* pkcs7ctx; + notmuch_bool_t verify; + notmuch_bool_t decrypt; + const char *gpgpath; +} _notmuch_crypto_t; + + +GMimeCryptoContext * +_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol); + +void +_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto); + + +#endif -- 2.7.0.rc3