From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id ABBWDaEP+1+jMAAA0tVLHw (envelope-from ) for ; Sun, 10 Jan 2021 14:30:57 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1 with LMTPS id yKALCaEP+1/nVwAAbx9fmQ (envelope-from ) for ; Sun, 10 Jan 2021 14:30:57 +0000 Received: from mail.notmuchmail.org (nmbug.tethera.net [IPv6:2607:5300:201:3100::1657]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (2048 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 0C7499402A9 for ; Sun, 10 Jan 2021 14:30:56 +0000 (UTC) Received: from nmbug.tethera.net (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id 00A5E29E2B; Sun, 10 Jan 2021 09:30:49 -0500 (EST) Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by mail.notmuchmail.org (Postfix) with ESMTPS id C4C041FBCC for ; Sun, 10 Jan 2021 09:30:47 -0500 (EST) Received: by mail-wm1-x32c.google.com with SMTP id q75so12628425wme.2 for ; Sun, 10 Jan 2021 06:30:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dme-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=YeDUXOKu3g2Eiz8s0izhQJoegLNJIw7/JVVFrIq6/S8=; b=YiAZnV7XiVcc8aynIFfniQQfIq2Z9JwFrO8DZ600I2R/UDrwPG1fU4II2C2AQWPZeb XRRSo2XoAFdBDrVEGVyPH8Fo+sDll17f2N6BXk9O4X7isbYdurKCb4+E9VwCpr71w38j SjfP0yz9U5xziMLBAjqZibjnjePb4pXIZTkaFcZaqV7PR3+mZtk2H/jP2clikzqYAbtx 6/QYnRSK8sDHQh74EjoI+hIK8hkDMGC2/80achlv52rDmIjhy+F1E6HcZmkGom3qru97 H0SBTkpEjJX/EwFUdE2/eSY/tXD9efTT4iTf0hDxmSup1Y6+uFDdxyBxM6yHKa5st3D2 Tb2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=YeDUXOKu3g2Eiz8s0izhQJoegLNJIw7/JVVFrIq6/S8=; b=U3Wc6NuJc4s6jaJhqWEw+YNytApxdBgFTvwrMEz8K5/TzjsSAK5QFekCyp8ifSULiu fF0woNun0Gf/Z/4KL77ZoTFo+b93gdhvB7WWO41mlQ+XRqxcu/RrBlg6WmwwFkLnGtJt Sq+LS6CjZNY3vuVT4TqM7PQRNEbBLErCnRGqIUjNHIB9il6ymCVjtknxJ8btLYr+dDEk sizpnDJiE1kyBzuLETus3ITL7TmfzXJoSR6jUBkU1Z9/6HScnsORH+hF0A84YY1LKwVj Ot6nUaReQ188FZfpUWL3kWv1PH0yC9iTVOckF2y87drmI5wNqJ/AHB3dZCYEk3s2MN+5 0X6Q== X-Gm-Message-State: AOAM531SIR3ibXYiWqfU7wlJ1PibEPSAFtRzZAC9AlPuyE9Y/U9rpKDW 5BepPStViJ35Q9aqXqpV7AeAdw== X-Google-Smtp-Source: ABdhPJxM5Wi+QXslY99WU9OW6P1l5guZQM4jxmWf7Q8XKh65okL3pMZ87jpfCh1ay64kYbkgyjNR+g== X-Received: by 2002:a1c:2605:: with SMTP id m5mr11131303wmm.111.1610289046429; Sun, 10 Jan 2021 06:30:46 -0800 (PST) Received: from disaster-area.hh.sledj.net (disaster-area.hh.sledj.net. [2001:8b0:bb71:7140:64::1]) by smtp.gmail.com with ESMTPSA id y2sm18221992wma.6.2021.01.10.06.30.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 10 Jan 2021 06:30:45 -0800 (PST) Received: from localhost (disaster-area.hh.sledj.net [local]) by disaster-area.hh.sledj.net (OpenSMTPD) with ESMTPA id ec9a2c0f; Sun, 10 Jan 2021 14:30:44 +0000 (UTC) From: David Edmondson To: notmuch@notmuchmail.org Subject: [autocrypt RFC PATCH] Add support for the notmuch mua Date: Sun, 10 Jan 2021 14:30:44 +0000 Message-Id: <20210110143044.840094-1-dme@dme.org> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Message-ID-Hash: TDL6LCDD5TTZMD7U2NLO77PWLAQQDMZJ X-Message-ID-Hash: TDL6LCDD5TTZMD7U2NLO77PWLAQQDMZJ X-MailFrom: dme@dme.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0 CC: David Edmondson X-Mailman-Version: 3.2.1 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_IN X-Migadu-Spam-Score: 0.06 Authentication-Results: aspmx1.migadu.com; dkim=fail (body hash did not verify) header.d=dme-org.20150623.gappssmtp.com header.s=20150623 header.b=YiAZnV7X; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 2607:5300:201:3100::1657 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Queue-Id: 0C7499402A9 X-Spam-Score: 0.06 X-Migadu-Scanner: scn1.migadu.com X-TUID: Xh4MVh5+c4AM --- This is very much an RFC patch, as I'm new to autocrypt. It's also a patch for autocrypt (https://git.sr.ht/~zge/autocrypt) rather than notmuch, but it made more sense to send it here first, I think. Comments welcomed. autocrypt-notmuch.el | 103 +++++++++++++++++++++++++++++++++++++++++++ autocrypt.el | 11 +++++ 2 files changed, 114 insertions(+) create mode 100644 autocrypt-notmuch.el diff --git a/autocrypt-notmuch.el b/autocrypt-notmuch.el new file mode 100644 index 0000000..f365be2 --- /dev/null +++ b/autocrypt-notmuch.el @@ -0,0 +1,103 @@ +;;; autocrypt-notmuch.el --- Autocrypt for Notmuch -*- lexical-binding:t -*- + +;; Author: David Edmondson +;; Version: 0.4.0 +;; Keywords: comm +;; Package-Requires: ((emacs "25.1")) +;; URL: https://git.sr.ht/~zge/autocrypt + +;; This file is NOT part of Emacs. +;; +;; This file is in the public domain, to the extent possible under law, +;; published under the CC0 1.0 Universal license. +;; +;; For a full copy of the CC0 license see +;; https://creativecommons.org/publicdomain/zero/1.0/legalcode + +;;; Commentary: + +;; MUA specific functions for Notmuch +;; +;; Set up with: +;; (autocrypt-notmuch-install) + +;;; Code: + +(eval-when-compile + (require 'pcase)) + +(require 'notmuch-show) + +(defvar autocrypt-notmuch-headers-id nil) +(defvar autocrypt-notmuch-headers-cache nil) + +;;;###autoload +(defun autocrypt-notmuch-install () + "Install autocrypt hooks for Notmuch." + (add-hook 'notmuch-show-insert-msg-hook #'autocrypt-process-header)) + +(defun autocrypt-notmuch-uninstall () + "Remove autocrypt hooks for Notmuch." + (remove-hook 'notmuch-show-insert-msg-hook #'autocrypt-process-header) + + (when (and (bufferp autocrypt-notmuch-headers-cache) + (buffer-live-p autocrypt-notmuch-headers-cache)) + (kill-buffer autocrypt-notmuch-headers-cache))) + +(defun autocrypt-notmuch-header-1 (field) + "Return the FIELD header for the currently shown message." + + ;; Currently it is can be expensive to retrieve FIELD if the message + ;; is large, as this function examines a raw copy of the complete + ;; message in a buffer. Given that autocrypt will require several + ;; headers from each message and therefore make repeated calls to + ;; `autocrypt-notmuch-header', attempt to alleviate this cost using + ;; a single element cache containing the headers of any requested + ;; message. + + ;; This would be improved if: + ;; notmuch show --format=raw --body=false + ;; worked. + + (let ((id (notmuch-show-get-message-id t))) + ;; If the current header cache is not for this message, make it + ;; so. + (unless (and (string= id autocrypt-notmuch-headers-id) + (bufferp autocrypt-notmuch-headers-cache) + (buffer-live-p autocrypt-notmuch-headers-cache)) + (setq autocrypt-notmuch-headers-id id + autocrypt-notmuch-headers-cache (get-buffer-create "*autocrypt-notmuch-headers-cache*")) + + (with-current-notmuch-show-message + ;; Keep only the headers in the cache - the body is not + ;; required. + (mail-narrow-to-head) + + (let ((content (buffer-substring (point-min) (point-max)))) + (with-current-buffer autocrypt-notmuch-headers-cache + (erase-buffer) + (insert content)))))) + + (with-current-buffer autocrypt-notmuch-headers-cache + (mail-fetch-field field))) + +(defun autocrypt-notmuch-header (field) + "Ask Notmuch to return header FIELD for the current message." + + (pcase field + ;; Some headers are cached in the message properties - retrieving + ;; them is faster than extracting the raw message and parsing it. + ("Cc" (notmuch-show-get-date)) + ("Date" (notmuch-show-get-date)) + ("From" (notmuch-show-get-from)) + ("To" (notmuch-show-get-date)) + (_ + ;; If this is not a matching message, don't bother looking more + ;; deeply, given that `autocrypt-notmuch-headers-1' can be + ;; expensive for large messages. + (when (plist-get (notmuch-show-get-message-properties) :match) + (autocrypt-notmuch-header-1 field))))) + +(provide 'autocrypt-notmuch) + +;;; autocrypt-notmuch.el ends here diff --git a/autocrypt.el b/autocrypt.el index 965f661..01c36c1 100644 --- a/autocrypt.el +++ b/autocrypt.el @@ -115,6 +115,15 @@ Every member of this list has to be an instance of the :sign-encrypt autocrypt-message-sign-encrypt :secure-attach autocrypt-message-secure-attach :encrypted-p mml-secure-is-encrypted-p) + (notmuch + :install autocrypt-notmuch-install + :uninstall autocrypt-notmuch-uninstall + :header autocrypt-notmuch-header + :add-header autocrypt-message-add-header + :remove-header message-remove-header + :sign-encrypt autocrypt-message-sign-encrypt + :secure-attach autocrypt-message-secure-attach + :encrypted-p mml-secure-is-encrypted-p) (message :install autocrypt-message-install :uninstall autocrypt-message-uninstall @@ -154,6 +163,8 @@ the part contents can be found.") The key should identify a record in the `autocrypt-mua-func-alist' alist." (cond + ((derived-mode-p 'notmuch-show-mode) + 'notmuch) ((derived-mode-p 'mu4e-main-mode 'mu4e-view-mode) 'mu4e) ((derived-mode-p 'gnus-mode) -- 2.29.2