Move pass-phrase memoization into the front end. Now connections to
authorChris Hanson <org/chris-hanson/cph>
Mon, 22 May 2000 20:22:52 +0000 (20:22 +0000)
committerChris Hanson <org/chris-hanson/cph>
Mon, 22 May 2000 20:22:52 +0000 (20:22 +0000)
the same account on the same server can share a pass phrase.

v7/src/imail/imail-core.scm
v7/src/imail/imail-file.scm
v7/src/imail/imail-imap.scm
v7/src/imail/imail-top.scm
v7/src/imail/todo.txt

index 363fca89fac18c2d1c2e335691ed5e6ed2ebcf89..054185a5d599b4247248ab6d3f387d60ccfb34ec 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;; $Id: imail-core.scm,v 1.85 2000/05/22 19:49:50 cph Exp $
+;;; $Id: imail-core.scm,v 1.86 2000/05/22 20:22:32 cph Exp $
 ;;;
 ;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
 ;;;
 
 ;; Return #T if URL represents an existing folder.
 (define-generic url-exists? (url))
+
+;; Return a string that can be used as a key to memoize a pass phrase
+;; for URL.  E.g. for IMAP this could be the URL string without the
+;; mailbox information, which would allow all URLs referring to the
+;; same user account on the same server to share a pass phrase.
+(define-generic url-pass-phrase-key (url))
 \f
 ;; Convert STRING to a URL.  GET-DEFAULT-URL is a procedure of one
 ;; argument that returns a URL that is used to fill in defaults if
index 729d100863731ac0c42ed9e5612a2882d9ed3975..a5055bf079ecce60346356893b36df6fe05de5bd 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;; $Id: imail-file.scm,v 1.35 2000/05/22 19:49:55 cph Exp $
+;;; $Id: imail-file.scm,v 1.36 2000/05/22 20:22:37 cph Exp $
 ;;;
 ;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
 ;;;
 (define-method url-exists? ((url <file-url>))
   (file-exists? (file-url-pathname url)))
 
+(define-method url-pass-phrase-key ((url <file-url>))
+  ;; Unused
+  url
+  "")
+
 (define (define-file-url-completers class filter)
   (define-method %url-complete-string
       ((string <string>) (default-url class)
index f20da48df27b86a1e4461842a8d7ffeb0dcfedc8..b6ca85b1cefdd700da13611fd97ae73d769bfed6 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;; $Id: imail-imap.scm,v 1.74 2000/05/22 19:49:57 cph Exp $
+;;; $Id: imail-imap.scm,v 1.75 2000/05/22 20:22:39 cph Exp $
 ;;;
 ;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
 ;;;
   (and (string=? (imap-url-user-id url1) (imap-url-user-id url2))
        (string=? (imap-url-host url1) (imap-url-host url2))
        (= (imap-url-port url1) (imap-url-port url2))))
+
+(define-method url-pass-phrase-key ((url <imap-url>))
+  (make-imap-url-string (imap-url-user-id url)
+                       (imap-url-host url)
+                       (imap-url-port url)
+                       ""))
 \f
 (define-method parse-url-body (string default-url)
   (call-with-values (lambda () (parse-imap-url-body string default-url))
 
 (define-class (<imap-connection> (constructor (url))) ()
   (url             define accessor)
-  (passphrase      define standard initial-value #f)
   (port            define standard initial-value #f)
   (greeting        define standard initial-value #f)
   (sequence-number define standard initial-value 0)
                (close-imap-connection connection)
                (error "Server doesn't support IMAP4rev1:" url)))
          (let ((response
-                (call-with-memoized-passphrase connection
-                  (lambda (passphrase)
+                (imail-call-with-pass-phrase (imap-connection-url connection)
+                  (lambda (pass-phrase)
                     (imap:command:login connection
                                         (imap-url-user-id url)
-                                        passphrase)))))
+                                        pass-phrase)))))
            (if (imap:response:no? response)
                (begin
                  (close-imap-connection connection)
         (if (imap-connection-folder connection) 0 1))
       (close-imap-connection connection)))
 \f
-(define (call-with-memoized-passphrase connection receiver)
-  (let ((passphrase (imap-connection-passphrase connection)))
-    (if passphrase
-       (call-with-unobscured-passphrase passphrase receiver)
-       (imail-call-with-pass-phrase (imap-connection-url connection)
-         (lambda (passphrase)
-           (set-imap-connection-passphrase! connection
-                                            (obscure-passphrase passphrase))
-           (receiver passphrase))))))
-
-(define (obscure-passphrase clear-text)
-  (let ((n (string-length clear-text)))
-    (let ((noise (random-byte-vector n)))
-      (let ((obscured-text (make-string (* 2 n))))
-       (string-move! noise obscured-text 0)
-       (do ((i 0 (fix:+ i 1)))
-           ((fix:= i n))
-         (vector-8b-set! obscured-text (fix:+ i n)
-                         (fix:xor (vector-8b-ref clear-text i)
-                                  (vector-8b-ref noise i))))
-       obscured-text))))
-
-(define (call-with-unobscured-passphrase obscured-text receiver)
-  (let ((n (quotient (string-length obscured-text) 2))
-       (clear-text))
-    (dynamic-wind
-     (lambda ()
-       (set! clear-text (make-string n))
-       unspecific)
-     (lambda ()
-       (do ((i 0 (fix:+ i 1)))
-          ((fix:= i n))
-        (vector-8b-set! clear-text i
-                        (fix:xor (vector-8b-ref obscured-text i)
-                                 (vector-8b-ref obscured-text (fix:+ i n)))))
-       (receiver clear-text))
-     (lambda ()
-       (string-fill! clear-text #\NUL)
-       (set! clear-text)
-       unspecific))))
-\f
 ;;;; Folder datatype
 
 (define-class (<imap-folder> (constructor (url connection))) (<folder>)
    (imap:command:single-response imap:response:capability? connection
                                 'CAPABILITY)))
 
-(define (imap:command:login connection user-id passphrase)
+(define (imap:command:login connection user-id pass-phrase)
   ((imail-message-wrapper "Logging in as " user-id)
    (lambda ()
-     (imap:command:no-response-1 connection 'LOGIN user-id passphrase))))
+     (imap:command:no-response-1 connection 'LOGIN user-id pass-phrase))))
 
 (define (imap:command:select connection mailbox)
   ((imail-message-wrapper "Select mailbox " mailbox)
index 9b1325d385dd44eae2ed447b04ac389740a6820f..884b60bf2140fe366f02c9a05509584aa7881834 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;; $Id: imail-top.scm,v 1.85 2000/05/22 19:48:23 cph Exp $
+;;; $Id: imail-top.scm,v 1.86 2000/05/22 20:22:46 cph Exp $
 ;;;
 ;;; Copyright (c) 1999-2000 Massachusetts Institute of Technology
 ;;;
@@ -128,13 +128,6 @@ May be called with an IMAIL folder URL as argument;
                         #t)
         buffer)))))
 
-(define (imail-call-with-pass-phrase url receiver)
-  (call-with-pass-phrase (string-append "Password for user "
-                                       (imap-url-user-id url)
-                                       " on host "
-                                       (imap-url-host url))
-                        receiver))
-
 (define (prompt-for-imail-url-string prompt default . options)
   (apply prompt-for-completed-string
         prompt
@@ -219,6 +212,52 @@ May be called with an IMAIL folder URL as argument;
 
 (define *imail-message-wrapper-prefix* #f)
 \f
+(define (imail-call-with-pass-phrase url receiver)
+  (let ((key (url-pass-phrase-key url)))
+    (let ((obscured (hash-table/get imail-memoized-pass-phrases key #f)))
+      (if obscured
+         (call-with-unobscured-pass-phrase obscured receiver)
+         (call-with-pass-phrase
+          (string-append "Pass phrase for " (url->string url))
+          (lambda (pass-phrase)
+            (hash-table/put! imail-memoized-pass-phrases key
+                             (obscure-pass-phrase pass-phrase))
+            (receiver pass-phrase)))))))
+
+(define imail-memoized-pass-phrases
+  (make-string-hash-table))
+
+(define (obscure-pass-phrase clear-text)
+  (let ((n (string-length clear-text)))
+    (let ((noise (random-byte-vector n)))
+      (let ((obscured-text (make-string (* 2 n))))
+       (string-move! noise obscured-text 0)
+       (do ((i 0 (fix:+ i 1)))
+           ((fix:= i n))
+         (vector-8b-set! obscured-text (fix:+ i n)
+                         (fix:xor (vector-8b-ref clear-text i)
+                                  (vector-8b-ref noise i))))
+       obscured-text))))
+
+(define (call-with-unobscured-pass-phrase obscured-text receiver)
+  (let ((n (quotient (string-length obscured-text) 2))
+       (clear-text))
+    (dynamic-wind
+     (lambda ()
+       (set! clear-text (make-string n))
+       unspecific)
+     (lambda ()
+       (do ((i 0 (fix:+ i 1)))
+          ((fix:= i n))
+        (vector-8b-set! clear-text i
+                        (fix:xor (vector-8b-ref obscured-text i)
+                                 (vector-8b-ref obscured-text (fix:+ i n)))))
+       (receiver clear-text))
+     (lambda ()
+       (string-fill! clear-text #\NUL)
+       (set! clear-text)
+       unspecific))))
+\f
 (define-major-mode imail read-only "IMAIL"
   "IMAIL mode is used by \\[imail] for editing IMAIL files.
 All normal editing commands are turned off.
index 4b80835e5c093a4af3d37438d9d2ce8147787f78..09b1e82b4a3781e4e441ce8208a410c19553c24b 100644 (file)
@@ -1,12 +1,9 @@
 IMAIL To-Do List
-$Id: todo.txt,v 1.37 2000/05/22 19:50:34 cph Exp $
+$Id: todo.txt,v 1.38 2000/05/22 20:22:52 cph Exp $
 
 Bug fixes
 ---------
 
-* Password should be cached s.t. it can be shared between connections
-  with compatible URLs.  Right now it is per-connection.
-
 * Login messages interfere with modeline when doing completion on IMAP
   URLs.
 
@@ -73,10 +70,7 @@ New features
   message ID can be used.  (Or perhaps no cache is required for
   non-IMAP folders.)
 
-* Password memoization should be controllable from the editor.  Should
-  this be moved into "imail-top"?  Then instead of storing the
-  password in the connection object, we could store it in a hash
-  table, or in a buffer property.
+* Password memoization should be controllable from the editor.
 
 * Implement file backup when writing file folders.