[gnus git] branch master updated: n0-17-77-g10a8138 =1= Netrc field encryption support.

Ted Zlatanov <[email protected]>
Newsgroups gmane.emacs.gnus.cvs
Message-ID <[email protected]>
       via  10a8138a1a5e7be68ff9b86492b507b342a4dead (commit)
      from  5d7c18060995c206e8a708829fa30801885cb972 (commit)


- Log -----------------------------------------------------------------
commit 10a8138a1a5e7be68ff9b86492b507b342a4dead
Author: Ted Zlatanov <[email protected]>
Date:   Wed Jun 15 22:38:55 2011 -0500

    Netrc field encryption support.
    
    * auth-source.el (auth-source-save-secrets): New variable to control if
    secret tokens should be saved encrypted.
    (auth-source-netrc-parse, auth-source-netrc-search): Pass the file name
    to `auth-source-netrc-normalize'.
    (with-auth-source-epa-overrides): Add convenience macro.
    (auth-source-epa-make-gpg-token): Convert text to a "gpg:" token.
    (auth-source-netrc-normalize): Convert "gpg:" tokens back to text in
    the lexical-let closure.
    (auth-source-netrc-create): Create "gpg:" tokens according to
    `auth-source-save-secrets'.

diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 2a27541..6052296 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,16 @@
+2011-06-16  Teodor Zlatanov  <[email protected]>
+
+	* auth-source.el (auth-source-save-secrets): New variable to control if
+	secret tokens should be saved encrypted.
+	(auth-source-netrc-parse, auth-source-netrc-search): Pass the file name
+	to `auth-source-netrc-normalize'.
+	(with-auth-source-epa-overrides): Add convenience macro.
+	(auth-source-epa-make-gpg-token): Convert text to a "gpg:" token.
+	(auth-source-netrc-normalize): Convert "gpg:" tokens back to text in
+	the lexical-let closure.
+	(auth-source-netrc-create): Create "gpg:" tokens according to
+	`auth-source-save-secrets'.
+
 2011-06-10  Katsumi Yamaoka  <[email protected]>
 
 	* gnus-group.el (gnus-group-update-group): Add new argument
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index ce483e4..904d523 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -164,6 +164,16 @@ let-binding."
           (const :tag "Never save" nil)
           (const :tag "Ask" ask)))
 
+(defcustom auth-source-save-secrets nil
+  "If set, auth-source will respect it for password tokens behavior."
+  :group 'auth-source
+  :version "23.2" ;; No Gnus
+  :type `(choice
+          :tag "auth-source new password token behavior"
+          (const :tag "Use GPG tokens" gpg)
+          (const :tag "Save unencrypted" nil)
+          (const :tag "Ask" ask)))
+
 (defvar auth-source-magic "auth-source-magic ")
 
 (defcustom auth-source-do-cache t
@@ -908,7 +918,7 @@ Note that the MAX parameter is used so we can exit the parse early."
                         (null require)
                         ;; every element of require is in the normalized list
                         (let ((normalized (nth 0 (auth-source-netrc-normalize
-                                                 (list alist)))))
+                                                 (list alist) file))))
                           (loop for req in require
                                 always (plist-get normalized req)))))
               (decf max)
@@ -944,7 +954,48 @@ Note that the MAX parameter is used so we can exit the parse early."
 
           (nreverse result))))))
 
-(defun auth-source-netrc-normalize (alist)
+(defmacro with-auth-source-epa-overrides (&rest body)
+  `(let ((file-name-handler-alist
+          ',(remove epa-file-handler file-name-handler-alist))
+         (find-file-hook
+          ',(remove 'epa-file-find-file-hook find-file-hook))
+         (auto-mode-alist
+          ',(remove epa-file-auto-mode-alist-entry auto-mode-alist)))
+     ,@body))
+
+(defun auth-source-epa-make-gpg-token (secret file)
+  (require 'epa nil t)
+  (unless (featurep 'epa)
+    (error "EPA could not be loaded."))
+  (let* ((base (file-name-sans-extension file))
+         (passkey (format "gpg:-%s" base))
+         (stash (concat base ".gpg"))
+         ;; temporarily disable EPA
+         (stashfile
+          (with-auth-source-epa-overrides
+           (make-temp-file "gpg-token" nil
+                           stash)))
+         (epa-file-passphrase-alist
+          `((,stashfile
+             . ,(password-read
+                 (format
+                  "token pass for %s? "
+                  file)
+                 passkey)))))
+    (write-region secret nil stashfile)
+    ;; temporarily disable EPA
+    (unwind-protect
+        (with-auth-source-epa-overrides
+         (with-temp-buffer
+           (insert-file-contents stashfile)
+           (base64-encode-region (point-min) (point-max) t)
+           (concat "gpg:"
+                   (buffer-substring-no-properties
+                    (point-min)
+                    (point-max)))))
+      (delete-file stashfile))))
+
+(defun auth-source-netrc-normalize (alist filename)
   (mapcar (lambda (entry)
             (let (ret item)
               (while (setq item (pop entry))
@@ -960,13 +1011,63 @@ Note that the MAX parameter is used so we can exit the parse early."
 
                   ;; send back the secret in a function (lexical binding)
                   (when (equal k "secret")
-                    (setq v (lexical-let ((v v))
-                              (lambda () v))))
-
+                    (setq v (lexical-let ((v v)
+                                          (filename filename)
+                                          (base (file-name-nondirectory
+                                                 filename))
+                                          (token-decoder nil)
+                                          (gpgdata nil)
+                                          (stash nil))
+                              (setq stash (concat base ".gpg"))
+                              (when (string-match "gpg:\\(.+\\)" v)
+                                (require 'epa nil t)
+                                (unless (featurep 'epa)
+                                  (error "EPA could not be loaded."))
+                                (setq gpgdata (base64-decode-string
+                                               (match-string 1 v)))
+                                ;; it's a GPG token
+                                (setq
+                                 token-decoder
+                                 (lambda (gpgdata)
+;;; FIXME: this relies on .gpg files being handled by EPA/EPG
+                                   (let* ((passkey (format "gpg:-%s" base))
+                                          ;; temporarily disable EPA
+                                          (stashfile
+                                           (with-auth-source-epa-overrides
+                                            (make-temp-file "gpg-token" nil
+                                                            stash)))
+                                          (epa-file-passphrase-alist
+                                           `((,stashfile
+                                              . ,(password-read
+                                                  (format
+                                                   "token pass for %s? "
+                                                   filename)
+                                                  passkey)))))
+                                     (unwind-protect
+                                         (progn
+                                           ;; temporarily disable EPA
+                                           (with-auth-source-epa-overrides
+                                            (write-region gpgdata
+                                                          nil
+                                                          stashfile))
+                                           (setq
+                                            v
+                                            (with-temp-buffer
+                                              (insert-file-contents stashfile)
+                                              (buffer-substring-no-properties
+                                               (point-min)
+                                               (point-max)))))
+                                       (delete-file stashfile)))
+                                   ;; clear out the decoder at end
+                                   (setq token-decoder nil
+                                         gpgdata nil))))
+                          (lambda ()
+                            (when token-decoder
+                              (funcall token-decoder gpgdata))
+                            v))))
                   (setq ret (plist-put ret
                                        (intern (concat ":" k))
-                                       v))
-                  ))
+                                     v))))
               ret))
           alist))
 
@@ -992,7 +1093,8 @@ See `auth-source-search' for details on SPEC."
                    :file (oref backend source)
                    :host (or host t)
                    :user (or user t)
-                   :port (or port t)))))
+                   :port (or port t))
+                  (oref backend source))))
 
     ;; if we need to create an entry AND none were found to match
     (when (and create
@@ -1108,7 +1210,21 @@ See `auth-source-search' for details on SPEC."
               (cond
                ((and (null data) (eq r 'secret))
                 ;; Special case prompt for passwords.
-                (read-passwd prompt))
+                ;; Respect `auth-source-save-secrets'
+                (let* ((ep (format "Do you want GPG password tokens? (%s)"
+                                   "see `auth-source-save-secrets'"))
+                       (gpg-encrypt
+;;; FIXME: this relies on .gpg files being handled by EPA/EPG
+                        ;; don't put GPG tokens in GPG-encrypted files
+                        (and (not (equal "gpg" (file-name-extension file)))
+                             (or (eq auth-source-save-secrets 'gpg)
+                                 (and (eq auth-source-save-secrets 'ask)
+                                      (setq auth-source-save-secrets
+                                            (and (y-or-n-p ep) 'gpg))))))
+                        (plain (read-passwd prompt)))
+                  (if (eq auth-source-save-secrets 'gpg)
+                      (auth-source-epa-make-gpg-token plain file)
+                    plain)))
                ((null data)
                 (when default
                   (setq prompt

-----------------------------------------------------------------------
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we listed those
revisions in full, above.

Summary of changes:
 lisp/ChangeLog      |   13 +++++
 lisp/auth-source.el |  142 ++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 142 insertions(+), 13 deletions(-)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnus Project".

The branch, master has been updated


hooks/post-receive
-- 
Gnus Project
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.