- elmo-imap4-session))
- (with-current-buffer (process-buffer
- (elmo-network-session-process-internal session))
- (unless (eq elmo-imap4-status 'auth)
- (unless (or (not (elmo-network-session-auth-internal session))
- (eq (elmo-network-session-auth-internal session) 'plain)
- (and (memq (intern
- (format "auth=%s"
- (elmo-network-session-auth-internal
- session)))
- (elmo-imap4-session-capability-internal session))
- (assq
- (elmo-network-session-auth-internal session)
- elmo-imap4-authenticator-alist)))
- (if (or elmo-imap4-force-login
- (y-or-n-p
- (format
- "There's no %s capability in server. continue?"
- (elmo-network-session-auth-internal session))))
- (elmo-network-session-set-auth-internal session nil)
- (signal 'elmo-open-error
- '(elmo-network-initialize-session))))
- (let ((authenticator
- (if (elmo-network-session-auth-internal session)
- (nth 1 (assq
- (elmo-network-session-auth-internal session)
- elmo-imap4-authenticator-alist))
- 'elmo-imap4-login)))
- (funcall authenticator session)))))
+ elmo-imap4-session))
+ (with-current-buffer (process-buffer
+ (elmo-network-session-process-internal session))
+ (let* ((auth (elmo-network-session-auth-internal session))
+ (auth (if (listp auth) auth (list auth))))
+ (unless (or (eq elmo-imap4-status 'auth)
+ (null auth))
+ (cond
+ ((eq 'clear (car auth))
+ (elmo-imap4-clear-login session))
+ ((eq 'login (car auth))
+ (elmo-imap4-auth-login session))
+ (t
+ (let* ((elmo-imap4-debug-inhibit-logging t)
+ (sasl-mechanisms
+ (delq nil
+ (mapcar
+ '(lambda (cap)
+ (if (string-match "^auth=\\(.*\\)$"
+ (symbol-name cap))
+ (match-string 1 (upcase (symbol-name cap)))))
+ (elmo-imap4-session-capability-internal session))))
+ (mechanism
+ (sasl-find-mechanism
+ (delq nil
+ (mapcar '(lambda (cap) (upcase (symbol-name cap)))
+ (if (listp auth)
+ auth
+ (list auth)))))) ;)
+ client name step response tag
+ sasl-read-passphrase)
+ (unless mechanism
+ (if (or elmo-imap4-force-login
+ (y-or-n-p
+ (format
+ "There's no %s capability in server. continue?"
+ (elmo-list-to-string
+ (elmo-network-session-auth-internal session)))))
+ (setq mechanism (sasl-find-mechanism
+ sasl-mechanisms))
+ (signal 'elmo-authenticate-error
+ '(elmo-imap4-auth-no-mechanisms))))
+ (setq client
+ (sasl-make-client
+ mechanism
+ (elmo-network-session-user-internal session)
+ "imap"
+ (elmo-network-session-host-internal session)))
+;;; (if elmo-imap4-auth-user-realm
+;;; (sasl-client-set-property client 'realm elmo-imap4-auth-user-realm))
+ (setq name (sasl-mechanism-name mechanism)
+ step (sasl-next-step client nil))
+ (elmo-network-session-set-auth-internal
+ session
+ (intern (downcase name)))
+ (setq sasl-read-passphrase
+ (function
+ (lambda (prompt)
+ (elmo-get-passwd
+ (elmo-network-session-password-key session)))))
+ (setq tag
+ (elmo-imap4-send-command
+ session
+ (concat "AUTHENTICATE " name
+ (and (sasl-step-data step)
+ (concat
+ " "
+ (elmo-base64-encode-string
+ (sasl-step-data step)
+ 'no-lin-break)))))) ;)
+ (catch 'done
+ (while t
+ (setq response
+ (elmo-imap4-read-untagged
+ (elmo-network-session-process-internal session)))
+ (if (elmo-imap4-response-continue-req-p response)
+ (unless (sasl-next-step client step)
+ ;; response is '+' but there's no next step.
+ (signal 'elmo-authenticate-error
+ (list (intern
+ (concat "elmo-imap4-auth-"
+ (downcase name))))))
+ ;; response is OK.
+ (if (elmo-imap4-response-ok-p response)
+ (throw 'done nil) ; finished.
+ ;; response is NO or BAD.
+ (signal 'elmo-authenticate-error
+ (list (intern
+ (concat "elmo-imap4-auth-"
+ (downcase name)))))))
+ (sasl-step-set-data
+ step
+ (elmo-base64-decode-string
+ (elmo-imap4-response-value response 'continue-req)))
+ (setq step (sasl-next-step client step))
+ (setq tag
+ (elmo-imap4-send-string
+ session
+ (if (sasl-step-data step)
+ (elmo-base64-encode-string (sasl-step-data step)
+ 'no-line-break)
+ ""))))))))))))