Browse code
2008-09-16 Mikel Bancroft <mikel@gemini>
layer authored on 16/09/2008 23:22:14
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -1,3 +1,8 @@ |
1 |
+2008-09-16 Mikel Bancroft <mikel@gemini> |
|
2 |
+ |
|
3 |
+ * rfe8214 - smtp.cl: Add support for SSL connections to secure |
|
4 |
+ SMTP Servers. Also add support for STARTTLS negotiation. |
|
5 |
+ |
|
1 | 6 |
2008-05-21 Ahmon Dancy <dancy@dancy> |
2 | 7 |
|
3 | 8 |
* bug17849: Fix parse-mime-structure behavior when it |
... | ... |
@@ -1,4 +1,10 @@ |
1 |
-#+(version= 8 0) |
|
1 |
+#+(version= 8 1) |
|
2 |
+(sys:defpatch "smtp" 1 |
|
3 |
+ "v1: add smtp support for ssl connections and STARTTLS negotiation." |
|
4 |
+ :type :system |
|
5 |
+ :post-loadable t) |
|
6 |
+ |
|
7 |
+#+(version= 8 0) ;; not current with latest sources |
|
2 | 8 |
(sys:defpatch "smtp" 5 |
3 | 9 |
"v1: send-letter w/attachments; send-smtp* can take streams; |
4 | 10 |
v2: add :port argument to send-letter, send-smtp, send-smtp-auth; |
... | ... |
@@ -8,7 +14,7 @@ v5: send-smtp-1: New external-format keyword arg." |
8 | 14 |
:type :system |
9 | 15 |
:post-loadable t) |
10 | 16 |
|
11 |
-#+(version= 7 0) |
|
17 |
+#+(version= 7 0) ;; not current with latest sources |
|
12 | 18 |
(sys:defpatch "smtp" 5 |
13 | 19 |
"v2: send-letter w/attachments; send-smtp* can take streams; |
14 | 20 |
v3: add :port argument to send-letter, send-smtp, send-smtp-auth; |
... | ... |
@@ -22,7 +28,7 @@ v5: rm stray force-output of t; send-smtp-1: New external-format keyword arg." |
22 | 28 |
;; smtp.cl |
23 | 29 |
;; |
24 | 30 |
;; copyright (c) 1986-2002 Franz Inc, Berkeley, CA - All rights reserved. |
25 |
-;; copyright (c) 2002-2007 Franz Inc, Oakland, CA - All rights reserved. |
|
31 |
+;; copyright (c) 2002-2008 Franz Inc, Oakland, CA - All rights reserved. |
|
26 | 32 |
;; |
27 | 33 |
;; This code is free software; you can redistribute it and/or |
28 | 34 |
;; modify it under the terms of the version 2.1 of |
... | ... |
@@ -43,7 +49,7 @@ v5: rm stray force-output of t; send-smtp-1: New external-format keyword arg." |
43 | 49 |
;; Suite 330, Boston, MA 02111-1307 USA |
44 | 50 |
;; |
45 | 51 |
;; |
46 |
-;; $Id: smtp.cl,v 1.23 2007/04/17 22:01:42 layer Exp $ |
|
52 |
+;; $Id: smtp.cl,v 1.24 2008/09/16 23:22:14 layer Exp $ |
|
47 | 53 |
|
48 | 54 |
;; Description: |
49 | 55 |
;; send mail to an smtp server. See rfc821 for the spec. |
... | ... |
@@ -282,7 +288,7 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
282 | 288 |
;; |
283 | 289 |
|
284 | 290 |
(let ((sock (connect-to-mail-server server login password))) |
285 |
- |
|
291 |
+ |
|
286 | 292 |
(unwind-protect |
287 | 293 |
(progn |
288 | 294 |
|
... | ... |
@@ -359,17 +365,32 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
359 | 365 |
;; returning a socket connected to it and |
360 | 366 |
;; signaling an error if it can't be made. |
361 | 367 |
|
362 |
- (let ((port 25)) ;; standard SMTP port |
|
368 |
+ (let ((use-port 25) ;; standard SMTP port |
|
369 |
+ ssl-args |
|
370 |
+ ssl |
|
371 |
+ starttls) |
|
363 | 372 |
(if* (consp server) |
364 |
- then (setf port (cdr server)) |
|
365 |
- (setf server (car server)) |
|
373 |
+ then (if* (consp (cdr server)) |
|
374 |
+ then ;; long form |
|
375 |
+ (setq ssl-args (cdr server)) |
|
376 |
+ (setf server (car server)) |
|
377 |
+ (setq ssl (getf ssl-args :ssl)) |
|
378 |
+ (remf ssl-args :ssl) |
|
379 |
+ (setq use-port (or (getf ssl-args :port) |
|
380 |
+ (if ssl 465 use-port))) |
|
381 |
+ (remf ssl-args :port) |
|
382 |
+ (setq starttls (getf ssl-args :starttls)) |
|
383 |
+ (remf ssl-args :starttls) |
|
384 |
+ else ;; short form |
|
385 |
+ (setf use-port (cdr server)) |
|
386 |
+ (setf server (car server))) |
|
366 | 387 |
elseif (stringp server) |
367 | 388 |
then (multiple-value-bind (match whole m1 m2) |
368 | 389 |
(match-re "^([^:]+):([0-9]+)$" server) |
369 | 390 |
(declare (ignore whole)) |
370 | 391 |
(if* match |
371 | 392 |
then (setf server m1) |
372 |
- (setf port (parse-integer m2))))) |
|
393 |
+ (setf use-port (parse-integer m2))))) |
|
373 | 394 |
|
374 | 395 |
(let ((ipaddr (determine-mail-server server)) |
375 | 396 |
(sock) |
... | ... |
@@ -379,15 +400,18 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
379 | 400 |
then (error "Can't determine ip address for mail server ~s" server)) |
380 | 401 |
|
381 | 402 |
(setq sock (socket:make-socket :remote-host ipaddr |
382 |
- :remote-port port |
|
403 |
+ :remote-port use-port |
|
383 | 404 |
)) |
405 |
+ (when ssl |
|
406 |
+ (setq sock (apply #'acl-socket:make-ssl-client-stream sock ssl-args))) |
|
407 |
+ |
|
384 | 408 |
(unwind-protect |
385 |
- (progn |
|
409 |
+ (tagbody |
|
386 | 410 |
(response-case (sock msg) |
387 | 411 |
(2 ;; to the initial connect |
388 | 412 |
nil) |
389 | 413 |
(t (error "initial connect failed: ~s" msg))) |
390 |
- |
|
414 |
+ ehlo |
|
391 | 415 |
;; now that we're connected we can compute our hostname |
392 | 416 |
(let ((hostname (socket:ipaddr-to-hostname |
393 | 417 |
(socket:local-host sock)))) |
... | ... |
@@ -395,10 +419,19 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
395 | 419 |
then (setq hostname |
396 | 420 |
(format nil "[~a]" (socket:ipaddr-to-dotted |
397 | 421 |
(socket:local-host sock))))) |
398 |
- (let ((mechs (smtp-ehlo sock hostname))) |
|
399 |
- (if (and mechs login password) |
|
400 |
- (setf sock |
|
401 |
- (smtp-authenticate sock server mechs login password))))) |
|
422 |
+ (let ((mechs (smtp-ehlo sock hostname)) |
|
423 |
+ auth-mechs) |
|
424 |
+ (if* (and mechs starttls (member "STARTTLS" mechs :test #'string=)) |
|
425 |
+ then (smtp-send-recv (sock (format nil "STARTTLS") msg) |
|
426 |
+ (2 ;; ok |
|
427 |
+ (setq sock (acl-socket:make-ssl-client-stream sock :method :tlsv1))) |
|
428 |
+ (t (smtp-transaction-error))) |
|
429 |
+ (go ehlo) |
|
430 |
+ elseif (and mechs login password |
|
431 |
+ (setq auth-mechs (car (member "LOGIN" mechs |
|
432 |
+ :test #'(lambda (x y) (search x y)))))) |
|
433 |
+ then (setf sock |
|
434 |
+ (smtp-authenticate sock server auth-mechs login password))))) |
|
402 | 435 |
|
403 | 436 |
;; all is good |
404 | 437 |
(setq ok t)) |
... | ... |
@@ -420,11 +453,16 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
420 | 453 |
(smtp-send-recv (sock (format nil "EHLO ~A" our-name) msg) |
421 | 454 |
(2 ;; ok |
422 | 455 |
;; Collect the auth mechanisms. |
423 |
- (multiple-value-bind (found whole mechs) |
|
424 |
- (match-regexp "250[- ]AUTH \\(.*\\)" msg) |
|
425 |
- (declare (ignore whole)) |
|
426 |
- (if found |
|
427 |
- mechs))) |
|
456 |
+ (let (mechs) |
|
457 |
+ (multiple-value-bind (found whole mech) |
|
458 |
+ (match-re "250[- ]AUTH (.*)" msg) |
|
459 |
+ (declare (ignore whole)) |
|
460 |
+ (if found (push mech mechs))) |
|
461 |
+ (multiple-value-bind (found whole mech) |
|
462 |
+ (match-re "250[- ](STARTTLS)" msg) |
|
463 |
+ (declare (ignore whole)) |
|
464 |
+ (if found (push mech mechs))) |
|
465 |
+ mechs)) |
|
428 | 466 |
(t |
429 | 467 |
(smtp-send-recv (sock (format nil "HELO ~A" our-name) msg) |
430 | 468 |
(2 ;; ok |