Browse code
Merge branch 'master' of /repo/git.fromcvs/imap
Kevin Layer authored on 10/04/2009 03:20:06
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -10,6 +10,12 @@ |
10 | 10 |
:type :system |
11 | 11 |
:post-loadable t) |
12 | 12 |
|
13 |
+#+(version= 8 1) |
|
14 |
+(sys:defpatch "imap" 1 |
|
15 |
+ "v1: Add ssl/tls support for both imap/pop connections." |
|
16 |
+ :type :system |
|
17 |
+ :post-loadable t) |
|
18 |
+ |
|
13 | 19 |
;; -*- mode: common-lisp; package: net.post-office -*- |
14 | 20 |
;; |
15 | 21 |
;; imap.cl |
... | ... |
@@ -29,7 +35,7 @@ |
29 | 35 |
;; merchantability or fitness for a particular purpose. See the GNU |
30 | 36 |
;; Lesser General Public License for more details. |
31 | 37 |
;; |
32 |
-;; $Id: imap.cl,v 1.31 2007/04/17 22:01:42 layer Exp $ |
|
38 |
+;; $Id: imap.cl,v 1.32 2009/03/25 22:46:02 layer Exp $ |
|
33 | 39 |
|
34 | 40 |
;; Description: |
35 | 41 |
;;- This code in this file obeys the Lisp Coding Standard found in |
... | ... |
@@ -373,25 +379,70 @@ |
373 | 379 |
(setf (aref str 1) #\linefeed) |
374 | 380 |
str)) |
375 | 381 |
|
382 |
+;; returns values: socket starttls |
|
383 |
+;; server is a cons of the form: |
|
384 |
+;; (server-name &key (port 25) (ssl nil) (starttls nil) ...ssl-client-keywords...) |
|
385 |
+(defun connect-to-imap/pop-server (server-info server-type) |
|
386 |
+ (macrolet ((pop-keyword (k l) `(prog1 (getf ,l ,k) (remf ,l ,k))) |
|
387 |
+ (server-port (ssl type) `(cond ((eq ,type :imap) (if ,ssl 993 143)) |
|
388 |
+ ((eq ,type :pop) (if ,ssl 995 110))))) |
|
389 |
+ (let* ((server (car server-info)) |
|
390 |
+ (ssl-args (cdr server-info)) |
|
391 |
+ ssl port starttls sock) |
|
392 |
+ (setq ssl (pop-keyword :ssl ssl-args)) |
|
393 |
+ (setq port (or (pop-keyword :port ssl-args) (server-port ssl server-type))) |
|
394 |
+ (setq starttls (pop-keyword :starttls ssl-args)) |
|
395 |
+ (setq sock (socket:make-socket :remote-host server |
|
396 |
+ :remote-port port)) |
|
397 |
+ (when ssl |
|
398 |
+ (setq sock (apply #'socket:make-ssl-client-stream sock ssl-args))) |
|
399 |
+ |
|
400 |
+ (values sock starttls))) ) |
|
401 |
+ |
|
376 | 402 |
(defun make-imap-connection (host &key (port 143) |
377 | 403 |
user |
378 | 404 |
password |
379 | 405 |
(timeout 30)) |
380 |
- (let* ((sock (socket:make-socket :remote-host host |
|
381 |
- :remote-port port)) |
|
382 |
- (imap (make-instance 'imap-mailbox |
|
383 |
- :socket sock |
|
384 |
- :host host |
|
385 |
- :timeout timeout |
|
386 |
- :state :unauthorized))) |
|
406 |
+ (multiple-value-bind (sock starttls) |
|
407 |
+ (if (consp host) |
|
408 |
+ (connect-to-imap/pop-server host :imap) |
|
409 |
+ (socket:make-socket :remote-host host :remote-port port)) |
|
410 |
+ (let ((imap (make-instance 'imap-mailbox |
|
411 |
+ :socket sock |
|
412 |
+ :host host |
|
413 |
+ :timeout timeout |
|
414 |
+ :state :unauthorized))) |
|
387 | 415 |
|
388 | 416 |
(multiple-value-bind (tag cmd count extra comment) |
389 | 417 |
(get-and-parse-from-imap-server imap) |
390 |
- (declare (ignore cmd count extra)) |
|
418 |
+ (declare (ignorable cmd count extra)) |
|
391 | 419 |
(if* (not (eq :untagged tag)) |
392 | 420 |
then (po-error :error-response |
393 | 421 |
:server-string comment))) |
394 | 422 |
|
423 |
+ ; check for starttls negotiation |
|
424 |
+ (when starttls |
|
425 |
+ (let (capabilities) |
|
426 |
+ (send-command-get-results |
|
427 |
+ imap "CAPABILITY" |
|
428 |
+ #'(lambda (mb cmd count extra comment) |
|
429 |
+ (declare (ignorable mb cmd count extra)) |
|
430 |
+ (setq capabilities comment)) |
|
431 |
+ #'(lambda (mb cmd count extra comment) |
|
432 |
+ (check-for-success mb cmd count extra comment |
|
433 |
+ "CAPABILITY"))) |
|
434 |
+ (when (and capabilities (match-re "STARTTLS" capabilities :case-fold t |
|
435 |
+ :return nil)) |
|
436 |
+ ;; negotiate starttls |
|
437 |
+ (send-command-get-results imap "STARTTLS" |
|
438 |
+ #'handle-untagged-response |
|
439 |
+ #'(lambda (mb cmd count extra comment) |
|
440 |
+ (check-for-success mb cmd count extra comment |
|
441 |
+ "STARTTLS") |
|
442 |
+ (setf (post-office-socket mb) |
|
443 |
+ (socket:make-ssl-client-stream |
|
444 |
+ (post-office-socket mb) :method :tlsv1))))))) |
|
445 |
+ |
|
395 | 446 |
; now login |
396 | 447 |
(send-command-get-results imap |
397 | 448 |
(format nil "login ~a ~a" user password) |
... | ... |
@@ -410,7 +461,7 @@ |
410 | 461 |
|
411 | 462 |
|
412 | 463 |
|
413 |
- imap)) |
|
464 |
+ imap))) |
|
414 | 465 |
|
415 | 466 |
|
416 | 467 |
(defmethod close-connection ((mb imap-mailbox)) |
... | ... |
@@ -452,9 +503,11 @@ |
452 | 503 |
user |
453 | 504 |
password |
454 | 505 |
(timeout 30)) |
455 |
- (let* ((sock (socket:make-socket :remote-host host |
|
456 |
- :remote-port port)) |
|
457 |
- (pop (make-instance 'pop-mailbox |
|
506 |
+ (multiple-value-bind (sock starttls) |
|
507 |
+ (if (consp host) |
|
508 |
+ (connect-to-imap/pop-server host :pop) |
|
509 |
+ (socket:make-socket :remote-host host :remote-port port)) |
|
510 |
+ (let ((pop (make-instance 'pop-mailbox |
|
458 | 511 |
:socket sock |
459 | 512 |
:host host |
460 | 513 |
:timeout timeout |
... | ... |
@@ -467,6 +520,15 @@ |
467 | 520 |
:format-control |
468 | 521 |
"unexpected line from server after connect"))) |
469 | 522 |
|
523 |
+ ; check for starttls negotiation |
|
524 |
+ (when starttls |
|
525 |
+ (let ((capabilities (send-pop-command-get-results pop "capa" t))) |
|
526 |
+ (when (and capabilities (match-re "STLS" capabilities :case-fold t |
|
527 |
+ :return nil)) |
|
528 |
+ (send-pop-command-get-results pop "STLS") |
|
529 |
+ (setf (post-office-socket pop) (socket:make-ssl-client-stream |
|
530 |
+ (post-office-socket pop) :method :tlsv1))))) |
|
531 |
+ |
|
470 | 532 |
; now login |
471 | 533 |
(send-pop-command-get-results pop (format nil "user ~a" user)) |
472 | 534 |
(send-pop-command-get-results pop (format nil "pass ~a" password)) |
... | ... |
@@ -476,7 +538,7 @@ |
476 | 538 |
|
477 | 539 |
|
478 | 540 |
|
479 |
- pop)) |
|
541 |
+ pop))) |
|
480 | 542 |
|
481 | 543 |
|
482 | 544 |
(defmethod send-command-get-results ((mb imap-mailbox) |