From: Daniel Kahn Gillmor Date: Fri, 8 Jul 2016 09:27:14 +0000 (+0200) Subject: [PATCH v4 03/16] make shared crypto code behave library-like X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8a2ac72e564864c70e83aff088436e2e6198ae29;p=notmuch-archives.git [PATCH v4 03/16] make shared crypto code behave library-like --- diff --git a/6f/f62a6921f611a0a893b1bca9605773344a56c7 b/6f/f62a6921f611a0a893b1bca9605773344a56c7 new file mode 100644 index 000000000..1f331e11c --- /dev/null +++ b/6f/f62a6921f611a0a893b1bca9605773344a56c7 @@ -0,0 +1,290 @@ +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 2294A6DE09ED + for ; Fri, 8 Jul 2016 03:14:08 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at cworth.org +X-Spam-Flag: NO +X-Spam-Score: 0.041 +X-Spam-Level: +X-Spam-Status: No, score=0.041 tagged_above=-999 required=5 tests=[AWL=0.041] + 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 xLj-IHd1uwvi for ; + Fri, 8 Jul 2016 03:14:00 -0700 (PDT) +Received: from che.mayfirst.org (che.mayfirst.org [162.247.75.118]) + by arlo.cworth.org (Postfix) with ESMTP id D41CB6DE0363 + for ; Fri, 8 Jul 2016 03:13:12 -0700 (PDT) +Received: from fifthhorseman.net (unknown [88.128.80.54]) + by che.mayfirst.org (Postfix) with ESMTPSA id 02291F99D + for ; Fri, 8 Jul 2016 06:13:11 -0400 (EDT) +Received: by fifthhorseman.net (Postfix, from userid 1000) + id 8C60420E94; Fri, 8 Jul 2016 11:27:34 +0200 (CEST) +From: Daniel Kahn Gillmor +To: Notmuch Mail +Subject: [PATCH v4 03/16] make shared crypto code behave library-like +Date: Fri, 8 Jul 2016 11:27:14 +0200 +Message-Id: <1467970047-8013-4-git-send-email-dkg@fifthhorseman.net> +X-Mailer: git-send-email 2.8.1 +In-Reply-To: <1467970047-8013-1-git-send-email-dkg@fifthhorseman.net> +References: <1467970047-8013-1-git-send-email-dkg@fifthhorseman.net> +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: Fri, 08 Jul 2016 10:14:08 -0000 + +If we're going to reuse the crypto code across both the library and +the client, then it needs to report error states properly and not +write to stderr. +--- + lib/database.cc | 6 ++++ + lib/notmuch.h | 17 +++++++++++ + mime-node.c | 7 ++++- + util/crypto.c | 89 ++++++++++++++++++++++++++++----------------------------- + util/crypto.h | 6 ++-- + 5 files changed, 76 insertions(+), 49 deletions(-) + +diff --git a/lib/database.cc b/lib/database.cc +index 3bdbd07..9d6b6f2 100644 +--- a/lib/database.cc ++++ b/lib/database.cc +@@ -369,6 +369,12 @@ notmuch_status_to_string (notmuch_status_t status) + return "Operation requires a database upgrade"; + case NOTMUCH_STATUS_PATH_ERROR: + return "Path supplied is illegal for this function"; ++ case NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL: ++ return "Crypto protocol missing, malformed, or unintelligible"; ++ case NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION: ++ return "Crypto engine initialization failure"; ++ case NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL: ++ return "Unknown crypto protocol"; + default: + case NOTMUCH_STATUS_LAST_STATUS: + return "Unknown error status value"; +diff --git a/lib/notmuch.h b/lib/notmuch.h +index 0d667f5..aaed516 100644 +--- a/lib/notmuch.h ++++ b/lib/notmuch.h +@@ -185,6 +185,23 @@ typedef enum _notmuch_status { + */ + NOTMUCH_STATUS_ILLEGAL_ARGUMENT, + /** ++ * A MIME object claimed to have cryptographic protection which ++ * notmuch tried to handle, but the protocol was not specified in ++ * an intelligible way. ++ */ ++ NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL, ++ /** ++ * Notmuch attempted to do crypto processing, but could not ++ * initialize the engine needed to do so. ++ */ ++ NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION, ++ /** ++ * A MIME object claimed to have cryptographic protection, and ++ * notmuch attempted to process it, but the specific protocol was ++ * something that notmuch doesn't know how to handle. ++ */ ++ NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL, ++ /** + * Not an actual status value. Just a way to find out how many + * valid status values there are. + */ +diff --git a/mime-node.c b/mime-node.c +index 14873ce..717a122 100644 +--- a/mime-node.c ++++ b/mime-node.c +@@ -244,7 +244,12 @@ _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_gmime_context (node->ctx->crypto, protocol); ++ notmuch_status_t status; ++ status = _notmuch_crypto_get_gmime_ctx_for_protocol (node->ctx->crypto, ++ protocol, &cryptoctx); ++ if (status) /* this is a warning, not an error */ ++ fprintf (stderr, "Warning: %s (%s).\n", notmuch_status_to_string (status), ++ protocol ? protocol : "(NULL)"); + } + + /* Handle PGP/MIME parts */ +diff --git a/util/crypto.c b/util/crypto.c +index 48c20bb..cce5cbc 100644 +--- a/util/crypto.c ++++ b/util/crypto.c +@@ -25,86 +25,86 @@ + + #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) ++/* Create or pass on a GPG context (GMime 2.6) */ ++static notmuch_status_t ++get_gpg_context (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx) + { +- GMimeCryptoContext *gpgctx; ++ if (ctx == NULL || crypto == NULL) ++ return NOTMUCH_STATUS_NULL_POINTER; + + if (crypto->gpgctx) { +- return crypto->gpgctx; ++ *ctx = crypto->gpgctx; ++ return NOTMUCH_STATUS_SUCCESS; + } + + /* 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 = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg"); ++ if (! crypto->gpgctx) { ++ return NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION; + } +- crypto->gpgctx = gpgctx; + +- g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, TRUE); +- g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE); ++ g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) crypto->gpgctx, TRUE); ++ g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) crypto->gpgctx, FALSE); + +- return crypto->gpgctx; ++ *ctx = crypto->gpgctx; ++ return NOTMUCH_STATUS_SUCCESS; + } + +-/* Create a PKCS7 context (GMime 2.6) */ +-static notmuch_crypto_context_t * +-create_pkcs7_context (notmuch_crypto_t *crypto) ++/* Create or pass on a PKCS7 context (GMime 2.6) */ ++static notmuch_status_t ++get_pkcs7_context (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx) + { +- notmuch_crypto_context_t *pkcs7ctx; ++ if (ctx == NULL || crypto == NULL) ++ return NOTMUCH_STATUS_NULL_POINTER; + +- if (crypto->pkcs7ctx) +- return crypto->pkcs7ctx; ++ if (crypto->pkcs7ctx) { ++ *ctx = crypto->pkcs7ctx; ++ return NOTMUCH_STATUS_SUCCESS; ++ } + + /* TODO: GMimePasswordRequestFunc */ +- pkcs7ctx = g_mime_pkcs7_context_new (NULL); +- if (! pkcs7ctx) { +- fprintf (stderr, "Failed to construct pkcs7 context.\n"); +- return NULL; ++ crypto->pkcs7ctx = g_mime_pkcs7_context_new (NULL); ++ if (! crypto->pkcs7ctx) { ++ return NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION; + } +- crypto->pkcs7ctx = pkcs7ctx; + +- g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx, ++ g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) crypto->pkcs7ctx, + FALSE); + +- return crypto->pkcs7ctx; ++ *ctx = crypto->pkcs7ctx; ++ return NOTMUCH_STATUS_SUCCESS; + } + static const struct { + const char *protocol; +- GMimeCryptoContext *(*get_context) (_notmuch_crypto_t *crypto); ++ notmuch_status_t (*get_context) (_notmuch_crypto_t *crypto, GMimeCryptoContext **ctx); + } protocols[] = { + { + .protocol = "application/pgp-signature", +- .get_context = create_gpg_context, ++ .get_context = get_gpg_context, + }, + { + .protocol = "application/pgp-encrypted", +- .get_context = create_gpg_context, ++ .get_context = get_gpg_context, + }, + { + .protocol = "application/pkcs7-signature", +- .get_context = create_pkcs7_context, ++ .get_context = get_pkcs7_context, + }, + { + .protocol = "application/x-pkcs7-signature", +- .get_context = create_pkcs7_context, ++ .get_context = get_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) ++notmuch_status_t ++_notmuch_crypto_get_gmime_ctx_for_protocol (_notmuch_crypto_t *crypto, ++ const char *protocol, ++ GMimeCryptoContext **ctx) + { +- GMimeCryptoContext *cryptoctx = NULL; +- size_t i; +- +- if (! protocol) { +- fprintf (stderr, "Cryptographic protocol is empty.\n"); +- return cryptoctx; +- } ++ if (! protocol) ++ return NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL; + + /* As per RFC 1847 section 2.1: "the [protocol] value token is + * comprised of the type and sub-type tokens of the Content-Type". +@@ -112,15 +112,12 @@ _notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protoc + * 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++) { ++ for (size_t i = 0; i < ARRAY_SIZE (protocols); i++) { + if (strcasecmp (protocol, protocols[i].protocol) == 0) +- return protocols[i].get_context (crypto); ++ return protocols[i].get_context (crypto, ctx); + } + +- fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n", +- protocol); +- +- return NULL; ++ return NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL; + } + + void +diff --git a/util/crypto.h b/util/crypto.h +index d4a51e8..7cb0a39 100644 +--- a/util/crypto.h ++++ b/util/crypto.h +@@ -15,8 +15,10 @@ typedef struct _notmuch_crypto { + } _notmuch_crypto_t; + + +-GMimeCryptoContext * +-_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol); ++notmuch_status_t ++_notmuch_crypto_get_gmime_ctx_for_protocol (_notmuch_crypto_t *crypto, ++ const char *protocol, ++ GMimeCryptoContext **ctx); + + void + _notmuch_crypto_cleanup (_notmuch_crypto_t *crypto); +-- +2.8.1 +