(require 'pcustom)
(require 'mail-utils) ; mail-strip-quoted-names
+(eval-when-compile (require 'sasl))
(eval-and-compile
(autoload 'starttls-open-stream "starttls")
(autoload 'starttls-negotiate "starttls")
(autoload 'sasl-cram-md5 "sasl")
- (autoload 'sasl-plain "sasl"))
+ (autoload 'sasl-plain "sasl")
+ (autoload 'sasl-scram-md5-client-msg-1 "sasl")
+ (autoload 'sasl-scram-md5-client-msg-2 "sasl")
+ (autoload 'sasl-scram-md5-authenticate-server "sasl"))
(eval-when-compile (require 'cl)) ; push
:type 'boolean
:group 'smtp)
-(defcustom smtp-authentication-type nil
+(defcustom smtp-authenticate-type nil
"*SMTP authentication mechanism (RFC2554)."
:type 'symbol
:group 'smtp)
-(defvar smtp-authentication-user nil)
-(defvar smtp-authentication-passphrase nil)
+(defvar smtp-authenticate-user nil)
+(defvar smtp-authenticate-passphrase nil)
-(defvar smtp-authentication-method-alist
+(defvar smtp-authenticate-method-alist
'((cram-md5 smtp-auth-cram-md5)
(plain smtp-auth-plain)
(login smtp-auth-login)
(anonymous smtp-auth-anonymous)
(scram-md5 smtp-auth-scram-md5)
- ))
+ (digest-md5 smtp-auth-digest-md5)))
(defcustom smtp-connection-type nil
"*SMTP connection type."
:type '(choice (const nil) (const :tag "TLS" starttls))
:group 'smtp)
-
+
(defvar smtp-read-point nil)
(defun smtp-make-fqdn ()
(starttls-negotiate process))
;; AUTH --- SMTP Service Extension for Authentication (RFC2554)
- (when smtp-authentication-type
- (let ((auth (intern smtp-authentication-type)) method)
+ (when smtp-authenticate-type
+ (let ((auth (intern smtp-authenticate-type)) method)
(if (and
(memq auth extensions)
- (setq method (nth 1 (assq auth smtp-authentication-method-alist))))
+ (setq method (nth 1 (assq auth smtp-authenticate-method-alist))))
(funcall method process)
(throw 'smtp-error
(format "AUTH mechanism %s not available" auth)))))
(kill-buffer smtp-address-buffer))))
(defun smtp-auth-cram-md5 (process)
- (let ((secure-word (copy-sequence smtp-authentication-passphrase))
+ (let ((secure-word (copy-sequence smtp-authenticate-passphrase))
response)
(smtp-send-command process "AUTH CRAM-MD5")
(setq response (smtp-read-response process))
process
(setq secure-word (unwind-protect
(sasl-cram-md5
- smtp-authentication-user secure-word
+ smtp-authenticate-user secure-word
(base64-decode-string
(substring (car (cdr response)) 4)))
(fillarray secure-word 0))
(throw 'done (car (cdr response))))))
(defun smtp-auth-plain (process)
- (let ((secure-word (copy-sequence smtp-authentication-passphrase))
+ (let ((secure-word (copy-sequence smtp-authenticate-passphrase))
response)
(smtp-send-command
process
(setq secure-word (unwind-protect
- (sasl-plain "" smtp-authentication-user secure-word)
+ (sasl-plain "" smtp-authenticate-user secure-word)
(fillarray secure-word 0))
secure-word (unwind-protect
(base64-encode-string secure-word)
(throw 'done (car (cdr response))))))
(defun smtp-auth-login (process)
- (let ((secure-word (copy-sequence smtp-authentication-passphrase))
+ (let ((secure-word (copy-sequence smtp-authenticate-passphrase))
response)
+ (smtp-send-command process "AUTH LOGIN")
+ (setq response (smtp-read-response process))
+ (if (or (null (car response))
+ (not (integerp (car response)))
+ (>= (car response) 400))
+ (throw 'done (car (cdr response))))
(smtp-send-command
process
- (concat "AUTH LOGIN " smtp-authentication-user))
+ (base64-encode-string
+ smtp-authenticate-user))
(setq response (smtp-read-response process))
(if (or (null (car response))
(not (integerp (car response)))
(defun smtp-auth-scram-md5 (process)
;; now tesing
- (let ((secure-word (copy-sequence smtp-authentication-passphrase))
- server-msg-1 server-msg-2 client-msg-1
- response)
+ (let (server-msg-1 server-msg-2 client-msg-1 salted-pass
+ response secure-word)
(smtp-send-command process "AUTH SCRAM-MD5")
(setq response (smtp-read-response process))
(if (or (null (car response))
(not (integerp (car response)))
(>= (car response) 400))
- (progn
- (fillarray secure-word 0)
- (throw 'done (car (cdr response)))))
- (smtp-send-command
- process
- (base64-encode-string
- (setq client-msg-1
- (sasl-scram-md5-client-msg-1 user))) t)
+ (throw 'done (car (cdr response))))
+ (unwind-protect
+ (smtp-send-command
+ process
+ (setq secure-word
+ (base64-encode-string
+ (setq client-msg-1
+ (sasl-scram-md5-client-msg-1
+ smtp-authenticate-user)))) t)
+ (fillarray secure-word 0))
(setq response (smtp-read-response process))
(if (or (null (car response))
(not (integerp (car response)))
(>= (car response) 400))
- (progn
- (fillarray secure-word 0)
+ (progn
(fillarray client-msg-1 0)
(throw 'done (car (cdr response)))))
+ (setq secure-word
+ (unwind-protect
+ (substring (car (cdr response)) 4)
+ (fillarray (car (cdr response)) 0)))
(setq server-msg-1
- (base64-decode-string
- (substring (car (cdr response)) 4)))
- (smtp-send-command
- process
- (base64-encode-string
- (sasl-scram-md5-client-msg-2
- server-msg-1
- client-msg-1
- secure-word)) t)
+ (unwind-protect
+ (base64-decode-string secure-word)
+ (fillarray secure-word 0)))
+ (setq secure-word
+ (sasl-scram-md5-client-msg-2
+ server-msg-1 client-msg-1
+ (setq salted-pass
+ (sasl-scram-md5-make-salted-pass
+ smtp-authenticate-passphrase server-msg-1))))
+ (setq secure-word
+ (unwind-protect
+ (base64-encode-string secure-word)
+ (fillarray secure-word 0)))
+ (unwind-protect
+ (smtp-send-command process secure-word t)
+ (fillarray secure-word 0))
(setq response (smtp-read-response process))
(if (or (null (car response))
(not (integerp (car response)))
(>= (car response) 400))
(progn
- (fillarray secure-word 0)
+ (fillarray salted-pass 0)
(fillarray server-msg-1 0)
(fillarray client-msg-1 0)
(throw 'done (car (cdr response)))))
(setq server-msg-2
- (base64-decode-string
- (substring (car (cdr response)) 4)))
- (if (null (prog1
- (sasl-scram-md5-authenticate-server
- server-msg-1
- server-msg-2
- client-msg-1
- secure-word)
- (fillarray secure-word 0)
- (fillarray server-msg-1 0)
- (fillarray server-msg-2 0)
- (fillarray client-msg-1 0)))
+ (unwind-protect
+ (base64-decode-string
+ (setq secure-word
+ (substring (car (cdr response)) 4)))
+ (fillarray secure-word 0)))
+ (if (null
+ (unwind-protect
+ (sasl-scram-md5-authenticate-server
+ server-msg-1
+ server-msg-2
+ client-msg-1
+ salted-pass)
+ (fillarray salted-pass 0)
+ (fillarray server-msg-1 0)
+ (fillarray server-msg-2 0)
+ (fillarray client-msg-1 0)))
(throw 'done nil))
(smtp-send-command process "")
(setq response (smtp-read-response process))
(not (integerp (car response)))
(>= (car response) 400))
(throw 'done (car (cdr response)))) ))
+
+(defun smtp-auth-digest-md5 (process)
+ "Login to server using the AUTH DIGEST-MD5 method."
+ (let (user realm response)
+ (smtp-send-command process "AUTH DIGEST-MD5")
+ (setq response (smtp-read-response process))
+ (if (or (null (car response))
+ (not (integerp (car response)))
+ (>= (car response) 400))
+ (throw 'done (car (cdr response))))
+ (if (string-match "^\\([^@]*\\)@\\([^@]*\\)"
+ smtp-authenticate-user)
+ (setq user (match-string 1 smtp-authenticate-user)
+ realm (match-string 2 smtp-authenticate-user))
+ (setq user smtp-authenticate-user
+ realm nil))
+ (smtp-send-command process
+ (base64-encode-string
+ (sasl-digest-md5-digest-response
+ (base64-decode-string
+ (substring (car (cdr response)) 4))
+ user
+ smtp-authenticate-passphrase
+ "smtp" smtp-server realm)
+ 'no-line-break))
+ (setq response (smtp-read-response process))
+ (if (or (null (car response))
+ (not (integerp (car response)))
+ (>= (car response) 400))
+ (throw 'done (car (cdr response))))
+ (smtp-send-command process "")))
(provide 'smtp)