aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno2013-01-07 12:59:02 +0900
committerDaiki Ueno2013-01-07 12:59:02 +0900
commit38eba8dfc489f91d5d02291cea7b4155461f730d (patch)
tree45e6661f5419d0ce4356327df196ed6216d5dfe1
parent84f6744ab74d1c5f201e88273fc6faa65956a440 (diff)
downloademacs-38eba8dfc489f91d5d02291cea7b4155461f730d.tar.gz
emacs-38eba8dfc489f91d5d02291cea7b4155461f730d.zip
lisp/gnus/mml-smime.el: Support signing by sender.
-rw-r--r--lisp/gnus/ChangeLog10
-rw-r--r--lisp/gnus/mml-smime.el62
2 files changed, 56 insertions, 16 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index c1140c526f6..40600fc20a9 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,13 @@
12013-01-07 Daiki Ueno <ueno@gnu.org>
2
3 * mml-smime.el: Support signing by sender.
4 Requested by Uwe Brauer.
5 (mml-smime-sign-with-sender): New user option analogous
6 to mml2015-sign-with-sender.
7 (mml-smime-epg-sign): Respect mml-smime-sign-with-sender.
8 (mml-smime-epg-find-usable-secret-key): New helper function copied from
9 mml2015.el.
10
12012-12-31 Lars Magne Ingebrigtsen <larsi@gnus.org> 112012-12-31 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 12
3 * gnus-msg.el (gnus-inews-insert-gcc): Don't insert Gcc headers if Gnus 13 * gnus-msg.el (gnus-inews-insert-gcc): Don't insert Gcc headers if Gnus
diff --git a/lisp/gnus/mml-smime.el b/lisp/gnus/mml-smime.el
index 3e769d396b0..e7f9de7980d 100644
--- a/lisp/gnus/mml-smime.el
+++ b/lisp/gnus/mml-smime.el
@@ -74,6 +74,11 @@ Whether the passphrase is cached at all is controlled by
74 :group 'mime-security 74 :group 'mime-security
75 :type '(repeat (string :tag "Key ID"))) 75 :type '(repeat (string :tag "Key ID")))
76 76
77(defcustom mml-smime-sign-with-sender nil
78 "If t, use message sender so find a key to sign with."
79 :group 'mime-security
80 :type 'boolean)
81
77(defun mml-smime-sign (cont) 82(defun mml-smime-sign (cont)
78 (let ((func (nth 1 (assq mml-smime-use mml-smime-function-alist)))) 83 (let ((func (nth 1 (assq mml-smime-use mml-smime-function-alist))))
79 (if func 84 (if func
@@ -366,6 +371,24 @@ Whether the passphrase is cached at all is controlled by
366 (setq pointer (cdr pointer)))) 371 (setq pointer (cdr pointer))))
367 (setq keys (cdr keys))))) 372 (setq keys (cdr keys)))))
368 373
374;; XXX: since gpg --list-secret-keys does not return validity of each
375;; key, `mml-smime-epg-find-usable-key' defined above is not enough for
376;; secret keys. The function `mml-smime-epg-find-usable-secret-key'
377;; below looks at appropriate public keys to check usability.
378(defun mml-smime-epg-find-usable-secret-key (context name usage)
379 (let ((secret-keys (epg-list-keys context name t))
380 secret-key)
381 (while (and (not secret-key) secret-keys)
382 (if (mml-smime-epg-find-usable-key
383 (epg-list-keys context (epg-sub-key-fingerprint
384 (car (epg-key-sub-key-list
385 (car secret-keys)))))
386 usage)
387 (setq secret-key (car secret-keys)
388 secret-keys nil)
389 (setq secret-keys (cdr secret-keys))))
390 secret-key))
391
369(autoload 'mml-compute-boundary "mml") 392(autoload 'mml-compute-boundary "mml")
370 393
371;; We require mm-decode, which requires mm-bodies, which autoloads 394;; We require mm-decode, which requires mm-bodies, which autoloads
@@ -376,29 +399,36 @@ Whether the passphrase is cached at all is controlled by
376 (let* ((inhibit-redisplay t) 399 (let* ((inhibit-redisplay t)
377 (context (epg-make-context 'CMS)) 400 (context (epg-make-context 'CMS))
378 (boundary (mml-compute-boundary cont)) 401 (boundary (mml-compute-boundary cont))
402 (sender (message-options-get 'message-sender))
403 (signer-names (or mml-smime-signers
404 (if (and mml-smime-sign-with-sender sender)
405 (list (concat "<" sender ">")))))
379 signer-key 406 signer-key
380 (signers 407 (signers
381 (or (message-options-get 'mml-smime-epg-signers) 408 (or (message-options-get 'mml-smime-epg-signers)
382 (message-options-set 409 (message-options-set
383 'mml-smime-epg-signers 410 'mml-smime-epg-signers
384 (if (eq mm-sign-option 'guided) 411 (if (eq mm-sign-option 'guided)
385 (epa-select-keys context "\ 412 (epa-select-keys context "\
386Select keys for signing. 413Select keys for signing.
387If no one is selected, default secret key is used. " 414If no one is selected, default secret key is used. "
388 mml-smime-signers t) 415 signer-names
389 (if mml-smime-signers 416 t)
390 (mapcar 417 (if (or sender mml-smime-signers)
391 (lambda (signer) 418 (delq nil
392 (setq signer-key (mml-smime-epg-find-usable-key 419 (mapcar
393 (epg-list-keys context signer t) 420 (lambda (signer)
394 'sign)) 421 (setq signer-key
395 (unless (or signer-key 422 (mml-smime-epg-find-usable-secret-key
396 (y-or-n-p 423 context signer 'sign))
397 (format "No secret key for %s; skip it? " 424 (unless (or signer-key
425 (y-or-n-p
426 (format
427 "No secret key for %s; skip it? "
398 signer))) 428 signer)))
399 (error "No secret key for %s" signer)) 429 (error "No secret key for %s" signer))
400 signer-key) 430 signer-key)
401 mml-smime-signers)))))) 431 signer-names)))))))
402 signature micalg) 432 signature micalg)
403 (epg-context-set-signers context signers) 433 (epg-context-set-signers context signers)
404 (if mml-smime-cache-passphrase 434 (if mml-smime-cache-passphrase