Synch with Gnus.
authoryamaoka <yamaoka>
Mon, 13 Nov 2000 22:53:12 +0000 (22:53 +0000)
committeryamaoka <yamaoka>
Mon, 13 Nov 2000 22:53:12 +0000 (22:53 +0000)
20 files changed:
lisp/ChangeLog
lisp/gnus-art.el
lisp/gnus-cite.el
lisp/gnus-msg.el
lisp/gnus-sum.el
lisp/message.el
lisp/mm-decode.el
lisp/mm-extern.el
lisp/mm-uu.el
lisp/mml-smime.el
lisp/mml2015.el
lisp/rfc2231.el
lisp/smime.el
texi/ChangeLog
texi/emacs-mime.texi
texi/gnus-ja.texi
texi/gnus.texi
texi/message-ja.texi
texi/message.texi
todo

index 950c44b..4d896fc 100644 (file)
@@ -1,9 +1,138 @@
+2000-11-13 16:09:09  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * mml2015.el (mml2015-mailcrypt-decrypt): Handle quit.
+       (mml2015-mailcrypt-clear-decrypt): Ditto.
+       (mml2015-mailcrypt-verify): Ditto.
+       (mml2015-mailcrypt-clear-verify): Ditto.
+       (mml2015-gpg-verify): Ditto.
+
+2000-11-13 15:29:58  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * smime.el (smime-openssl-program): Test the existence of openssl.
+       * mml-smime.el: Require mm-decode.
+       (mml-smime-verify-test): New function.
+       * mm-decode.el (mm-verify-function-alist): Use it.
+
+2000-11-13 09:50:29  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-sum.el (gnus-summary-repair-multipart): Fix Mime-Version
+       anyway.
+
+2000-11-13  Simon Josefsson  <sj@extundo.com>
+
+       * mm-uu.el (mm-uu-pgp-signed-extract): Explain why clear
+       verification doesn't work.
+
+2000-11-12 23:36:45  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-msg.el (gnus-inews-mark-gcc-as-read): New variable.
+       (gnus-inews-do-gcc): Use it.
+
+2000-11-12 21:35:04  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * rfc2231.el (rfc2231-encode-string): Insert semi-colon and
+       leading space.
+       * mm-extern.el (mm-inline-external-body): Report error when no 
+       access-type.
+
+2000-11-12 19:48:30  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-sum.el (gnus-select-newsgroup): Change the error message.
+
+2000-11-12 11:53:18  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-art.el (gnus-mime-button-menu): Use select-window.
+
+2000-11-12 09:47:54  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-art.el (gnus-mime-display-part): Display multipart/related
+       as multipart/mixed.
+
+2000-11-12  David Edmondson  <dme@dme.org>
+       
+       * message.el (message-cite-prefix-regexp): moved from gnus-cite.el
+       and replace `.' with `\w' to allow for different syntax tables
+       (from Vladimir Volovich).
+       * message.el (message-newline-and-reformat): use
+       `message-cite-prefix-regexp'.
+       * gnus-cite.el (gnus-supercite-regexp): use
+       `message-cite-prefix-regexp'.
+       * gnus-cite.el (gnus-cite-parse): use
+       `message-cite-prefix-regexp'.
+
+2000-11-12 08:52:46  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * mml2015.el (mml2015-mailcrypt-verify): Replace armors with
+       PGP SIGNATURE.  Escape leading "-"'s.
+       (mml2015-mailcrypt-sign): Replace armors with PGP MESSAGE.
+
+2000-11-11 15:55:35  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * mm-uu.el (mm-uu-type-alist): Stricter shar regexp.
+
+2000-11-11  Simon Josefsson  <sj@extundo.com>
+
+       * mml2015.el (mml2015-gpg-verify): Set "OK" security status.
+
+       * smime.el (smime-details-buffer): New variable.
+       (smime-sign-region): 
+       (smime-encrypt-region): 
+       (smime-verify-region): 
+       (smime-decrypt-region): Copy OpenSSL output to the buffer.
+
+       * mml-smime.el (mml-smime-verify): Support security info.
+
+2000-11-10 17:11:22  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * mm-decode.el (mm-verify-option): Set default to nil.
+       (mm-decrypt-option): Ditto.
+       * gnus-art.el (article-verify-x-pgp-sig): New function.
+
+2000-11-10 09:01:25  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-art.el (gnus-mime-display-alternative): Show button if no
+       preferred part.
+
 2000-11-07  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus-sum.el (gnus-move-split-methods): Say that
        `gnus-split-methods' uses file names, whereas this uses group
        names.  (Report from Nevin Kapur)
 
+2000-11-10 01:23:20  ShengHuo ZHU  <zsh@cs.rochester.edu>
+  
+       * mm-partial.el (mm-inline-partial): Insert MIME-Version.
+
+2000-11-09 17:02:50  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * nnheader.el (nnheader-directory-files-is-safe): New variable.
+       (nnheader-directory-articles): Use it.
+       (nnheader-article-to-file-alist): Ditto.
+
+2000-11-09 16:20:37  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * rfc2047.el (rfc2047-pad-base64): New function.
+       (rfc2047-decode): Use it.
+
+2000-11-09 08:53:04  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-srvr.el (gnus-browse-foreign-server): Bind the original
+       select method.
+
+2000-11-08 19:58:58  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * mml2015.el (mml2015-gpg-decrypt-1): 
+       (mml2015-gpg-verify): buffer-string has no argument in Emacs.
+
+2000-11-08 16:37:02  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * gnus-cache.el (gnus-cache-generate-nov-databases): Reopen cache.
+
+2000-11-08 08:38:30  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * pop3.el (pop3-munge-message-separator): A message may have an
+       empty body.
+  
 2000-11-07 18:02:26  ShengHuo ZHU  <zsh@cs.rochester.edu>
 
        * mm-uu.el (mm-uu-type-alist): Don't test pgp stuff.
 
 2000-09-29  David Edmondson  <dme@thus.net>
 
-       One-line patch.
-       
        * message.el (message-newline-and-reformat): Typo.
 
 2000-11-04 10:11:05  ShengHuo ZHU  <zsh@cs.rochester.edu>
index acf82c9..031ec4a 100644 (file)
@@ -1013,6 +1013,14 @@ See the manual for details."
   :group 'gnus-article-treat
   :type gnus-article-treat-custom)
 
+(defcustom gnus-treat-x-pgp-sig 'head
+  "Verify X-PGP-Sig.
+Valid values are nil, t, `head', `last', an integer or a predicate.
+See the manual for details."
+  :group 'gnus-article-treat
+  :group 'mime-security
+  :type gnus-article-treat-custom)
+
 (defvar gnus-article-encrypt-protocol-alist
   '(("PGP" . mml2015-self-encrypt)))
 
@@ -1034,6 +1042,7 @@ It is a string, such as \"PGP\". If nil, ask user."
 (defvar gnus-treatment-function-alist
   '((gnus-treat-decode-article-as-default-mime-charset
      gnus-article-decode-article-as-default-mime-charset)
+    (gnus-treat-x-pgp-sig gnus-article-verify-x-pgp-sig)
     (gnus-treat-strip-banner gnus-article-strip-banner)
     (gnus-treat-strip-headers-in-body gnus-article-strip-headers-in-body)
     (gnus-treat-buttonize gnus-article-add-buttons)
@@ -2747,6 +2756,76 @@ If variable `gnus-use-long-file-name' is non-nil, it is
         (expand-file-name "news" (gnus-newsgroup-directory-form newsgroup)))
        gnus-article-save-directory)))
 
+(defun article-verify-x-pgp-sig ()
+  "Verify X-PGP-Sig."
+  (interactive)
+  (let ((sig (with-current-buffer gnus-original-article-buffer
+              (gnus-fetch-field "X-PGP-Sig")))
+       items info headers)
+    (when (and sig (mm-uu-pgp-signed-test))
+      (with-temp-buffer
+       (insert-buffer gnus-original-article-buffer)
+       (setq items (split-string sig))
+       (message-narrow-to-head)
+       (let ((inhibit-point-motion-hooks t)
+             (case-fold-search t))
+         ;; Don't verify multiple headers.
+         (setq headers (mapconcat (lambda (header)
+                                    (concat header ": " 
+                                            (mail-fetch-field header) "\n"))
+                                  (split-string (nth 1 items) ",") "")))
+       (delete-region (point-min) (point-max))
+       (insert "-----BEGIN PGP SIGNED MESSAGE-----\n\n")
+       (insert "X-Signed-Headers: " (nth 1 items) "\n")
+       (insert headers)
+       (widen)
+       (forward-line)
+       (while (not (eobp))
+         (if (looking-at "^-")
+             (insert "- "))
+         (forward-line))
+       (insert "\n-----BEGIN PGP SIGNATURE-----\n")
+       (insert "Version: " (car items) "\n\n")
+       (insert (mapconcat 'identity (cddr items) "\n"))
+       (insert "\n-----END PGP SIGNATURE-----\n")
+       (let ((mm-security-handle (list (format "multipart/signed"))))
+         (mml2015-clean-buffer)
+         (let ((coding-system-for-write (or gnus-newsgroup-charset
+                                            'iso-8859-1)))
+           (funcall (mml2015-clear-verify-function)))
+         (setq info 
+               (or (mm-handle-multipart-ctl-parameter 
+                    mm-security-handle 'gnus-details)
+                   (mm-handle-multipart-ctl-parameter 
+                    mm-security-handle 'gnus-info)))))
+      (when info
+       (let (buffer-read-only bface eface)
+         (save-restriction
+           (message-narrow-to-head)
+           (goto-char (point-max))
+           (forward-line -1)
+           (setq bface (get-text-property (gnus-point-at-bol) 'face)
+                 eface (get-text-property (1- (gnus-point-at-eol)) 'face))
+           (message-remove-header "X-Gnus-PGP-Verify")
+           (if (re-search-forward "^X-PGP-Sig:" nil t)
+               (forward-line)
+             (goto-char (point-max)))
+           (narrow-to-region (point) (point))
+           (insert "X-Gnus-PGP-Verify: " info "\n")
+           (goto-char (point-min))
+           (forward-line)
+           (while (not (eobp))
+             (if (not (looking-at "^[ \t]"))
+                 (insert " "))
+             (forward-line))
+           ;; Do highlighting.
+           (goto-char (point-min))
+           (when (looking-at "\\([^:]+\\): *")
+             (put-text-property (match-beginning 1) (1+ (match-end 1))
+                                'face bface)
+             (put-text-property (match-end 0) (point-max)
+                                'face eface))))))))
+
 (eval-and-compile
   (mapcar
    (lambda (func)
@@ -2767,6 +2846,7 @@ If variable `gnus-use-long-file-name' is non-nil, it is
                    (call-interactively ',afunc)
                  (apply ',afunc args))))))))
    '(article-hide-headers
+     article-verify-x-pgp-sig
      article-hide-boring-headers
      article-toggle-headers
      article-treat-overstrike
@@ -3331,9 +3411,9 @@ value of the variable `gnus-show-mime' is non-nil."
 (defun gnus-mime-button-menu (event)
   "Construct a context-sensitive menu of MIME commands."
   (interactive "e")
-  (save-excursion
+  (save-window-excursion
     (let ((pos (event-start event)))
-      (set-buffer (window-buffer (posn-window pos)))
+      (select-window (posn-window pos))
       (goto-char (posn-point pos))
       (gnus-article-check-buffer)
       (let ((response (x-popup-menu
@@ -3855,8 +3935,11 @@ In no internal viewer is available, use an external viewer."
         (not gnus-mime-display-multipart-as-mixed))
     ;;;!!!We should find the start part, but we just default
     ;;;!!!to the first part.
-    (gnus-mime-display-part (cadr handle)))
-   ;; Other multiparts are handled like multipart/mixed.
+    ;;(gnus-mime-display-part (cadr handle))
+    ;;;!!! Most multipart/related is an HTML message plus images.
+    ;;;!!! Unfortunately we are unable to let W3 display those 
+    ;;;!!! included images, so we just display it as a mixed multipart.
+    (gnus-mime-display-mixed (cdr handle)))
    ((equal (car handle) "multipart/signed")
     (or (memq 'signed gnus-article-wash-types)
        (push 'signed gnus-article-wash-types))
@@ -3867,6 +3950,7 @@ In no internal viewer is available, use an external viewer."
        (push 'encrypted gnus-article-wash-types))
     (gnus-insert-mime-security-button handle)
     (gnus-mime-display-mixed (cdr handle)))
+   ;; Other multiparts are handled like multipart/mixed.
    (t
     (gnus-mime-display-mixed (cdr handle)))))
 
@@ -3978,6 +4062,7 @@ In no internal viewer is available, use an external viewer."
        (unless (setq not-pref (cadr (member preferred ihandles)))
          (setq not-pref (car ihandles)))
        (when (or ibegend
+                 (not preferred)
                  (not (gnus-unbuttonized-mime-type-p
                        "multipart/alternative")))
          (gnus-add-text-properties
index a2dbe97..925acb3 100644 (file)
@@ -26,6 +26,7 @@
 (require 'gnus)
 (require 'gnus-art)
 (require 'gnus-range)
+(require 'message)     ; for message-cite-prefix-regexp
 
 (eval-when-compile (require 'static))
 
@@ -76,19 +77,13 @@ Set it to nil to parse all articles."
   :type '(choice (const :tag "all" nil)
                 integer))
 
-(defcustom gnus-cite-prefix-regexp
-  "^[]>»|:}+ ]*[]>»|:}+]\\(.*>»\\)?\\|^.*>"
-  "*Regexp matching the longest possible citation prefix on a line."
-  :group 'gnus-cite
-  :type 'regexp)
-
 (defcustom gnus-cite-max-prefix 20
   "Maximum possible length for a citation prefix."
   :group 'gnus-cite
   :type 'integer)
 
 (defcustom gnus-supercite-regexp
-  (concat "^\\(" gnus-cite-prefix-regexp "\\)? *"
+  (concat "^\\(" message-cite-prefix-regexp "\\)? *"
          ">>>>> +\"\\([^\"\n]+\\)\" +==")
   "*Regexp matching normal Supercite attribution lines.
 The first grouping must match prefixes added by other packages."
@@ -308,7 +303,7 @@ Attribution lines are highlighted with the same face as the
 corresponding citation merged with `gnus-cite-attribution-face'.
 
 Text is considered cited if at least `gnus-cite-minimum-match-count'
-lines matches `gnus-cite-prefix-regexp' with the same prefix.
+lines matches `message-cite-prefix-regexp' with the same prefix.
 
 Lines matching `gnus-cite-attribution-suffix' and perhaps
 `gnus-cite-attribution-prefix' are considered attribution lines."
@@ -681,7 +676,7 @@ See also the documentation for `gnus-article-highlight-citation'."
       ;; Ignore very long prefixes.
       (when (> end (+ (point) gnus-cite-max-prefix))
        (setq end (+ (point) gnus-cite-max-prefix)))
-      (while (re-search-forward gnus-cite-prefix-regexp (1- end) t)
+      (while (re-search-forward message-cite-prefix-regexp (1- end) t)
        ;; Each prefix.
        (setq end (match-end 0)
              prefix (buffer-substring begin end))
index 0f4b95f..7ab899a 100644 (file)
@@ -106,6 +106,9 @@ the second with the current group name.")
 (defvar gnus-posting-styles nil
   "*Alist of styles to use when posting.")
 
+(defvar gnus-inews-mark-gcc-as-read nil
+  "If non-nil, automatically mark Gcc articles as read.")
+
 (defcustom gnus-group-posting-charset-alist
   '(("^\\(no\\|fr\\|dk\\)\\.[^,]*\\(,[ \t\n]*\\(no\\|fr\\|dk\\)\\.[^,]*\\)*$" iso-8859-1 (iso-8859-1))
     ("^\\(fido7\\|relcom\\)\\.[^,]*\\(,[ \t\n]*\\(fido7\\|relcom\\)\\.[^,]*\\)*$" koi8-r (koi8-r))
@@ -1158,7 +1161,7 @@ this is a reply."
        (let ((gcc (or gcc (mail-fetch-field "gcc" nil t)))
              (coding-system-for-write 'raw-text)
              (output-coding-system 'raw-text)
-             groups group method)
+             groups group method group-art)
          (when gcc
            (message-remove-header "gcc")
            (widen)
@@ -1179,10 +1182,19 @@ this is a reply."
                       (concat "^" (regexp-quote mail-header-separator) "$")
                       nil t)
                  (replace-match "" t t ))
-               (unless (gnus-request-accept-article group method t t)
+               (unless (setq group-art 
+                             (gnus-request-accept-article group method t t))
                  (gnus-message 1 "Couldn't store article in group %s: %s"
                                group (gnus-status-message method))
                  (sit-for 2))
+               (when (and group-art gnus-inews-mark-gcc-as-read)
+                 (let ((active (gnus-active group)))
+                   (when active
+                     (if (< (cdr active) (cdr group-art))
+                         (gnus-set-active group (cons (car active) 
+                                                      (cdr group-art))))
+                     (gnus-group-make-articles-read group 
+                                                    (list (cdr group-art))))))
                (kill-buffer (current-buffer))))))))))
 
 (defun gnus-inews-insert-gcc ()
index 7d0f16a..7e36abb 100644 (file)
@@ -1590,6 +1590,7 @@ increase the score of each group you read."
     "v" gnus-summary-verbose-headers
     "m" gnus-summary-toggle-mime
     "H" gnus-article-strip-headers-in-body
+    "p" gnus-article-verify-x-pgp-sig
     "d" gnus-article-treat-dumbquotes
     "s" gnus-smiley-display)
 
@@ -1760,6 +1761,7 @@ increase the score of each group you read."
               ["Verbose header" gnus-summary-verbose-headers t]
               ["Toggle header" gnus-summary-toggle-header t]
              ["Toggle smileys" gnus-smiley-display t]
+             ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t])
              ("Output"
               ["Save in default format" gnus-summary-save-article t]
@@ -4197,7 +4199,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
        (progn                          ; Or we bug out.
          (when (equal major-mode 'gnus-summary-mode)
            (kill-buffer (current-buffer)))
-         (error "Couldn't request group %s: %s"
+         (error "Couldn't activate group %s: %s"
                 group (gnus-status-message group))))
 
     (unless (gnus-request-group group t)
@@ -9986,17 +9988,17 @@ treated as multipart/mixed."
   (interactive (list (gnus-summary-article-number)))
   (gnus-with-article article
     (message-narrow-to-head)
+    (message-remove-header "Mime-Version")
     (goto-char (point-max))
+    (insert "Mime-Version: 1.0\n")
     (widen)
     (when (search-forward "\n--" nil t)
       (let ((separator (buffer-substring (point) (gnus-point-at-eol))))
        (message-narrow-to-head)
-       (message-remove-header "Mime-Version")
        (message-remove-header "Content-Type")
        (goto-char (point-max))
        (insert (format "Content-Type: multipart/mixed; boundary=\"%s\"\n"
                        separator))
-       (insert "Mime-Version: 1.0\n")
        (widen))))
   (let (gnus-mark-article-hook)
     (gnus-summary-select-article t t nil article)))
index 2669b15..842f32c 100644 (file)
@@ -436,6 +436,12 @@ The provided functions are:
   :group 'message-insertion
   :type 'regexp)
 
+(defcustom message-cite-prefix-regexp
+  "^[]>»|:}+ ]*[]>»|:}+]\\(\\w*>»\\)?\\|^\\w*>"
+  "*Regexp matching the longest possible citation prefix on a line."
+  :group 'message-insertion
+  :type 'regexp)
+
 (defcustom message-cancel-message "I am canceling my own article.\n"
   "Message to be inserted in the cancel message."
   :group 'message-interface
@@ -2120,21 +2126,18 @@ With the prefix argument FORCE, insert the header anyway."
 (defun message-newline-and-reformat ()
   "Insert four newlines, and then reformat if inside quoted text."
   (interactive)
-  (let ((prefix "[]>»|:}+ \t]*")
-       (supercite-thing "[-._a-zA-Z0-9]*[>]+[ \t]*")
-       quoted point)
+  (let (quoted point)
     (unless (bolp)
       (save-excursion
        (beginning-of-line)
-       (when (looking-at (concat prefix "\\|"
-                                 supercite-thing))
+       (when (looking-at message-cite-prefix-regexp)
          (setq quoted (match-string 0))))
       (insert "\n"))
     (setq point (point))
     (insert "\n\n\n")
     (delete-region (point) (re-search-forward "[ \t]*"))
     (when quoted
-      (insert quoted))
+      (insert quoted " "))
     (fill-paragraph nil)
     (goto-char point)
     (forward-line 1)))
index d2f9257..4020aa9 100644 (file)
@@ -239,13 +239,16 @@ to:
 (autoload 'mml2015-verify "mml2015")
 (autoload 'mml2015-verify-test "mml2015")
 (autoload 'mml-smime-verify "mml-smime")
+(autoload 'mml-smime-verify-test "mml-smime")
 
 (defvar mm-verify-function-alist
   '(("application/pgp-signature" mml2015-verify "PGP" mml2015-verify-test)
-    ("application/pkcs7-signature" mml-smime-verify "S/MIME" nil)
-    ("application/x-pkcs7-signature" mml-smime-verify "S/MIME" nil)))
+    ("application/pkcs7-signature" mml-smime-verify "S/MIME" 
+     mml-smime-verify-test)
+    ("application/x-pkcs7-signature" mml-smime-verify "S/MIME" 
+     mml-smime-verify-test)))
 
-(defcustom mm-verify-option 'known
+(defcustom mm-verify-option nil
   "Option of verifying signed parts.
 `never', not verify; `always', always verify; 
 `known', only verify known protocols. Otherwise, ask user."
@@ -261,7 +264,7 @@ to:
 (defvar mm-decrypt-function-alist
   '(("application/pgp-encrypted" mml2015-decrypt "PGP" mml2015-decrypt-test)))
 
-(defcustom mm-decrypt-option 'known
+(defcustom mm-decrypt-option nil
   "Option of decrypting signed parts.
 `never', not decrypt; `always', always decrypt; 
 `known', only decrypt known protocols. Otherwise, ask user."
index f2b20f9..e9c07fb 100644 (file)
@@ -116,7 +116,10 @@ the entire message.
 If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing."
   (let* ((access-type (cdr (assq 'access-type 
                                 (cdr (mm-handle-type handle)))))
-        (func (cdr (assq (intern (downcase access-type))
+        (func (cdr (assq (intern 
+                          (downcase 
+                           (or access-type
+                               (error "Couldn't find access type."))))
                          mm-extern-function-alist)))
         gnus-displaying-mime buf
         handles)
index 9e9c37f..b1b6102 100644 (file)
@@ -85,7 +85,7 @@ This can be either \"inline\" or \"attachment\".")
      mm-uu-binhex-filename)
     (shar 
      "^#! */bin/sh"
-     "^exit 0\\|^$"
+     "^exit 0$"
      mm-uu-shar-extract)
     (forward 
 ;;; Thanks to Edward J. Sabol <sabol@alderaan.gsfc.nasa.gov> and 
@@ -262,11 +262,16 @@ To disable dissecting shar codes, for instance, add
     (mm-set-handle-multipart-parameter 
      mm-security-handle 'protocol "application/pgp-signature")
     (with-current-buffer buf
-      (when (mm-uu-pgp-signed-test)
-       (mml2015-clean-buffer)
-       (let ((coding-system-for-write (or gnus-newsgroup-charset
-                                          'iso-8859-1)))
-         (funcall (mml2015-clear-verify-function))))
+      (if (mm-uu-pgp-signed-test)
+         (progn
+           (mml2015-clean-buffer)
+           (let ((coding-system-for-write (or gnus-newsgroup-charset
+                                              'iso-8859-1)))
+             (funcall (mml2015-clear-verify-function))))
+       (when (and mml2015-use (null (mml2015-clear-verify-function)))
+         (mm-set-handle-multipart-parameter
+          mm-security-handle 'gnus-details 
+          (format "Clear verification not supported by `%s'.\n" mml2015-use))))
       (goto-char (point-min))
       (if (search-forward "\n\n" nil t)
          (delete-region (point-min) (point)))
index 427c538..62e27d6 100644 (file)
@@ -28,6 +28,7 @@
 ;;; Code:
 
 (require 'smime)
+(require 'mm-decode)
 
 (defun mml-smime-verify (handle ctl)
   (with-current-buffer (mm-handle-multipart-original-buffer ctl)
                    (mm-handle-multipart-ctl-parameter ctl 'micalg)))
     (insert (format "boundary=\"%s\"\n\n"
                    (mm-handle-multipart-ctl-parameter ctl 'boundary)))
-    (smime-verify-buffer)
+    (when (get-buffer smime-details-buffer)
+      (kill-buffer smime-details-buffer))
+    (if (smime-verify-buffer)
+       (progn
+         (mm-set-handle-multipart-parameter 
+          mm-security-handle 'gnus-info "OK")
+         (kill-buffer smime-details-buffer))
+      (mm-set-handle-multipart-parameter 
+       mm-security-handle 'gnus-info "Failed")
+      (mm-set-handle-multipart-parameter
+       mm-security-handle 'gnus-details (with-current-buffer smime-details-buffer 
+                                         (buffer-string))))
     handle))
 
+(defun mml-smime-verify-test (handle ctl)
+  smime-openssl-program)
+
 (provide 'mml-smime)
 
 ;;; mml-smime.el ends here
index a571748..154677f 100644 (file)
                (error 
                 (mm-set-handle-multipart-parameter 
                  mm-security-handle 'gnus-details (cadr err)) 
+                nil)
+               (quit
+                (mm-set-handle-multipart-parameter 
+                 mm-security-handle 'gnus-details "Quit.") 
                 nil)))
        (unless (car result)
          (mm-set-handle-multipart-parameter 
            (error 
             (mm-set-handle-multipart-parameter 
              mm-security-handle 'gnus-details (cadr err)) 
+            nil)
+           (quit
+            (mm-set-handle-multipart-parameter 
+             mm-security-handle 'gnus-details "Quit.") 
             nil)))
     (if (car result)
        (mm-set-handle-multipart-parameter 
                        (or (mml2015-fix-micalg
                             (mail-content-type-get ctl 'micalg))
                            "SHA1")))
-       (insert part "\n")
-       (goto-char (point-max))
+       (save-restriction
+         (narrow-to-region (point) (point))
+         (insert part "\n")
+         (goto-char (point-min))
+         (while (not (eobp))
+           (if (looking-at "^-")
+               (insert "- "))
+           (forward-line)))
        (unless (setq part (mm-find-part-by-type 
                            (cdr handle) "application/pgp-signature" nil t))
          (mm-set-handle-multipart-parameter 
           mm-security-handle 'gnus-info "Corrupted")
          (throw 'error handle))
-       (mm-insert-part part)
+       (save-restriction
+         (narrow-to-region (point) (point))
+         (mm-insert-part part)
+         (goto-char (point-min))
+         (if (re-search-forward "^-----\\([^-]+\\)-----$" nil t)
+             (replace-match "BEGIN PGP SIGNATURE" t t nil 1))
+         (if (re-search-forward "^-----\\([^-]+\\)-----$" nil t)
+             (replace-match "END PGP SIGNATURE" t t nil 1)))
        (unless (condition-case err
                    (funcall mml2015-verify-function)
                  (error 
                   (mm-set-handle-multipart-parameter 
                    mm-security-handle 'gnus-details (cadr err)) 
+                  nil)
+                 (quit
+                  (mm-set-handle-multipart-parameter 
+                   mm-security-handle 'gnus-details "Quit.") 
                   nil))
          (mm-set-handle-multipart-parameter 
           mm-security-handle 'gnus-info "Failed")
        (error 
         (mm-set-handle-multipart-parameter 
          mm-security-handle 'gnus-details (cadr err)) 
+        nil)
+       (quit
+        (mm-set-handle-multipart-parameter 
+         mm-security-handle 'gnus-details "Quit.") 
         nil))
       (mm-set-handle-multipart-parameter 
        mm-security-handle 'gnus-info "OK")
                   nil nil nil nil)
   (let ((boundary 
         (funcall mml-boundary-function (incf mml-multipart-number)))
-       (scheme-alist (funcall (or mc-default-scheme 
-                                  (cdr (car mc-schemes)))))
        hash)
     (goto-char (point-min))
-    (unless (re-search-forward (cdr (assq 'signed-begin-line scheme-alist)))
+    (unless (re-search-forward "^-----BEGIN PGP SIGNED MESSAGE-----\r?$" nil t)
       (error "Cannot find signed begin line." ))
     (goto-char (match-beginning 0))
     (forward-line 1)
                    (downcase hash)))
     (insert (format "\n--%s\n" boundary))
     (goto-char (point-max))
-    (unless (re-search-backward (cdr (assq 'signed-end-line scheme-alist)))
+    (unless (re-search-backward "^-----END PGP \\(SIGNATURE\\)-----\r?$" nil t)
       (error "Cannot find signature part." ))
+    (replace-match "MESSAGE" t t nil 1)
     (goto-char (match-beginning 0))
-    (unless (re-search-backward "^-+BEGIN" nil t)
+    (unless (re-search-backward "^-----BEGIN PGP \\(SIGNATURE\\)-----\r?$" 
+                               nil t)
       (error "Cannot find signature part." ))
+    (replace-match "MESSAGE" t t nil 1)
     (goto-char (match-beginning 0))
     (insert (format "--%s\n" boundary))
     (insert "Content-Type: application/pgp-signature\n\n")
             mm-security-handle 'gnus-info "Corrupted")
            (throw 'error handle))
          (mm-insert-part part)
-         (unless (gpg-verify message signature mml2015-result-buffer)
+         (unless (condition-case err
+                     (gpg-verify message signature mml2015-result-buffer)
+                   (error 
+                    (mm-set-handle-multipart-parameter 
+                     mm-security-handle 'gnus-details (cadr err)) 
+                    nil)
+                   (quit
+                    (mm-set-handle-multipart-parameter 
+                     mm-security-handle 'gnus-details "Quit.") 
+                    nil))
            (mm-set-handle-multipart-parameter 
             mm-security-handle 'gnus-details 
             (with-current-buffer mml2015-result-buffer
               (buffer-string)))
            (mm-set-handle-multipart-parameter 
             mm-security-handle 'gnus-info "Failed")
-           (throw 'error handle))))
+           (throw 'error handle)))
+       (mm-set-handle-multipart-parameter 
+        mm-security-handle 'gnus-info "OK"))
       handle)))
 
 (defun mml2015-gpg-sign (cont)
index 65367eb..d8d381b 100644 (file)
@@ -186,7 +186,7 @@ These look like \"us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A\"."
        (goto-char (point-min))
        (while (not (eobp))
          (when (> (current-column) 60)
-           (insert "\n")
+           (insert ";\n")
            (setq broken t))
          (if (or (not (memq (following-char) ascii))
                  (memq (following-char) control)
@@ -203,7 +203,8 @@ These look like \"us-ascii'en-us'This%20is%20%2A%2A%2Afun%2A%2A%2A\"."
        (if (not broken)
            (insert param "*=")
          (while (not (eobp))
-           (insert param "*" (format "%d" (incf num)) "*=")
+           (insert (if (>= num 0) " " "\n ")
+                   param "*" (format "%d" (incf num)) "*=")
            (forward-line 1))))
        (spacep
        (goto-char (point-min))
index 0d3bbe9..530ed8d 100644 (file)
@@ -26,9 +26,9 @@
 ;; This library perform S/MIME operations from within Emacs.
 ;;
 ;; Functions for fetching certificates from public repositories are
-;; NOT provided (yet).
+;; provided, currently only from DNS.  LDAP support (via EUDC) is planned.
 ;;
-;; It uses OpenSSL (tested with version 0.9.5a) for signing,
+;; It uses OpenSSL (tested with version 0.9.5a and 0.9.6) for signing,
 ;; encryption and decryption.
 ;;
 ;; Some general knowledge of S/MIME, X.509, PKCS#12, PEM etc is
@@ -140,7 +140,11 @@ manually."
   :type 'directory
   :group 'smime)
 
-(defcustom smime-openssl-program "openssl"
+(defcustom smime-openssl-program 
+  (and (condition-case () 
+          (eq 0 (call-process "openssl" nil nil nil "version"))
+        (error nil))
+       "openssl")
   "Name of OpenSSL binary."
   :type 'string
   :group 'smime)
@@ -152,6 +156,8 @@ If nil, use system defaults."
                 string)
   :group 'dig)
 
+(defvar smime-details-buffer "*S/MIME OpenSSL output*")
+
 ;; OpenSSL wrappers.
 
 (defun smime-call-openssl-region (b e buf &rest args)
@@ -179,6 +185,9 @@ private key and certificate."
          (when (looking-at "^MIME-Version: 1.0$")
            (delete-region (point) (progn (forward-line 1) (point))))
          t)
+      (with-current-buffer (get-buffer-create smime-details-buffer)
+       (goto-char (point-max))
+       (insert-buffer buffer))
       (kill-buffer buffer))))
 
 (defun smime-encrypt-region (b e certfiles)
@@ -195,6 +204,9 @@ is expected to contain of a PEM encoded certificate."
          (when (looking-at "^MIME-Version: 1.0$")
            (delete-region (point) (progn (forward-line 1) (point))))
          t)
+      (with-current-buffer (get-buffer-create smime-details-buffer)
+       (goto-char (point-max))
+       (insert-buffer buffer))
       (kill-buffer buffer))))
 
 ;; Sign+encrypt buffer
@@ -240,6 +252,9 @@ nil."
            (message "S/MIME message verified succesfully.")
          (message "S/MIME message NOT verified successfully.")
          nil)
+      (with-current-buffer (get-buffer-create smime-details-buffer)
+       (goto-char (point-max))
+       (insert-buffer buffer))
       (kill-buffer buffer))))
   
 (defun smime-decrypt-region (b e keyfile)
@@ -249,6 +264,9 @@ nil."
                 "-recip" keyfile)
       
       )
+    (with-current-buffer (get-buffer-create smime-details-buffer)
+      (goto-char (point-max))
+      (insert-buffer buffer))
     (kill-buffer buffer)))
   
 ;; Verify+Decrypt buffer
index 95727db..f94f32a 100644 (file)
@@ -1,3 +1,21 @@
+2000-11-12  Florian Weimer  <fw@deneb.enyo.de>
+
+       * message.texi (Security): Fixed typo, change "PGP" to "OpenPGP".
+
+2000-11-12  David Edmondson  <dme@dme.org>
+
+       * gnus.texi: remove `gnus-cite-prefix-regexp'.
+
+       * message.texi (Insertion): move `gnus-cite-prefix-regexp' from
+       gnus.texi to here and rename to `message-cite-prefix-regexp'.
+
+2000-11-11  Simon Josefsson  <sj@extundo.com>
+
+       * message.texi (Security): Add.
+
+       * emacs-mime.texi (MML Definition): Add sign, encrypt, keyfile and
+       certfile.
+
 2000-11-07  Kai Gro\e,A_\e(Bjohann  <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
        * gnus.texi (Mail Group Commands): `gnus-move-split-methods' uses
index c8a2f46..a0c96b4 100644 (file)
@@ -1067,6 +1067,14 @@ RFC822 date when the part was read (@code{Content-Disposition}).
 @item size
 The size (in octets) of the part (@code{Content-Disposition}).
 
+@item sign
+What technology to sign this MML part with (@code{smime} or
+@code{pgpmime})
+
+@item encrypt
+What technology to encrypt this MML part with (@code{smime} or
+@code{pgpmime})
+
 @end table
 
 Parameters for @samp{application/octet-stream}:
@@ -1098,6 +1106,24 @@ Valid values are @samp{read} and @samp{read-write}
 
 @end table
 
+Parameters for @samp{sign=smime}:
+
+@table @samp
+
+@item keyfile
+File containing key and certificate for signer.
+
+@end table
+
+Parameters for @samp{encrypt=smime}:
+
+@table @samp
+
+@item certfile
+File containing certificate for recipient.
+
+@end table
+
 
 @node Advanced MML Example
 @section Advanced MML Example
index 505ad94..1d91685 100644 (file)
@@ -6870,10 +6870,6 @@ Gnus \e$B$O%U%!%$%k$r1\Mw$9$k$N$r7hDj$9$k$N$K\e(B@dfn{\e$B5,B'JQ?t\e(B}\e$B$rMQ$$$^$9
 \e$B5-;v$NBg$-$5$,$3$NJQ?t\e(B (\e$B%G%#%U%)%k%H$G$O\e(B 25000) \e$B$h$jBg$-$$5-;v$O!"0zMQ%O\e(B
 \e$B%$%i%$%H$O9T$o$l$^$;$s!#\e(B
 
-@item gnus-cite-prefix-regexp
-@vindex gnus-cite-prefix-regexp
-\e$B$"$k9T$,<h$jF@$k:GBg$N0zMQ@\F,8l$K9gCW$9$k@55,I=8=$G$9!#\e(B
-
 @item gnus-cite-max-prefix
 @vindex gnus-cite-max-prefix
 \e$B0zMQ@\F,8l$N:GBg$ND9$5$G$9\e(B (\e$B%G%#%U%)%k%H$G$O\e(B 20 \e$B$G$9\e(B)\e$B!#\e(B
index 41c3d6c..c53aff6 100644 (file)
@@ -6992,10 +6992,6 @@ Some variables to customize the citation highlights:
 If the article size if bigger than this variable (which is 25000 by
 default), no citation highlighting will be performed.
 
-@item gnus-cite-prefix-regexp
-@vindex gnus-cite-prefix-regexp
-Regexp matching the longest possible citation prefix on a line.
-
 @item gnus-cite-max-prefix
 @vindex gnus-cite-max-prefix
 Maximum possible length for a citation prefix (default 20).
index 57a717e..5d078a8 100644 (file)
@@ -326,6 +326,7 @@ Message \e$B$O%U%)%m!<%"%C%W$,$I$3$K9T$/$+$rIaDL$NJ}K!$r;H$C$F7hDj$7$^$9$,!"\e(B
 * Movement::            \e$B%a%C%;!<%8%P%C%U%!$rF0$-2s$k!#\e(B
 * Insertion::           \e$B%a%C%;!<%8%P%C%U%!$KJ*;v$rA^F~$9$k!#\e(B
 @c * MIME::                @sc{mime} considerations.
+@c * Security::            Signing and encrypting messages.
 * Various Commands::    \e$B$$$m$$$m$J;v!#\e(B
 * Sending::             \e$B<B:]$K%a%C%;!<%8$rAw$k!#\e(B
 * Mail Aliases::        \e$B$I$N$h$&$K$7$F%a!<%k$NJLL>$r;H$&$+!#\e(B
@@ -466,6 +467,10 @@ u} (@code{undo}) \e$B$,;HMQ2DG=$G!"Bg>fIW$G$"$k$H8@$&;v$r3P$($F$*$$$F2<$5$$!#\e(B
 \e$B$+$l$^$9!#=i4|CM$O\e(B @samp{.} \e$B$G!"$3$l$OA4$F$N%X%C%@!<$,<h$j=|$+$l$k$H8@$&\e(B
 \e$B;v$G$9!#\e(B
 
+@item message-cite-prefix-regexp
+@vindex message-cite-prefix-regexp
+\e$B$"$k9T$,<h$jF@$k:GBg$N0zMQ@\F,8l$K9gCW$9$k@55,I=8=$G$9!#\e(B
+
 @item message-citation-line-function
 @vindex message-citation-line-function
 \e$B0zMQ9T$rA^F~$9$k$?$a$K8F$P$l$k4X?t$G$9!#=i4|CM$O\e(B 
@@ -573,6 +578,135 @@ RFC1036bis \e$B$O!"=pL>$O$=$NA0$K\e(B @samp{-- } \e$B$N\e(B3\e$BJ8;z$@$1$N9T$,$"$k$Y$
 @c language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME
 @c Manual}).
 
+@c @node Security
+@c @section Security
+@c @cindex Security
+@c @cindex S/MIME
+@c @cindex PGP/MIME
+@c @cindex sign
+@c @cindex encrypt
+
+@c Using the MML language, Message is able to create digitally signed and
+@c digitally encrypted messages.  Message (or rather MML) currently support
+@c PGP/MIME and S/MIME.  Instructing MML to perform security operations on
+@c a MIME part is done using the @code{M-m s} key map for signing and the
+@c @code{M-m c} key map for encryption, as follows.
+
+@c @table @kbd
+
+@c @item M-m s s
+@c @kindex M-m s s
+@c @findex mml-secure-sign-smime
+
+@c Digitally sign current MIME part using S/MIME.
+
+@c @item M-m s p
+@c @kindex M-m s p
+@c @findex mml-secure-sign-pgp
+
+@c Digitally sign current MIME part using PGP/MIME.
+
+@c @item M-m c s
+@c @kindex M-m c s
+@c @findex mml-secure-encrypt-smime
+
+@c Digitally encrypt current MIME part using S/MIME.
+
+@c @item M-m c p
+@c @kindex M-m c p
+@c @findex mml-secure-encrypt-pgpmime
+
+@c Digitally encrypt current MIME part using PGP/MIME.
+
+@c @end table
+
+@c These commands do not immediately sign or encrypt the message, they
+@c merely insert proper MML tags to instruct the MML engine to perform that
+@c operation when the message is actually sent.  They may perform other
+@c operations too, such as locating and retrieving a S/MIME certificate of
+@c the person you wish to send encrypted mail to.
+
+@c Since signing and especially encryption often is used when sensitive
+@c information is sent, you may want to have some way to ensure that your
+@c mail is actually signed or encrypted.  After invoking the above
+@c sign/encrypt commands, it is possible to preview the raw article by
+@c using @code{C-u M-m P} (@code{mml-preview}).  Then you can verify that
+@c your long rant about what your ex-significant other or whomever actually
+@c did with that funny looking person at that strange party the other
+@c night, actually will be sent encrypted.
+
+@c @emph{Note!}  Neither PGP/MIME nor S/MIME encrypt/signs RFC822 headers.
+@c They only operate on the MIME object.  Keep this in mind before sending
+@c mail with a sensitive Subject line.
+
+@c Actually using the security commands above is not very difficult.  At
+@c least not compared with making sure all involved programs talk with each
+@c other properly.  Thus, we now describe what external libraries or
+@c programs are required to make things work, and some small general hints.
+
+@c @subsection Using S/MIME
+
+@c @emph{Note!}  This section assume you have a basic familiarity with
+@c modern cryptography, S/MIME, various PKCS standards, OpenSSL and so on.
+
+@c The S/MIME support in Message (and MML) require OpenSSL.  OpenSSL
+@c perform the actual S/MIME sign/encrypt operations.  OpenSSL can be found
+@c at @code{http://www.openssl.org/}.  OpenSSL 0.9.5a and later should
+@c work.  However, version 0.9.5a insert a spurious CR character into MIME
+@c separators so you may wish to avoid it if you would like to avoid being
+@c regarded as someone who send strange mail. (Although by sending S/MIME
+@c messages you've probably already lost that contest.)
+
+@c To be able to send encrypted mail, a personal certificate is not
+@c required.  Message (MML) need a certificate for the person to whom you
+@c wish to communicate with though.  You're asked for this when you type
+@c @code{M-m c s}.  Currently there are two ways to retrieve this
+@c certificate, from a local file or from DNS.  If you chose a local file,
+@c it need to contain a X.509 certificate in PEM format.  If you chose DNS,
+@c you're asked for the domain name where the certificate is stored, the
+@c default is a good guess.  To my belief, Message (MML) is the first mail
+@c agent in the world to support retrieving S/MIME certificates from DNS,
+@c so you're not likely to find very many certificates out there.  At least
+@c there should be one, stored at the domain @code{simon.josefsson.org}.
+@c LDAP is a more popular method of distributing certificates, support for
+@c it is planned.  (Meanwhile, you can use @code{ldapsearch} from the
+@c command line to retrieve a certificate into a file and use it.)
+
+@c As for signing messages, OpenSSL can't perform signing operations
+@c without some kind of configuration.  Especially, you need to tell it
+@c where your private key and your certificate is stored.  MML uses an
+@c Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain
+@c a @code{custom} group used for this configuration.  So, try @code{M-x
+@c customize-group RET smime RET} and look around.
+
+@c Currently there is no support for talking to a CA (or RA) to create your
+@c own certificate.  None is planned either.  You need to do this manually
+@c with OpenSSL or using some other program.  I used Netscape and got a
+@c free S/MIME certificate from one of the big CA's on the net.  Netscape
+@c is able to export your private key and certificate in PKCS #12 format.
+@c Use OpenSSL to convert this into a plain X.509 certificate in PEM format
+@c as follows.
+
+@c @example
+@c $ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem
+@c @end example
+
+@c The @code{key+cert.pem} file should be pointed to from the
+@c @code{smime-keys} variable.  You should now be able to send signed mail.
+
+@c @emph{Note!}  Your private key is store unencrypted in the file, so take
+@c care in handling it.
+
+@c @subsection Using PGP/MIME
+
+@c PGP/MIME require an external OpenPGP implementation, such as GNU Privacy
+@c Guard (@code{http://www.gnupg.org/}.  It also require a Emacs interface
+@c to it, such as Mailcrypt (available from
+@c @code{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or
+@c Florian Weimer's @code{gpg.el}.
+
+@c Creating your own OpenPGP key is described in detail in the
+@c documentation of your OpenPGP implementation, so we refer to it.
 
 @node Various Commands
 @section \e$B$$$m$$$m$JL?Na\e(B
index fb42b8b..178b867 100644 (file)
@@ -324,6 +324,7 @@ will be removed before popping up the buffer.  The default is
 * Movement::            Moving around in message buffers.
 * Insertion::           Inserting things into message buffers.
 * MIME::                @sc{mime} considerations.
+* Security::            Signing and encrypting messages.
 * Various Commands::    Various things.
 * Sending::             Actually sending the message.
 * Mail Aliases::        How to use mail aliases.
@@ -466,6 +467,10 @@ All headers that match this regexp will be removed from yanked
 messages.  The default is @samp{.}, which means that all headers will be
 removed.
 
+@item message-cite-prefix-regexp
+@vindex message-cite-prefix-regexp
+Regexp matching the longest possible citation prefix on a line.
+
 @item message-citation-line-function
 @vindex message-citation-line-function
 Function called to insert the citation line.  The default is
@@ -575,6 +580,135 @@ You can also create arbitrarily complex multiparts using the MML
 language (@pxref{Composing, , Composing, emacs-mime, The Emacs MIME
 Manual}).
 
+@node Security
+@section Security
+@cindex Security
+@cindex S/MIME
+@cindex PGP/MIME
+@cindex sign
+@cindex encrypt
+
+Using the MML language, Message is able to create digitally signed and
+digitally encrypted messages.  Message (or rather MML) currently support
+PGP/MIME and S/MIME.  Instructing MML to perform security operations on
+a MIME part is done using the @code{M-m s} key map for signing and the
+@code{M-m c} key map for encryption, as follows.
+
+@table @kbd
+
+@item M-m s s
+@kindex M-m s s
+@findex mml-secure-sign-smime
+
+Digitally sign current MIME part using S/MIME.
+
+@item M-m s p
+@kindex M-m s p
+@findex mml-secure-sign-pgp
+
+Digitally sign current MIME part using PGP/MIME.
+
+@item M-m c s
+@kindex M-m c s
+@findex mml-secure-encrypt-smime
+
+Digitally encrypt current MIME part using S/MIME.
+
+@item M-m c p
+@kindex M-m c p
+@findex mml-secure-encrypt-pgpmime
+
+Digitally encrypt current MIME part using PGP/MIME.
+
+@end table
+
+These commands do not immediately sign or encrypt the message, they
+merely insert proper MML tags to instruct the MML engine to perform that
+operation when the message is actually sent.  They may perform other
+operations too, such as locating and retrieving a S/MIME certificate of
+the person you wish to send encrypted mail to.
+
+Since signing and especially encryption often is used when sensitive
+information is sent, you may want to have some way to ensure that your
+mail is actually signed or encrypted.  After invoking the above
+sign/encrypt commands, it is possible to preview the raw article by
+using @code{C-u M-m P} (@code{mml-preview}).  Then you can verify that
+your long rant about what your ex-significant other or whomever actually
+did with that funny looking person at that strange party the other
+night, actually will be sent encrypted.
+
+@emph{Note!}  Neither PGP/MIME nor S/MIME encrypt/signs RFC822 headers.
+They only operate on the MIME object.  Keep this in mind before sending
+mail with a sensitive Subject line.
+
+Actually using the security commands above is not very difficult.  At
+least not compared with making sure all involved programs talk with each
+other properly.  Thus, we now describe what external libraries or
+programs are required to make things work, and some small general hints.
+
+@subsection Using S/MIME
+
+@emph{Note!}  This section assume you have a basic familiarity with
+modern cryptography, S/MIME, various PKCS standards, OpenSSL and so on.
+
+The S/MIME support in Message (and MML) require OpenSSL.  OpenSSL
+perform the actual S/MIME sign/encrypt operations.  OpenSSL can be found
+at @code{http://www.openssl.org/}.  OpenSSL 0.9.5a and later should
+work.  However, version 0.9.5a insert a spurious CR character into MIME
+separators so you may wish to avoid it if you would like to avoid being
+regarded as someone who send strange mail. (Although by sending S/MIME
+messages you've probably already lost that contest.)
+
+To be able to send encrypted mail, a personal certificate is not
+required.  Message (MML) need a certificate for the person to whom you
+wish to communicate with though.  You're asked for this when you type
+@code{M-m c s}.  Currently there are two ways to retrieve this
+certificate, from a local file or from DNS.  If you chose a local file,
+it need to contain a X.509 certificate in PEM format.  If you chose DNS,
+you're asked for the domain name where the certificate is stored, the
+default is a good guess.  To my belief, Message (MML) is the first mail
+agent in the world to support retrieving S/MIME certificates from DNS,
+so you're not likely to find very many certificates out there.  At least
+there should be one, stored at the domain @code{simon.josefsson.org}.
+LDAP is a more popular method of distributing certificates, support for
+it is planned.  (Meanwhile, you can use @code{ldapsearch} from the
+command line to retrieve a certificate into a file and use it.)
+
+As for signing messages, OpenSSL can't perform signing operations
+without some kind of configuration.  Especially, you need to tell it
+where your private key and your certificate is stored.  MML uses an
+Emacs interface to OpenSSL, aptly named @code{smime.el}, and it contain
+a @code{custom} group used for this configuration.  So, try @code{M-x
+customize-group RET smime RET} and look around.
+
+Currently there is no support for talking to a CA (or RA) to create your
+own certificate.  None is planned either.  You need to do this manually
+with OpenSSL or using some other program.  I used Netscape and got a
+free S/MIME certificate from one of the big CA's on the net.  Netscape
+is able to export your private key and certificate in PKCS #12 format.
+Use OpenSSL to convert this into a plain X.509 certificate in PEM format
+as follows.
+
+@example
+$ openssl pkcs12 -in ns.p12 -clcerts -nodes > key+cert.pem
+@end example
+
+The @code{key+cert.pem} file should be pointed to from the
+@code{smime-keys} variable.  You should now be able to send signed mail.
+
+@emph{Note!}  Your private key is store unencrypted in the file, so take
+care in handling it.
+
+@subsection Using PGP/MIME
+
+PGP/MIME require an external OpenPGP implementation, such as GNU Privacy
+Guard (@code{http://www.gnupg.org/}.  It also require a Emacs interface
+to it, such as Mailcrypt (available from
+@code{http://www.nb.net/~lbudney/linux/software/mailcrypt.html}) or
+Florian Weimer's @code{gpg.el}.
+
+Creating your own OpenPGP key is described in detail in the
+documentation of your OpenPGP implementation, so we refer to it.
 
 @node Various Commands
 @section Various Commands
diff --git a/todo b/todo
index f3243de..3aded8c 100644 (file)
--- a/todo
+++ b/todo
@@ -1,6 +1,8 @@
 ;; Also know as the "wish list".  Some are done. For the others, no
 ;; promise when to be implemented.
 
+* Emphasis delimiters show when `W W c'.
+
 * Parsing of the common list confirmation requests so that Gnus can
    prepare the response with a single command.  Including LISTSERV
    periodic ping messages and the like.
@@ -679,6 +681,8 @@ exceeding lisp nesting on huge groups.
 
 *  a way to tick/mark as read Gcc'd articles.
 
+   [done, (setq gnus-inews-mark-gcc-as-read t)]
+
 *  a way to say that all groups within a specific topic comes from a
  particular server?  Hm.