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 <d...@fifthhorseman.net>
---
 devel/schemata                 |  6 ++++++
 notmuch-show.c                 | 21 +++++++++++++++++++++
 test/T356-protected-headers.sh |  4 ++--
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/devel/schemata b/devel/schemata
index 72feb7b7..9d3c8d30 100644
--- a/devel/schemata
+++ b/devel/schemata
@@ -88,9 +88,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-hea...@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-mess...@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

_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to