+2006-04-26 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * deuglify.el (gnus-outlook-deuglify-unwrap-min)
+ (gnus-outlook-deuglify-unwrap-max): Remove autoload.
+
+ * mml-sec.el (mml-secure-method): New internal variable.
+ (mml-secure-sign, mml-secure-encrypt, mml-secure-message-sign)
+ (mml-secure-message-sign-encrypt, mml-secure-message-encrypt): New
+ functions using mml-secure-method. Sync from the trunk.
+
+ * mml.el (mml-mode-map): Add key bindings for those functions.
+ (mml-menu): Simplify security menu entries. Suggested by Jesper
+ Harder <harder@myrealbox.com>. Sync from the trunk.
+
+ * message.el (message-valid-fqdn-regexp): Add TLDs .cat, jobs,
+ .mobi and .travel. Remove .nato, .bitnet and .uucp.
+ (message-in-body-p): New function. Sync from the trunk.
+
+ * mml.el (mml-mode, mml-dnd-protocol-alist)
+ (mml-dnd-attach-options, mml-dnd-attach-file)
+ (mml-attach-file, mml-attach-buffer, mml-attach-external): Sync
+ DND support and use of message-in-body-p from the trunk.
+
+2006-04-25 Andreas Seltenreich <uwi7@rz.uni-karlsruhe.de>
+
+ * nnweb.el (nnweb-google-wash-article): Sync up to new Google
+ HTML.
+
+2006-04-25 Katsumi Yamaoka <yamaoka@jpl.org>
+
+ * mm-uu.el (mm-uu-pgp-signed-test): Erase prompt.
+ (mm-uu-pgp-encrypted-test): Ditto.
+ (mm-uu-pgp-encrypted-extract-1): Make sure there's a blank line
+ between header and body; return application/pgp-encrypted handle
+ if decryption failed; decode decrypted body by charset.
+
+ * mm-decode.el (mm-automatic-display): Don't make application/pgp
+ element match to application/pgp-*.
+
2006-04-20 Reiner Steib <Reiner.Steib@gmx.de>
* gnus-util.el (gnus-replace-in-string): Prefer
:version "22.1"
:group 'gnus)
-;;;###autoload
(defcustom gnus-outlook-deuglify-unwrap-min 45
"Minimum length of the cited line above the (possibly) wrapped line."
:version "22.1"
:type 'integer
:group 'gnus-outlook-deuglify)
-;;;###autoload
(defcustom gnus-outlook-deuglify-unwrap-max 95
"Maximum length of the cited line after unwrapping."
:version "22.1"
:type 'string
:group 'gnus-outlook-deuglify)
-;;;###autoload
(defcustom gnus-outlook-display-hook nil
"A hook called after an deuglified article has been prepared.
It is run after `gnus-article-prepare-hook'."
(defcustom message-valid-fqdn-regexp
(concat "[a-z0-9][-.a-z0-9]+\\." ;; [hostname.subdomain.]domain.
;; valid TLDs:
- "\\([a-z][a-z]" ;; two letter country TDLs
- "\\|biz\\|com\\|edu\\|gov\\|int\\|mil\\|net\\|org"
- "\\|aero\\|coop\\|info\\|name\\|museum"
- "\\|arpa\\|pro\\|uucp\\|bitnet\\|bofh" ;; old style?
- "\\)")
+ "\\([a-z][a-z]\\|" ;; two letter country TDLs
+ "aero\\|arpa\\|bitnet\\|biz\\|bofh\\|"
+ "cat\\|com\\|coop\\|edu\\|gov\\|"
+ "info\\|int\\|jobs\\|"
+ "mil\\|mobi\\|museum\\|name\\|net\\|"
+ "org\\|pro\\|travel\\|uucp\\)")
+ ;; http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
+ ;; http://en.wikipedia.org/wiki/GTLD
+ ;; `in the process of being approved': .asia .post .tel .sex
+ ;; "dead" nato bitnet uucp
"Regular expression that matches a valid FQDN."
;; see also: gnus-button-valid-fqdn-regexp
:version "22.1"
(or (search-forward (concat "\n" mail-header-separator "\n") nil t)
(search-forward-regexp "[^:]+:\\([^\n]\\|\n[ \t]\\)+\n\n" nil t)))
+(defun message-in-body-p ()
+ "Return t if point is in the message body."
+ (let ((body (save-excursion (message-goto-body) (point))))
+ (>= (point) body)))
+
(defun message-goto-eoh ()
"Move point to the end of the headers."
(interactive)
"application/pkcs7-signature" "application/x-pkcs7-mime"
"application/pkcs7-mime"
;; Mutt still uses this even though it has already been withdrawn.
- "application/pgp")
+ "application/pgp\\'")
"A list of MIME types to be displayed automatically."
:type '(repeat regexp)
:group 'mime-display)
((eq mm-verify-option 'never) nil)
((eq mm-verify-option 'always) t)
((eq mm-verify-option 'known) t)
- (t (y-or-n-p "Verify pgp signed part? ")))))
+ (t (prog1
+ (y-or-n-p "Verify pgp signed part? ")
+ (message ""))))))
(eval-when-compile
(defvar gnus-newsgroup-charset))
((eq mm-decrypt-option 'never) nil)
((eq mm-decrypt-option 'always) t)
((eq mm-decrypt-option 'known) t)
- (t (y-or-n-p "Decrypt pgp encrypted part? ")))))
+ (t (prog1
+ (y-or-n-p "Decrypt pgp encrypted part? ")
+ (message ""))))))
(defun mm-uu-pgp-encrypted-extract-1 (handles ctl)
- (let ((buf (mm-uu-copy-to-buffer (point-min) (point-max))))
- (if (mm-uu-pgp-encrypted-test)
- (with-current-buffer buf
- (mml2015-clean-buffer)
- (funcall (mml2015-clear-decrypt-function))))
- (list (mm-make-handle buf mm-uu-text-plain-type))))
+ (let ((buf (mm-uu-copy-to-buffer (point-min) (point-max)))
+ (first t)
+ charset)
+ ;; Make sure there's a blank line between header and body.
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (while (prog2
+ (forward-line 1)
+ (if first
+ (looking-at "[^\t\n ]+:")
+ (looking-at "[^\t\n ]+:\\|[\t ]"))
+ (setq first nil)))
+ (unless (memq (char-after) '(?\n nil))
+ (insert "\n"))
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (setq charset (mail-fetch-field "charset")))
+ (if (and (mm-uu-pgp-encrypted-test)
+ (progn
+ (mml2015-clean-buffer)
+ (funcall (mml2015-clear-decrypt-function))
+ (equal (mm-handle-multipart-ctl-parameter mm-security-handle
+ 'gnus-info)
+ "OK")))
+ (progn
+ ;; Decode charset.
+ (when (and (or charset
+ (setq charset gnus-newsgroup-charset))
+ (setq charset (mm-charset-to-coding-system charset))
+ (not (eq charset 'ascii)))
+ (mm-decode-coding-region (point-min) (point-max) charset))
+ (list (mm-make-handle buf mm-uu-text-plain-type)))
+ (list (mm-make-handle buf '("application/pgp-encrypted")))))))
(defun mm-uu-pgp-encrypted-extract ()
(let ((mm-security-handle (list (format "multipart/encrypted"))))
(cons method tags))))
(t (error "The message is corrupted. No mail header separator"))))))
+(defvar mml-secure-method
+ (if (equal mml-default-encrypt-method mml-default-sign-method)
+ mml-default-sign-method
+ "pgpmime")
+ "Current security method. Internal variable.")
+
+(defun mml-secure-sign (&optional method)
+ "Add MML tags to sign this MML part.
+Use METHOD if given. Else use `mml-secure-method' or
+`mml-default-sign-method'."
+ (interactive)
+ (mml-secure-part
+ (or method mml-secure-method mml-default-sign-method)
+ 'sign))
+
+(defun mml-secure-encrypt (&optional method)
+ "Add MML tags to encrypt this MML part.
+Use METHOD if given. Else use `mml-secure-method' or
+`mml-default-sign-method'."
+ (interactive)
+ (mml-secure-part
+ (or method mml-secure-method mml-default-sign-method)))
+
(defun mml-secure-sign-pgp ()
"Add MML tags to PGP sign this MML part."
(interactive)
(when (re-search-backward "^<#secure.*>\n" nil t)
(delete-region (match-beginning 0) (match-end 0)))))
+
+(defun mml-secure-message-sign (&optional method)
+ "Add MML tags to sign this MML part.
+Use METHOD if given. Else use `mml-secure-method' or
+`mml-default-sign-method'."
+ (interactive)
+ (mml-secure-part
+ (or method mml-secure-method mml-default-sign-method)
+ 'sign))
+
+(defun mml-secure-message-sign-encrypt (&optional method)
+ "Add MML tag to sign and encrypt the entire message.
+Use METHOD if given. Else use `mml-secure-method' or
+`mml-default-sign-method'."
+ (interactive)
+ (mml-secure-message
+ (or method mml-secure-method mml-default-sign-method)
+ 'signencrypt))
+
+(defun mml-secure-message-encrypt (&optional method)
+ "Add MML tag to encrypt the entire message.
+Use METHOD if given. Else use `mml-secure-method' or
+`mml-default-sign-method'."
+ (interactive)
+ (mml-secure-message
+ (or method mml-secure-method mml-default-sign-method)
+ 'encrypt))
+
(defun mml-secure-message-sign-smime ()
"Add MML tag to encrypt/sign the entire message."
(interactive)
(autoload 'message-fetch-field "message")
(autoload 'message-info "message")
(autoload 'fill-flowed-encode "flow-fill")
- (autoload 'message-posting-charset "message"))
+ (autoload 'message-posting-charset "message")
+ (autoload 'dnd-get-local-file-name "dnd"))
(defvar gnus-article-mime-handles)
(defvar gnus-mouse-2)
(defvar message-posting-charset)
(defvar message-required-mail-headers)
(defvar message-required-news-headers)
+(defvar dnd-protocol-alist)
(defcustom mml-content-type-parameters
'(name access-type expiration size permission format)
(encryptpart (make-sparse-keymap))
(map (make-sparse-keymap))
(main (make-sparse-keymap)))
+ (define-key map "\C-s" 'mml-secure-message-sign)
+ (define-key map "\C-c" 'mml-secure-message-encrypt)
+ (define-key map "\C-e" 'mml-secure-message-sign-encrypt)
+ (define-key map "\C-p\C-s" 'mml-secure-sign)
+ (define-key map "\C-p\C-c" 'mml-secure-encrypt)
(define-key sign "p" 'mml-secure-message-sign-pgpmime)
(define-key sign "o" 'mml-secure-message-sign-pgp)
(define-key sign "s" 'mml-secure-message-sign-smime)
["Attach File..." mml-attach-file
,@(if (featurep 'xemacs) '(t)
'(:help "Attach a file at point"))]
- ["Attach Buffer..." mml-attach-buffer t]
- ["Attach External..." mml-attach-external t]
- ["Insert Part..." mml-insert-part t]
- ["Insert Multipart..." mml-insert-multipart t]
- ["PGP/MIME Sign" mml-secure-message-sign-pgpmime t]
- ["PGP/MIME Encrypt" mml-secure-message-encrypt-pgpmime t]
- ["PGP Sign" mml-secure-message-sign-pgp t]
- ["PGP Encrypt" mml-secure-message-encrypt-pgp t]
- ["S/MIME Sign" mml-secure-message-sign-smime t]
- ["S/MIME Encrypt" mml-secure-message-encrypt-smime t]
- ("Secure MIME part"
- ["PGP/MIME Sign Part" mml-secure-sign-pgpmime t]
- ["PGP/MIME Encrypt Part" mml-secure-encrypt-pgpmime t]
- ["PGP Sign Part" mml-secure-sign-pgp t]
- ["PGP Encrypt Part" mml-secure-encrypt-pgp t]
- ["S/MIME Sign Part" mml-secure-sign-smime t]
- ["S/MIME Encrypt Part" mml-secure-encrypt-smime t])
- ["Encrypt/Sign off" mml-unsecure-message t]
+ ["Attach Buffer..." mml-attach-buffer
+ ,@(if (featurep 'xemacs) '(t)
+ '(:help "Attach a buffer to the outgoing MIME message"))]
+ ["Attach External..." mml-attach-external
+ ,@(if (featurep 'xemacs) '(t)
+ '(:help "Attach reference to file"))]
+ ;;
+ ("Change Security Method"
+ ["PGP/MIME"
+ (lambda () (interactive) (setq mml-secure-method "pgpmime"))
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Set Security Method to PGP/MIME"))
+ :style radio
+ :selected (equal mml-secure-method "pgpmime") ]
+ ["S/MIME"
+ (lambda () (interactive) (setq mml-secure-method "smime"))
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Set Security Method to S/MIME"))
+ :style radio
+ :selected (equal mml-secure-method "smime") ]
+ ["Inline PGP"
+ (lambda () (interactive) (setq mml-secure-method "pgp"))
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Set Security Method to inline PGP"))
+ :style radio
+ :selected (equal mml-secure-method "pgp") ] )
+ ;;
+ ["Sign Message" mml-secure-message-sign t]
+ ["Encrypt Message" mml-secure-message-encrypt t]
+ ["Sign and Encrypt Message" mml-secure-message-sign-encrypt t]
+ ["Encrypt/Sign off" mml-unsecure-message
+ ,@(if (featurep 'xemacs) '(t)
+ '(:help "Don't Encrypt/Sign Message"))]
+ ;; Maybe we could remove these, because people who write MML most probably
+ ;; don't use the menu:
+ ["Insert Part..." mml-insert-part
+ :active (message-in-body-p)]
+ ["Insert Multipart..." mml-insert-multipart
+ :active (message-in-body-p)]
+ ;;
+ ;; Do we have separate encrypt and encrypt/sign commands for parts?
+ ["Sign Part" mml-secure-sign t]
+ ["Encrypt Part" mml-secure-encrypt t]
;;["Narrow" mml-narrow-to-part t]
- ["Quote MML" mml-quote-region t]
+ ["Quote MML in region" mml-quote-region
+ :active (message-mark-active-p)
+ ,@(if (featurep 'xemacs) nil
+ '(:help "Quote MML tags in region"))]
["Validate MML" mml-validate t]
["Preview" mml-preview t]
"----"
(when (set (make-local-variable 'mml-mode)
(if (null arg) (not mml-mode)
(> (prefix-numeric-value arg) 0)))
- (gnus-add-minor-mode 'mml-mode " MML" mml-mode-map)
+ (add-minor-mode 'mml-mode " MML" mml-mode-map)
(easy-menu-add mml-menu mml-mode-map)
+ (when (boundp 'dnd-protocol-alist)
+ (set (make-local-variable 'dnd-protocol-alist)
+ (append mml-dnd-protocol-alist dnd-protocol-alist)))
(run-hooks 'mml-mode-hook)))
;;;
;;; Attachment functions.
+(defcustom mml-dnd-protocol-alist
+ '(("^file:///" . mml-dnd-attach-file)
+ ("^file://" . dnd-open-file)
+ ("^file:" . mml-dnd-attach-file))
+ "The functions to call when a drop in `mml-mode' is made.
+See `dnd-protocol-alist' for more information. When nil, behave
+as in other buffers."
+ :type '(choice (repeat (cons (regexp) (function)))
+ (const :tag "Behave as in other buffers" nil))
+ :version "22.1" ;; Gnus 5.10.9
+ :group 'message)
+
+(defcustom mml-dnd-attach-options nil
+ "Which options should be queried when attaching a file via drag and drop.
+
+If it is a list, valid members are `type', `description' and
+`disposition'. `disposition' implies `type'. If it is nil,
+don't ask for options. If it is t, ask the user whether or not
+to specify options."
+ :type '(choice
+ (const :tag "Non" nil)
+ (const :tag "Query" t)
+ (list :value (type description disposition)
+ (set :inline t
+ (const type)
+ (const description)
+ (const disposition))))
+ :version "22.1" ;; Gnus 5.10.9
+ :group 'message)
+
(defun mml-attach-file (file &optional type description disposition)
"Attach a file to the outgoing MIME message.
The file is not inserted or encoded until you send the message with
(description (mml-minibuffer-read-description))
(disposition (mml-minibuffer-read-disposition type)))
(list file type description disposition)))
- (mml-insert-empty-tag 'part
- 'type type
- 'filename file
- 'disposition (or disposition "attachment")
- 'description description))
+ (save-excursion
+ (unless (message-in-body-p) (goto-char (point-max)))
+ (mml-insert-empty-tag 'part
+ 'type type
+ 'filename file
+ 'disposition (or disposition "attachment")
+ 'description description)))
+
+(defun mml-dnd-attach-file (uri action)
+ "Attach a drag and drop file.
+
+Ask for type, description or disposition according to
+`mml-dnd-attach-options'."
+ (let ((file (dnd-get-local-file-name uri t)))
+ (when (and file (file-regular-p file))
+ (let ((mml-dnd-attach-options mml-dnd-attach-options)
+ type description disposition)
+ (setq mml-dnd-attach-options
+ (when (and (eq mml-dnd-attach-options t)
+ (not
+ (y-or-n-p
+ "Use default type, disposition and description? ")))
+ '(type description disposition)))
+ (when (or (memq 'type mml-dnd-attach-options)
+ (memq 'disposition mml-dnd-attach-options))
+ (setq type (mml-minibuffer-read-type file)))
+ (when (memq 'description mml-dnd-attach-options)
+ (setq description (mml-minibuffer-read-description)))
+ (when (memq 'disposition mml-dnd-attach-options)
+ (setq disposition (mml-minibuffer-read-disposition type)))
+ (mml-attach-file file type description disposition)))))
(defun mml-attach-buffer (buffer &optional type description)
"Attach a buffer to the outgoing MIME message.
(type (mml-minibuffer-read-type buffer "text/plain"))
(description (mml-minibuffer-read-description)))
(list buffer type description)))
- (mml-insert-empty-tag 'part 'type type 'buffer buffer
- 'disposition "attachment" 'description description))
+ (save-excursion
+ (unless (message-in-body-p) (goto-char (point-max)))
+ (mml-insert-empty-tag 'part 'type type 'buffer buffer
+ 'disposition "attachment"
+ 'description description)))
(defun mml-attach-external (file &optional type description)
"Attach an external file into the buffer.
(type (mml-minibuffer-read-type file))
(description (mml-minibuffer-read-description)))
(list file type description)))
- (mml-insert-empty-tag 'external 'type type 'name file
- 'disposition "attachment" 'description description))
+ (save-excursion
+ (unless (message-in-body-p) (goto-char (point-max)))
+ (mml-insert-empty-tag 'external 'type type 'name file
+ 'disposition "attachment" 'description description)))
(defun mml-insert-multipart (&optional type)
(interactive (list (completing-read "Multipart type (default mixed): "
(defvar pgg-output-buffer))
(defun mml1991-pgg-sign (cont)
+ ;; Make sure to load pgg.el before binding pgg-* variables.
+ (require 'pgg)
(let ((pgg-text-mode t)
+ (pgg-default-user-id (or (message-options-get 'mml-sender)
+ pgg-default-user-id))
headers cte)
;; Don't sign headers.
(goto-char (point-min))
- (while (not (looking-at "^$"))
- (forward-line))
- (unless (eobp) ;; no headers?
+ (when (re-search-forward "^$" nil t)
(setq headers (buffer-substring (point-min) (point)))
- (forward-line) ;; skip header/body separator
- (delete-region (point-min) (point)))
- (when (string-match "^Content-Transfer-Encoding: \\(.+\\)" headers)
- (setq cte (intern (match-string 1 headers))))
- (mm-decode-content-transfer-encoding cte)
- (unless (let ((pgg-default-user-id
- (or (message-options-get 'mml-sender)
- pgg-default-user-id)))
- (pgg-sign-region (point-min) (point-max) t))
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (setq cte (mail-fetch-field "content-transfer-encoding")))
+ (forward-line 1)
+ (delete-region (point-min) (point))
+ (when cte
+ (setq cte (intern (downcase cte)))
+ (mm-decode-content-transfer-encoding cte)))
+ (unless (pgg-sign-region (point-min) (point-max) t)
(pop-to-buffer pgg-errors-buffer)
(error "Encrypt error"))
(delete-region (point-min) (point-max))
(goto-char (point-min))
(while (re-search-forward "\r+$" nil t)
(replace-match "" t t))
- (mm-encode-content-transfer-encoding cte)
+ (when cte
+ (mm-encode-content-transfer-encoding cte))
(goto-char (point-min))
(when headers
(insert headers))
t))
(defun mml1991-pgg-encrypt (cont &optional sign)
- (let ((pgg-text-mode t)
- cte)
- ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED
- (goto-char (point-min))
- (while (looking-at "^Content[^ ]+:")
- (when (looking-at "^Content-Transfer-Encoding: \\(.+\\)")
- (setq cte (intern (match-string 1))))
- (forward-line))
- (unless (bobp)
- (delete-region (point-min) (point)))
- (mm-decode-content-transfer-encoding cte)
- (unless (pgg-encrypt-region
- (point-min) (point-max)
- (split-string
- (or
- (message-options-get 'message-recipients)
- (message-options-set 'message-recipients
- (read-string "Recipients: ")))
- "[ \f\t\n\r\v,]+")
- sign)
- (pop-to-buffer pgg-errors-buffer)
- (error "Encrypt error"))
- (delete-region (point-min) (point-max))
- ;;(insert "Content-Type: application/pgp-encrypted\n\n")
- ;;(insert "Version: 1\n\n")
- (insert "\n")
- (insert-buffer-substring pgg-output-buffer)
- t))
+ (goto-char (point-min))
+ (when (re-search-forward "^$" nil t)
+ (let ((cte (save-restriction
+ (narrow-to-region (point-min) (point))
+ (mail-fetch-field "content-transfer-encoding"))))
+ ;; Strip MIME headers since it will be ASCII armoured.
+ (forward-line 1)
+ (delete-region (point-min) (point))
+ (when cte
+ (mm-decode-content-transfer-encoding (intern (downcase cte))))))
+ (unless (progn
+ ;; Make sure to load pgg.el before binding `pgg-text-mode'.
+ (require 'pgg)
+ (let ((pgg-text-mode t))
+ (pgg-encrypt-region
+ (point-min) (point-max)
+ (split-string
+ (or
+ (message-options-get 'message-recipients)
+ (message-options-set 'message-recipients
+ (read-string "Recipients: ")))
+ "[ \f\t\n\r\v,]+")
+ sign)))
+ (pop-to-buffer pgg-errors-buffer)
+ (error "Encrypt error"))
+ (delete-region (point-min) (point-max))
+ (insert "\n")
+ (insert-buffer-substring pgg-output-buffer)
+ t)
;;;###autoload
(defun mml1991-encrypt (cont &optional sign)
(defun nnweb-google-wash-article ()
;; We have Google's masked e-mail addresses here. :-/
(let ((case-fold-search t)
- (start-re "<pre>\n *")
- (end-re "\n *</pre>"))
+ (start-re "<pre>[\r\n ]*")
+ (end-re "[\r\n ]*</pre>"))
(goto-char (point-min))
(if (save-excursion
(or (re-search-forward "The requested message.*could not be found."
+2006-04-26 Reiner Steib <Reiner.Steib@gmx.de>
+
+ * pgg.texi (Caching passphrase): Fix markup and typos. Simplify.
+
+2006-04-26 Sascha Wilde <wilde@sha-bang.de>
+
+ * pgg.texi (Caching passphrase): Added documentation for
+ pgg-gpg-use-agent.
+
2006-04-24 Bill Wohler <wohler@newt.com>
* mh-e.texi (Getting Started): Made it more explicit that you need
Elapsed time for expiration in seconds.
@end defvar
+@defvar pgg-gpg-use-agent
+When using GnuPG (gpg) as PGP scheme you can use @code{gpg-agent} for
+caching@footnote{Actually @code{gpg-agent} does not cache passphrases
+but private keys. On the other hand, from a users point of view this
+technical difference isn't visible.}. If non-@code{nil} try to use a
+running @code{gpg-agent}. It defaults to @code{nil}.
+@end defvar
+
@node Default user identity
@section Default user identity