Pop3 Over SSL/TLS in Common Lisp -


can point me common lisp library (specifically sbcl on linux) pulling pop3 email on ssl/tls? cl-pop seems fine, doesn't seem support ssl , i'm not sure how wrap cl+ssl (assuming it's possible). have suggestions short of rolling own?

you can redefine usocket-connect function yield stream type returned ssl library. can define methods send , receive data on stream using regular strings (the ssl library supports binary default, cl-pop assumes strings can sent). you'll need depend on flexi-streams library convert between text , binary. (ql:quickload :flexi-streams)

the following code make change , define needed methods. since usocket-connect replaced, provide :unencrypted keyword create regular socket.

the code made more efficient.

the string-to-octets , octets-to-string functions support :external-format argument allows them encode/decode many character encoding schemes, including utf-8, iso-8859-*, , others. full list of supported encodings documented here. didn't use :external-format in answer, defaults :latin-1.

the code written against old version of cl+ssl seems have been installed on system debian package manager. current versions of make-ssl-client-stream , make-ssl-server-stream support several more keyword arguments supported version on machine. doesn't matter, however, because cl-pop use none of these keyword arguments.

(defpackage :ssl-pop   (:use :common-lisp :cl+ssl :usocket :flexi-streams))  (in-package :ssl-pop)      (let ((old-connect (symbol-function 'socket-connect)))   (defun socket-connect (host port &key (protocol :stream)                          external-format certificate key crypto-password                          (clientp t) close-callback unencrypted                          (unwrap-streams-p t) crypto-hostname                          (element-type '(unsigned-byte 8)) timeout deadline                          (nodelay t nodelay-specified) local-host                          local-port)     (let* ((old-connect-args             `(,host ,port :protocol ,protocol                     :element-type ,element-type                     :timeout ,timeout :deadline ,deadline                     ,@(if nodelay-specified                           `(:nodelay ,nodelay))                     :local-host ,local-host                     :local-port ,local-port))            (plain-socket (apply old-connect old-connect-args)))       (if unencrypted           plain-socket           (let ((socket-stream (socket-stream plain-socket)))             (assert (streamp socket-stream))             (if clientp                 (make-ssl-client-stream socket-stream                                         :external-format external-format                                         :certificate certificate                                         :key key                                          :close-callback close-callback)                 (make-ssl-server-stream socket-stream                                         :external-format external-format                                         :certificate certificate                                         :key key)))))))  (defmethod socket-stream ((object cl+ssl::ssl-stream))   object)  (defmethod socket-receive ((socket cl+ssl::ssl-stream) buffer length                            &key (element-type '(unsigned-byte 8)))   (let ((buffer (or buffer (make-array length                                        :element-type element-type))))     (loop ix 0 below length                   (restart-case              (setf (aref buffer ix) (read-byte socket))            (thats-ok () :report "return bytes read"                 (return-from socket-receive (subseq buffer 0 ix)))))     buffer))  (defmethod socket-send ((socket cl+ssl::ssl-stream) buffer length                         &key host port)   (declare (ignore host port)) ;; they're udp   (loop byte across buffer        (write-byte byte socket)))  (defmethod sb-gray:stream-read-line ((socket cl+ssl::ssl-stream))   (let ((result (make-array 0 :adjustable t :fill-pointer t                             :element-type '(unsigned-byte 8))))     (loop next-byte = (read-byte socket)           until (and (>= (length result) 1)                      (= next-byte 10)                      (= (aref result (- (length result) 1)) 13))                   (vector-push-extend next-byte result))     (octets-to-string      (concatenate 'vector                   (subseq result 0 (- (length result) 1))))))  (defmethod trivial-gray-streams:stream-write-sequence     ((stream cl+ssl::ssl-stream) (sequence string) start end      &key &allow-other-keys)   (trivial-gray-streams:stream-write-sequence stream                                               (string-to-octets sequence)                                               start end))  (defmethod sb-gray:stream-write-char ((stream cl+ssl::ssl-stream)                                       (char character))   (let ((string (make-string 1 :initial-element char)))     (write-sequence (string-to-octets string) stream)))  (defmethod socket-close ((socket cl+ssl::ssl-stream))   (close socket)) 

Comments

Popular posts from this blog

How to provide Authorization & Authentication using Asp.net, C#? -

toolbar - How to add link to user registration inside toobar in admin joomla 3 custom component -

How to use Authorization & Authentication in Asp.net, C#? -