From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 826306DE0EC6 for ; Mon, 27 May 2019 15:14:21 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.262 X-Spam-Level: X-Spam-Status: No, score=-0.262 tagged_above=-999 required=5 tests=[AWL=-0.061, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] 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 NZdJ7vkeLHdv for ; Mon, 27 May 2019 15:14:20 -0700 (PDT) Received: from che.mayfirst.org (che.mayfirst.org [162.247.75.118]) by arlo.cworth.org (Postfix) with ESMTPS id C07456DE0EC5 for ; Mon, 27 May 2019 15:14:20 -0700 (PDT) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019; t=1558995260; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : from; bh=FFNUeiQUcVVWeqxN3R5cXtzk+YPuljHPRhsWhKVtHv8=; b=TvMPJ8DCQ3dITTTf3HM+86sUx4zlkx7gBxwQB4N5jSXhk1IYFmJ1YeJM gHIceEBpx9vY2f4vBlw0ECX22ziQCA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fifthhorseman.net; i=@fifthhorseman.net; q=dns/txt; s=2019rsa; t=1558995260; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : from; bh=FFNUeiQUcVVWeqxN3R5cXtzk+YPuljHPRhsWhKVtHv8=; b=vPBZYzGfxxphavYfhZVuI+pksus08vrJTYJPa44vD9BJrmXTD6muGT40 3fixZ7fJ9nwb7B1vCKiuk8Wd9TJ3h6vyq6S1ABZt78Uz13yyVCLBewcj0B +uIUMDG1xaqISZqAn7ctagyNXUj5Wd45nYGahgccF4GjqKFL2coxOMD6TJ MaA6a+3c4VSSf18QEOMfZqVtMkrVm4qSCo6yqlYXrQW3ApRpsJgNmlN4jE o6tujxuUTEgJ/sx8045c5GqyLhOK4LSx/hbcWy/T2PGn7wX+jL/Ahkky4M FmygH4ixqVT0uqzw3Lo73uLEmddSbhOdTKOoLKwD//LH2nZgCp/N/Q== Received: from fifthhorseman.net (cpe-74-71-53-242.nyc.res.rr.com [74.71.53.242]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by che.mayfirst.org (Postfix) with ESMTPSA id E28F4F99D for ; Mon, 27 May 2019 18:14:19 -0400 (EDT) Received: by fifthhorseman.net (Postfix, from userid 1000) id E9AC52024B; Mon, 27 May 2019 18:14:16 -0400 (EDT) From: Daniel Kahn Gillmor To: Notmuch Mail Subject: [PATCH v4 06/17] cli/show: add information about which headers were protected Date: Mon, 27 May 2019 18:14:16 -0400 Message-Id: <20190527221416.9708-1-dkg@fifthhorseman.net> X-Mailer: git-send-email 2.20.1 In-Reply-To: <871s0kkxy3.fsf@tethera.net> References: <871s0kkxy3.fsf@tethera.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.29 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: Mon, 27 May 2019 22:14:21 -0000 The header-mask member of the per-message crypto object allows a clever UI frontend to mark whether a header was protected (or not). And if it was protected, it contains enough information to show useful detail to an interested user. For example, an MUA could offer a "show what this message's Subject looked like on the wire" feature in expert mode. As before, we only handle Subject for now, but we might be able to handle other headers in the future. Signed-off-by: Daniel Kahn Gillmor --- devel/schemata | 9 +++++++++ notmuch-show.c | 21 +++++++++++++++++++++ test/T356-protected-headers.sh | 4 ++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/devel/schemata b/devel/schemata index 72feb7b7..c0f69e7e 100644 --- a/devel/schemata +++ b/devel/schemata @@ -48,6 +48,9 @@ threadid = string # Message ID, sans "id:" messageid = string +# E-mail header name, sans trailing colon, like "Subject" or "In-Reply-To" +header_name = string + notmuch show schema ------------------- @@ -88,9 +91,15 @@ crypto = { status: sigstatus, # was the set of signatures described under encrypted cover? encrypted: bool, + # which of the headers is covered by sigstatus? + headers: [header_name*] }, decrypted?: { status: msgdecstatus, + # map encrypted headers that differed from the outside headers. + # the value of each item in the map is what that field showed externally + # (maybe null if it was not present in the external headers). + header-mask: { header_name: string|null,*} } } diff --git a/notmuch-show.c b/notmuch-show.c index b1f6a4bb..4dfe9c1d 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -645,6 +645,12 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, sp->map_key (sp, "encrypted"); sp->boolean (sp, msg_crypto->signature_encrypted); } + if (msg_crypto->payload_subject) { + sp->map_key (sp, "headers"); + sp->begin_list (sp); + sp->string (sp, "Subject"); + sp->end (sp); + } sp->end (sp); } if (msg_crypto->decryption_status != NOTMUCH_MESSAGE_DECRYPTED_NONE) { @@ -652,6 +658,21 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, mime_node_t *node, sp->begin_map (sp); sp->map_key (sp, "status"); sp->string (sp, msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL ? "full" : "partial"); + + if (msg_crypto->payload_subject) { + const char *subject = g_mime_message_get_subject GMIME_MESSAGE (node->part); + if (subject == NULL || strcmp (subject, msg_crypto->payload_subject)) { + /* protected subject differs from the external header */ + sp->map_key (sp, "header-mask"); + sp->begin_map (sp); + sp->map_key (sp, "Subject"); + if (subject == NULL) + sp->null (sp); + else + sp->string (sp, subject); + sp->end (sp); + } + } sp->end (sp); } } diff --git a/test/T356-protected-headers.sh b/test/T356-protected-headers.sh index 8a8fef6a..68d431e9 100755 --- a/test/T356-protected-headers.sh +++ b/test/T356-protected-headers.sh @@ -22,7 +22,7 @@ test_json_nodes <<<"$output" \ test_begin_subtest "verify protected header is visible with decryption" output=$(notmuch show --decrypt=true --format=json id:protected-header@crypto.notmuchmail.org) test_json_nodes <<<"$output" \ - 'crypto:[0][0][0]["crypto"]={"decrypted": {"status": "full"}}' \ + 'crypto:[0][0][0]["crypto"]={"decrypted": {"status": "full", "header-mask": {"Subject": "Subject Unavailable"}}}' \ 'subject:[0][0][0]["headers"]["Subject"]="This is a protected header"' test_begin_subtest "misplaced protected headers should not be made visible during decryption" @@ -58,7 +58,7 @@ test_json_nodes <<<"$output" \ test_begin_subtest "verify nested message/rfc822 protected header is visible" output=$(notmuch show --decrypt=true --format=json id:nested-rfc822-message@crypto.notmuchmail.org) test_json_nodes <<<"$output" \ - 'crypto:[0][0][0]["crypto"]={"decrypted": {"status": "full"}}' \ + 'crypto:[0][0][0]["crypto"]={"decrypted": {"status": "full", "header-mask": {"Subject": "Subject Unavailable"}}}' \ 'subject:[0][0][0]["headers"]["Subject"]="This is a message using draft-melnikov-smime-header-signing"' test_done -- 2.20.1