From 8b2130cc950b58452d31d4cf04e4a456e6e89e59 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Mon, 1 Feb 2016 15:39:47 +1900 Subject: [PATCH] [PATCH v3 02/16] Move crypto.c into libutil --- a8/9a129a709051faa8c944c811b5884764408675 | 566 ++++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 a8/9a129a709051faa8c944c811b5884764408675 diff --git a/a8/9a129a709051faa8c944c811b5884764408675 b/a8/9a129a709051faa8c944c811b5884764408675 new file mode 100644 index 000000000..e65da7731 --- /dev/null +++ b/a8/9a129a709051faa8c944c811b5884764408675 @@ -0,0 +1,566 @@ +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 + -- 2.26.2