lib: convert notmuch decryption policy to an enum
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Fri, 8 Dec 2017 06:23:52 +0000 (01:23 -0500)
committerDavid Bremner <david@tethera.net>
Fri, 8 Dec 2017 12:07:02 +0000 (08:07 -0400)
Future patches in this series will introduce new policies; this merely
readies the way for them.

We also convert --try-decrypt to a keyword argument instead of a boolean.

lib/index.cc
lib/indexopts.c
lib/notmuch.h
mime-node.c
notmuch-client.h
notmuch-reply.c
notmuch-show.c
notmuch.c
test/T357-index-decryption.sh
util/crypto.h

index ff14e4089605f3e22d431f9f7fe8a88cc7454435..905366ae3c6fca5363e5c40eb8cbd67501eb0e87 100644 (file)
@@ -525,7 +525,7 @@ _index_encrypted_mime_part (notmuch_message_t *message,
     notmuch_database_t * notmuch = NULL;
     GMimeObject *clear = NULL;
 
-    if (!indexopts || !notmuch_indexopts_get_decrypt_policy (indexopts))
+    if (!indexopts || (notmuch_indexopts_get_decrypt_policy (indexopts) == NOTMUCH_DECRYPT_FALSE))
        return;
 
     notmuch = _notmuch_message_database (message);
index 0f65b97c9d1edbf8536a77863b23eab2e0d5b39c..78f533916f2a995f0da70df25ec42812caff4ef9 100644 (file)
@@ -26,25 +26,26 @@ notmuch_database_get_default_indexopts (notmuch_database_t *db)
     notmuch_indexopts_t *ret = talloc_zero (db, notmuch_indexopts_t);
     if (!ret)
        return ret;
+    ret->crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
 
-    char * decrypt;
-    notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt);
+    char * decrypt_policy;
+    notmuch_status_t err = notmuch_database_get_config (db, "index.decrypt", &decrypt_policy);
     if (err)
        return ret;
 
-    if (decrypt &&
-       ((!(strcasecmp(decrypt, "true"))) ||
-        (!(strcasecmp(decrypt, "yes"))) ||
-        (!(strcasecmp(decrypt, "1")))))
-       notmuch_indexopts_set_decrypt_policy (ret, true);
+    if (decrypt_policy &&
+       ((!(strcasecmp(decrypt_policy, "true"))) ||
+        (!(strcasecmp(decrypt_policy, "yes"))) ||
+        (!(strcasecmp(decrypt_policy, "1")))))
+       notmuch_indexopts_set_decrypt_policy (ret, NOTMUCH_DECRYPT_TRUE);
 
-    free (decrypt);
+    free (decrypt_policy);
     return ret;
 }
 
 notmuch_status_t
 notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
-                                     notmuch_bool_t decrypt_policy)
+                                     notmuch_decryption_policy_t decrypt_policy)
 {
     if (!indexopts)
        return NOTMUCH_STATUS_NULL_POINTER;
@@ -52,7 +53,7 @@ notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
-notmuch_bool_t
+notmuch_decryption_policy_t
 notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts)
 {
     if (!indexopts)
index ef463090ee09fb496debff66d7fc6b44341f520b..47633496c87cc75d9ff9da05614319450ae7691f 100644 (file)
@@ -2233,6 +2233,16 @@ notmuch_config_list_destroy (notmuch_config_list_t *config_list);
 notmuch_indexopts_t *
 notmuch_database_get_default_indexopts (notmuch_database_t *db);
 
+/**
+ * Stating a policy about how to decrypt messages.
+ *
+ * See index.decrypt in notmuch-config(1) for more details.
+ */
+typedef enum {
+    NOTMUCH_DECRYPT_FALSE,
+    NOTMUCH_DECRYPT_TRUE,
+} notmuch_decryption_policy_t;
+
 /**
  * Specify whether to decrypt encrypted parts while indexing.
  *
@@ -2245,7 +2255,7 @@ notmuch_database_get_default_indexopts (notmuch_database_t *db);
  */
 notmuch_status_t
 notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
-                                     notmuch_bool_t decrypt_policy);
+                                     notmuch_decryption_policy_t decrypt_policy);
 
 /**
  * Return whether to decrypt encrypted parts while indexing.
@@ -2253,7 +2263,7 @@ notmuch_indexopts_set_decrypt_policy (notmuch_indexopts_t *indexopts,
  *
  * @since libnotmuch 5.1 (notmuch 0.26)
  */
-notmuch_bool_t
+notmuch_decryption_policy_t
 notmuch_indexopts_get_decrypt_policy (const notmuch_indexopts_t *indexopts);
 
 /**
index daaae9f81ad5d510ed798aa20f55c7d14efe029a..c4de708b7806d75c9650325494f508892a4e5124 100644 (file)
@@ -270,7 +270,7 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part)
     }
 
 #if (GMIME_MAJOR_VERSION < 3)
-    if ((GMIME_IS_MULTIPART_ENCRYPTED (part) && node->ctx->crypto->decrypt)
+    if ((GMIME_IS_MULTIPART_ENCRYPTED (part) && (node->ctx->crypto->decrypt == NOTMUCH_DECRYPT_TRUE))
        || (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");
@@ -286,7 +286,7 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part)
 #endif
 
     /* Handle PGP/MIME parts */
-    if (GMIME_IS_MULTIPART_ENCRYPTED (part) && node->ctx->crypto->decrypt) {
+    if (GMIME_IS_MULTIPART_ENCRYPTED (part) && (node->ctx->crypto->decrypt == NOTMUCH_DECRYPT_TRUE)) {
        if (node->nchildren != 2) {
            /* this violates RFC 3156 section 4, so we won't bother with it. */
            fprintf (stderr, "Error: %d part(s) for a multipart/encrypted "
index fc981459f3cad724f61ecef626f5ba55407ab48c..50b69e35750c2f4a8ff69ddef9dd616da81ff06d 100644 (file)
@@ -414,9 +414,10 @@ struct mime_node {
 
 /* Construct a new MIME node pointing to the root message part of
  * message. If crypto->verify is true, signed child parts will be
- * verified. If crypto->decrypt is true, encrypted child parts will be
- * decrypted.  If the crypto contexts (crypto->gpgctx or
- * crypto->pkcs7) are NULL, they will be lazily initialized.
+ * verified. If crypto->decrypt is NOTMUCH_DECRYPT_TRUE, encrypted
+ * child parts will be decrypted.  If the crypto contexts
+ * (crypto->gpgctx or crypto->pkcs7) are NULL, they will be lazily
+ * initialized.
  *
  * Return value:
  *
@@ -500,7 +501,7 @@ int notmuch_minimal_options (const char* subcommand_name,
 /* the state chosen by the user invoking one of the notmuch
  * subcommands that does indexing */
 struct _notmuch_client_indexing_cli_choices {
-    bool decrypt_policy;
+    int decrypt_policy;
     bool decrypt_policy_set;
     notmuch_indexopts_t * opts;
 };
index 2c7cc4eba674c7cd761a5532ccb67dd55ad8a2b9..eec34bed9fcb80c5c51e27a29b74b3c35d0bee5c 100644 (file)
@@ -700,9 +700,11 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
     int opt_index;
     notmuch_show_params_t params = {
        .part = -1,
+       .crypto = { .decrypt = NOTMUCH_DECRYPT_FALSE },
     };
     int format = FORMAT_DEFAULT;
     int reply_all = true;
+    bool decrypt = false;
 
     notmuch_opt_desc_t options[] = {
        { .opt_keyword = &format, .name = "format", .keywords =
@@ -716,7 +718,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
          (notmuch_keyword_t []){ { "all", true },
                                  { "sender", false },
                                  { 0, 0 } } },
-       { .opt_bool = &params.crypto.decrypt, .name = "decrypt" },
+       { .opt_bool = &decrypt, .name = "decrypt" },
        { .opt_inherit = notmuch_shared_options },
        { }
     };
@@ -726,6 +728,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
        return EXIT_FAILURE;
 
     notmuch_process_shared_options (argv[0]);
+    if (decrypt)
+       params.crypto.decrypt = NOTMUCH_DECRYPT_TRUE;
 
     notmuch_exit_if_unsupported_format ();
 
index 7afd39478b0e3aa5665d94b5e2acb6234c6793c0..7ee9685aad0f9dca3701972b54d0efef24bfcd8f 100644 (file)
@@ -1083,11 +1083,13 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
        .part = -1,
        .omit_excluded = true,
        .output_body = true,
+       .crypto = { .decrypt = NOTMUCH_DECRYPT_FALSE },
     };
     int format = NOTMUCH_FORMAT_NOT_SPECIFIED;
     bool exclude = true;
     bool entire_thread_set = false;
     bool single_message;
+    bool decrypt = false;
 
     notmuch_opt_desc_t options[] = {
        { .opt_keyword = &format, .name = "format", .keywords =
@@ -1102,7 +1104,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
        { .opt_bool = &params.entire_thread, .name = "entire-thread",
          .present = &entire_thread_set },
        { .opt_int = &params.part, .name = "part" },
-       { .opt_bool = &params.crypto.decrypt, .name = "decrypt" },
+       { .opt_bool = &decrypt, .name = "decrypt" },
        { .opt_bool = &params.crypto.verify, .name = "verify" },
        { .opt_bool = &params.output_body, .name = "body" },
        { .opt_bool = &params.include_html, .name = "include-html" },
@@ -1116,9 +1118,11 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
 
     notmuch_process_shared_options (argv[0]);
 
-    /* decryption implies verification */
-    if (params.crypto.decrypt)
+    if (decrypt) {
+       params.crypto.decrypt = NOTMUCH_DECRYPT_TRUE;
+       /* decryption implies verification */
        params.crypto.verify = true;
+    }
 
     /* specifying a part implies single message display */
     single_message = params.part >= 0;
index 89d5e77b07ff1a5ba03eef8238d8989ac428c02d..7d5eeae4f035dca7191132a067b58e3b8f05d5f4 100644 (file)
--- a/notmuch.c
+++ b/notmuch.c
@@ -99,8 +99,11 @@ int notmuch_minimal_options (const char *subcommand_name,
 
 struct _notmuch_client_indexing_cli_choices indexing_cli_choices = { };
 const notmuch_opt_desc_t  notmuch_shared_indexing_options [] = {
-    { .opt_bool = &indexing_cli_choices.decrypt_policy,
-      .present = &indexing_cli_choices.decrypt_policy_set,
+    { .opt_keyword = &indexing_cli_choices.decrypt_policy,
+      .present = &indexing_cli_choices.decrypt_policy_set, .keywords =
+      (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
+                             { "true", NOTMUCH_DECRYPT_TRUE },
+                             { 0, 0 } },
       .name = "decrypt" },
     { }
 };
@@ -117,15 +120,15 @@ notmuch_process_shared_indexing_options (notmuch_database_t *notmuch, g_mime_3_u
            return NOTMUCH_STATUS_OUT_OF_MEMORY;
        status = notmuch_indexopts_set_decrypt_policy (indexing_cli_choices.opts, indexing_cli_choices.decrypt_policy);
        if (status != NOTMUCH_STATUS_SUCCESS) {
-           fprintf (stderr, "Error: Failed to set index decryption policy to %s. (%s)\n",
-                    indexing_cli_choices.decrypt_policy ? "True" : "False", notmuch_status_to_string (status));
+           fprintf (stderr, "Error: Failed to set index decryption policy to %d. (%s)\n",
+                    indexing_cli_choices.decrypt_policy, notmuch_status_to_string (status));
            notmuch_indexopts_destroy (indexing_cli_choices.opts);
            indexing_cli_choices.opts = NULL;
            return status;
        }
     }
 #if (GMIME_MAJOR_VERSION < 3)
-    if (indexing_cli_choices.opts && notmuch_indexopts_get_decrypt_policy (indexing_cli_choices.opts)) {
+    if (indexing_cli_choices.opts && notmuch_indexopts_get_decrypt_policy (indexing_cli_choices.opts) == NOTMUCH_DECRYPT_TRUE) {
        const char* gpg_path = notmuch_config_get_crypto_gpg_path (config);
        if (gpg_path && strcmp(gpg_path, "gpg"))
            fprintf (stderr, "Warning: deprecated crypto.gpg_path is set to '%s'\n"
index 2047d1455b0621e87fe3096037ce27172f67174b..15deaa6ee4ef3512061eccf45f98b7306bf81bf5 100755 (executable)
@@ -71,8 +71,8 @@ test_expect_equal \
 
 # try reinserting it with decryption, should appear again, but now we
 # have two copies of the message:
-test_begin_subtest "message cleartext is present after reinserting with --decrypt"
-notmuch insert --folder=sent --decrypt <<<"$contents"
+test_begin_subtest "message cleartext is present after reinserting with --decrypt=true"
+notmuch insert --folder=sent --decrypt=true <<<"$contents"
 output=$(notmuch search wumpus)
 expected='thread:0000000000000003   2000-01-01 [1/1(2)] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
 test_expect_equal \
@@ -93,8 +93,8 @@ test_expect_equal \
 # try inserting it with decryption, should appear as a single copy
 # (note: i think thread id skips 4 because of duplicate message-id
 # insertion, above)
-test_begin_subtest "message cleartext is present with insert --decrypt"
-notmuch insert --folder=sent --decrypt <<<"$contents"
+test_begin_subtest "message cleartext is present with insert --decrypt=true"
+notmuch insert --folder=sent --decrypt=true <<<"$contents"
 output=$(notmuch search wumpus)
 expected='thread:0000000000000005   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
 test_expect_equal \
@@ -159,7 +159,7 @@ test_expect_equal \
 add_email_corpus crypto
 
 test_begin_subtest "indexing message fails when secret key not available"
-notmuch reindex --decrypt id:simple-encrypted@crypto.notmuchmail.org
+notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
 output=$(notmuch dump )
 expected='#notmuch-dump batch-tag:3 config,properties,tags
 +encrypted +inbox +unread -- id:simple-encrypted@crypto.notmuchmail.org
@@ -180,7 +180,7 @@ notmuch restore <<EOF
 #notmuch-dump batch-tag:3 config,properties,tags
 #= simple-encrypted@crypto.notmuchmail.org session-key=9%3AFC09987F5F927CC0CC0EE80A96E4C5BBF4A499818FB591207705DFDDD6112CF9
 EOF
-notmuch reindex --decrypt id:simple-encrypted@crypto.notmuchmail.org
+notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
 output=$(notmuch search sekrit)
 expected='thread:0000000000000001   2016-12-22 [1/1] Daniel Kahn Gillmor; encrypted message (encrypted inbox unread)'
 if [ $NOTMUCH_HAVE_GMIME_SESSION_KEYS -eq 0 ]; then
index 0c62ac70d8f1cfde40634964654b2fb58c14e229..b23ca7472a6e05281d2b5d3bfe2f68ea11cd4d73 100644 (file)
@@ -7,7 +7,7 @@
 
 typedef struct _notmuch_crypto {
     bool verify;
-    bool decrypt;
+    notmuch_decryption_policy_t decrypt;
 #if (GMIME_MAJOR_VERSION < 3)
     GMimeCryptoContext* gpgctx;
     GMimeCryptoContext* pkcs7ctx;