+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>
: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)))
(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)
(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)
(call-interactively ',afunc)
(apply ',afunc args))))))))
'(article-hide-headers
+ article-verify-x-pgp-sig
article-hide-boring-headers
article-toggle-headers
article-treat-overstrike
(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
(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))
(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)))))
(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
(require 'gnus)
(require 'gnus-art)
(require 'gnus-range)
+(require 'message) ; for message-cite-prefix-regexp
(eval-when-compile (require 'static))
: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."
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."
;; 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))
(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))
(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)
(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 ()
"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)
["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]
(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)
(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)))
: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
(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)))
(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."
(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."
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)
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
(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)))
;;; 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
(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)
(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)
(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))
;; 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
: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)
string)
:group 'dig)
+(defvar smime-details-buffer "*S/MIME OpenSSL output*")
+
;; OpenSSL wrappers.
(defun smime-call-openssl-region (b e buf &rest args)
(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)
(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
(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)
"-recip" keyfile)
)
+ (with-current-buffer (get-buffer-create smime-details-buffer)
+ (goto-char (point-max))
+ (insert-buffer buffer))
(kill-buffer buffer)))
;; Verify+Decrypt buffer
+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
@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}:
@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
\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
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).
* 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
\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
@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
* 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.
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
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
;; 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.
* 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.