Browse code
rfe12276: Handle SMTP servers which violate SMTP SASL AUTH protocol
Some SMTP servers (notably The Amazon SES SMTP endpoint
(email-smtp.us-east-1.amazonaws.com)) violate the protocol rules on the
first server response. Apparently other SMTP clients are tolerant of
this, so we try to be as well.
Change-Id: I5280fa6473e56b5c08188d2819db3271294bf62a
Showing 1 changed files
... | ... |
@@ -1,3 +1,9 @@ |
1 |
+#+(version= 8 2) |
|
2 |
+(sys:defpatch "smtp" 1 |
|
3 |
+ "v1: Handle SMTP servers which violate SMTP SASL AUTH protocol." |
|
4 |
+ :type :system |
|
5 |
+ :post-loadable t) |
|
6 |
+ |
|
1 | 7 |
#+(version= 8 1) |
2 | 8 |
(sys:defpatch "smtp" 1 |
3 | 9 |
"v1: add smtp support for ssl connections and STARTTLS negotiation." |
... | ... |
@@ -472,7 +478,8 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
472 | 478 |
(defun smtp-authenticate (sock server mechs login password) |
473 | 479 |
(let ((ctx (net.sasl:sasl-client-new "smtp" server |
474 | 480 |
:user login |
475 |
- :pass password))) |
|
481 |
+ :pass password)) |
|
482 |
+ (first-server-response t)) |
|
476 | 483 |
(multiple-value-bind (res selected-mech response) |
477 | 484 |
(net.sasl:sasl-client-start ctx mechs) |
478 | 485 |
(if (not (eq res :continue)) |
... | ... |
@@ -481,12 +488,30 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
481 | 488 |
(loop |
482 | 489 |
(response-case (sock msg) |
483 | 490 |
(3 ;; need more interaction |
484 |
- (multiple-value-setq (res response) |
|
485 |
- (net.sasl:sasl-step |
|
486 |
- ctx |
|
487 |
- (base64-string-to-usb8-array (subseq msg 4)))) |
|
488 |
- (smtp-command sock "~a" |
|
489 |
- (usb8-array-to-base64-string response nil))) |
|
491 |
+ ;; [rfe12276] Some SMTP servers (notably The Amazon SES |
|
492 |
+ ;; SMTP endpoint (email-smtp.us-east-1.amazonaws.com)) |
|
493 |
+ ;; violate the protocol rules on the first server response. |
|
494 |
+ ;; Apparently other SMTP clients are tolerant of this, so |
|
495 |
+ ;; we try to be as well. |
|
496 |
+ |
|
497 |
+ (multiple-value-bind (decoded-server-response err) |
|
498 |
+ (ignore-errors (base64-string-to-usb8-array (subseq msg 4))) |
|
499 |
+ (when (null decoded-server-response) |
|
500 |
+ (if* first-server-response |
|
501 |
+ then ;; Ignore initial server response if it's |
|
502 |
+ ;; bogus. |
|
503 |
+ ;;;(warn "Bogus server initial response: ~s~%" (subseq msg 4)) |
|
504 |
+ (setf first-server-response nil) |
|
505 |
+ else ;; We tolerate a bogus initial response, but no others |
|
506 |
+ (error "Failed to decode server response of ~s: ~a" |
|
507 |
+ (subseq msg 4) |
|
508 |
+ err))) |
|
509 |
+ |
|
510 |
+ (multiple-value-setq (res response) |
|
511 |
+ (net.sasl:sasl-step ctx decoded-server-response)) |
|
512 |
+ |
|
513 |
+ (smtp-command sock "~a" |
|
514 |
+ (usb8-array-to-base64-string response nil)))) |
|
490 | 515 |
(2 ;; server is satisfied. |
491 | 516 |
;; Make sure the auth process really completed |
492 | 517 |
(if (not (net.sasl:sasl-conn-auth-complete-p ctx)) |