diff --git a/lib/index.cc b/lib/index.cc index ff14e408..905366ae 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -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); diff --git a/lib/indexopts.c b/lib/indexopts.c index 0f65b97c..78f53391 100644 --- a/lib/indexopts.c +++ b/lib/indexopts.c @@ -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) diff --git a/lib/notmuch.h b/lib/notmuch.h index ef463090..47633496 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -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); /** diff --git a/mime-node.c b/mime-node.c index daaae9f8..c4de708b 100644 --- a/mime-node.c +++ b/mime-node.c @@ -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 " diff --git a/notmuch-client.h b/notmuch-client.h index fc981459..50b69e35 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -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; }; diff --git a/notmuch-reply.c b/notmuch-reply.c index 2c7cc4eb..eec34bed 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -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 = ¶ms.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 (); diff --git a/notmuch-show.c b/notmuch-show.c index 7afd3947..7ee9685a 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -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 = ¶ms.entire_thread, .name = "entire-thread", .present = &entire_thread_set }, { .opt_int = ¶ms.part, .name = "part" }, - { .opt_bool = ¶ms.crypto.decrypt, .name = "decrypt" }, + { .opt_bool = &decrypt, .name = "decrypt" }, { .opt_bool = ¶ms.crypto.verify, .name = "verify" }, { .opt_bool = ¶ms.output_body, .name = "body" }, { .opt_bool = ¶ms.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; diff --git a/notmuch.c b/notmuch.c index 89d5e77b..7d5eeae4 100644 --- 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" diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh index 2047d145..15deaa6e 100755 --- a/test/T357-index-decryption.sh +++ b/test/T357-index-decryption.sh @@ -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 <