From dlichteblau at common-lisp.net Wed Nov 9 22:10:45 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 9 Nov 2005 23:10:45 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: Module imported: cl+ssl Message-ID: <20051109221045.52ABB8855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/home/dlichteblau/neu/cl+ssl Log Message: initial import Status: Vendor Tag: david Release Tags: start I cl+ssl/CVS N cl+ssl/LICENSE N cl+ssl/Makefile N cl+ssl/bio.lisp N cl+ssl/cl+ssl.asd N cl+ssl/conditions.lisp N cl+ssl/ffi.lisp N cl+ssl/index.css N cl+ssl/index.html N cl+ssl/package.lisp N cl+ssl/reload.lisp N cl+ssl/streams.lisp N cl+ssl/test.lisp No conflicts created by this import Date: Wed Nov 9 23:10:44 2005 Author: dlichteblau New module cl+ssl added From dlichteblau at common-lisp.net Wed Nov 9 22:11:01 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 9 Nov 2005 23:11:01 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: Module imported: trivial-gray-streams Message-ID: <20051109221101.79BA88855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-gray-streams In directory common-lisp.net:/home/dlichteblau/neu/trivial-gray-streams Log Message: initial import Status: Vendor Tag: david Release Tags: start I trivial-gray-streams/CVS N trivial-gray-streams/Makefile N trivial-gray-streams/README N trivial-gray-streams/mixin.lisp N trivial-gray-streams/package.lisp N trivial-gray-streams/trivial-gray-streams.asd No conflicts created by this import Date: Wed Nov 9 23:11:00 2005 Author: dlichteblau New module trivial-gray-streams added From dlichteblau at common-lisp.net Wed Nov 9 22:11:16 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 9 Nov 2005 23:11:16 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: Module imported: trivial-https Message-ID: <20051109221116.F09E78855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-https In directory common-lisp.net:/home/dlichteblau/neu/trivial-https Log Message: initial import Status: Vendor Tag: david Release Tags: start I trivial-https/CVS N trivial-https/LICENSE N trivial-https/README N trivial-https/trivial-https.asd N trivial-https/trivial-https.lisp No conflicts created by this import Date: Wed Nov 9 23:11:16 2005 Author: dlichteblau New module trivial-https added From dlichteblau at common-lisp.net Wed Nov 16 17:07:58 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 16 Nov 2005 18:07:58 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: cl+ssl/ffi.lisp cl+ssl/index.html cl+ssl/package.lisp cl+ssl/reload.lisp Message-ID: <20051116170758.60779880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/tmp/cvs-serv21049 Modified Files: ffi.lisp index.html package.lisp reload.lisp Log Message: reload function Date: Wed Nov 16 18:07:55 2005 Author: dlichteblau Index: cl+ssl/ffi.lisp diff -u cl+ssl/ffi.lisp:1.1.1.1 cl+ssl/ffi.lisp:1.2 --- cl+ssl/ffi.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/ffi.lisp Wed Nov 16 18:07:53 2005 @@ -232,3 +232,8 @@ (initialize method)) (unless *bio-lisp-method* (setf *bio-lisp-method* (make-bio-lisp-method)))) + +(defun reload () + (cffi:load-foreign-library cl+ssl-system:*libssl-pathname*) + (setf *ssl-global-context* nil) + (setf *ssl-global-method* nil)) Index: cl+ssl/index.html diff -u cl+ssl/index.html:1.1.1.1 cl+ssl/index.html:1.2 --- cl+ssl/index.html:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/index.html Wed Nov 16 18:07:53 2005 @@ -113,12 +113,16 @@ reads and writes to this server stream will be pushed through the OpenSSL library. The SSL connection can be closed using the standard close function. -

-

certificate is the path to a file containing the PEM-encoded certificate for your server. key is the path to the PEM-encoded key for the server, which must not be associated with a passphrase. +

+

+

Function CL+SSL:RELOAD ()
+ Reload libssl. Call this function after restarting a Lisp + core with CL+SSL dumped into it on Lisp implementations that do + not reload shared libraries automatically.

Portability

Index: cl+ssl/package.lisp diff -u cl+ssl/package.lisp:1.1.1.1 cl+ssl/package.lisp:1.2 --- cl+ssl/package.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/package.lisp Wed Nov 16 18:07:53 2005 @@ -9,5 +9,6 @@ (defpackage :cl+ssl (:use :common-lisp :trivial-gray-streams) (:export #:ensure-initialized + #:reload #:make-ssl-client-stream #:make-ssl-server-stream)) Index: cl+ssl/reload.lisp diff -u cl+ssl/reload.lisp:1.1.1.1 cl+ssl/reload.lisp:1.2 --- cl+ssl/reload.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/reload.lisp Wed Nov 16 18:07:53 2005 @@ -10,8 +10,8 @@ ;;; the actual sources ;;; - before ssl.lisp is loaded, which needs the library at compilation ;;; time on some implemenations -;;; - but not every time ssl.lisp is re-loaded as would happen if we -;;; put this directly into ssl.lisp +;;; - but not every time ffi.lisp is re-loaded as would happen if we +;;; put this directly into ffi.lisp (in-package :cl+ssl-system) (cffi:load-foreign-library *libssl-pathname*) From dlichteblau at common-lisp.net Wed Nov 16 17:08:26 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 16 Nov 2005 18:08:26 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: trivial-https/trivial-https.lisp Message-ID: <20051116170826.8551B880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-https In directory common-lisp.net:/tmp/cvs-serv21082 Modified Files: trivial-https.lisp Log Message: use octet streams for https Date: Wed Nov 16 18:08:25 2005 Author: dlichteblau Index: trivial-https/trivial-https.lisp diff -u trivial-https/trivial-https.lisp:1.1.1.1 trivial-https/trivial-https.lisp:1.2 --- trivial-https/trivial-https.lisp:1.1.1.1 Wed Nov 9 23:11:16 2005 +++ trivial-https/trivial-https.lisp Wed Nov 16 18:08:25 2005 @@ -50,9 +50,11 @@ (defun http-get (url &optional headers) (let* ((host (url-host url)) (port (url-port url)) - (stream (open-stream host port))) - (when (equal (url-scheme url) "https") - (setf stream (cl+ssl:make-ssl-client-stream stream))) + (stream + (if (equal (url-scheme url) "https") + (cl+ssl:make-ssl-client-stream + (open-stream host port :element-type '(unsigned-byte 8))) + (open-stream host port)))) (format stream "GET ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~A" url +crlf+ host +crlf+ +crlf+) (loop for (name . value) in headers do @@ -67,9 +69,11 @@ (defun http-post (url content-type content) (let* ((host (url-host url)) (port (url-port url)) - (stream (open-stream host port))) - (when (equal (url-scheme url) "https") - (setf stream (cl+ssl:make-ssl-client-stream stream))) + (stream + (if (equal (url-scheme url) "https") + (cl+ssl:make-ssl-client-stream + (open-stream host port :element-type '(unsigned-byte 8))) + (open-stream host port)))) (format stream "POST ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~AContent-Type: ~A~AContent-Length: ~D~A~A~A" url +crlf+ host +crlf+ +crlf+ content-type +crlf+ (length content) +crlf+ +crlf+ content) (force-output stream) (list From dlichteblau at common-lisp.net Wed Nov 16 17:13:18 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Wed, 16 Nov 2005 18:13:18 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: cl+ssl/streams.lisp Message-ID: <20051116171318.B4666880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/tmp/cvs-serv21118 Modified Files: streams.lisp Log Message: stream-write-sequence fix, thanks to erik enge Date: Wed Nov 16 18:13:17 2005 Author: dlichteblau Index: cl+ssl/streams.lisp diff -u cl+ssl/streams.lisp:1.1.1.1 cl+ssl/streams.lisp:1.2 --- cl+ssl/streams.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/streams.lisp Wed Nov 16 18:13:17 2005 @@ -74,8 +74,9 @@ (defmethod stream-write-sequence ((stream ssl-stream) (thing array) - &optional (start 0) (end (length thing))) + &optional (start 0) end) (check-type thing (simple-array (unsigned-byte 8) (*))) + (setf end (or end (length thing))) (let ((buf (ssl-stream-io-buffer stream)) (handle (ssl-stream-handle stream)) (socket (ssl-stream-socket stream)) @@ -87,7 +88,8 @@ ;; argument to WITH-POINTER-TO-VECTOR-DATA, so we need to copy all data: (replace buf thing :start2 start :end2 end) (cffi-sys::with-pointer-to-vector-data (ptr buf) - (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr length)))) + (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr length))) + thing) ;;; minimal character stream implementation From dlichteblau at common-lisp.net Fri Nov 25 20:08:45 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 21:08:45 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: trivial-gray-streams/README trivial-gray-streams/mixin.lisp trivial-gray-streams/package.lisp Message-ID: <20051125200845.C7D288855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-gray-streams In directory common-lisp.net:/tmp/cvs-serv29967 Modified Files: README mixin.lisp package.lisp Log Message: read-/write-sequence handling komplett umgestrickt Date: Fri Nov 25 21:08:44 2005 Author: dlichteblau Index: trivial-gray-streams/README diff -u trivial-gray-streams/README:1.1.1.1 trivial-gray-streams/README:1.2 --- trivial-gray-streams/README:1.1.1.1 Wed Nov 9 23:11:00 2005 +++ trivial-gray-streams/README Fri Nov 25 21:08:44 2005 @@ -14,7 +14,10 @@ implementation-specific package you would have to use otherwise to get at gray stream symbols. 2. For STREAM-READ-SEQUENCE and STREAM-WRITE-SEQUENCE, notice that we - use two &OPTIONAL arguments. -3. In order for (2) to work on Lispworks, CLISP, and OpenMCL, make sure to - subclass all your stream classes from TRIVIAL-GRAY-STREAM-MIXIN if you - intend to define methods on those two generic functions. + use two required arguments and allow additional keyword arguments. + So the lambda list when defining a method on either function should look + like this: + (stream sequence start end &key) +3. In order for (2) to work on all Lisps, make sure to subclass all your + stream classes from TRIVIAL-GRAY-STREAM-MIXIN if you intend to define + methods on those two generic functions. Index: trivial-gray-streams/mixin.lisp diff -u trivial-gray-streams/mixin.lisp:1.1.1.1 trivial-gray-streams/mixin.lisp:1.2 --- trivial-gray-streams/mixin.lisp:1.1.1.1 Wed Nov 9 23:11:00 2005 +++ trivial-gray-streams/mixin.lisp Fri Nov 25 21:08:44 2005 @@ -2,37 +2,55 @@ (defclass trivial-gray-stream-mixin () ()) -#+lispworks +(defgeneric stream-read-sequence + (stream sequence start end &key &allow-other-keys)) +(defgeneric stream-write-sequence + (stream sequence start end &key &allow-other-keys)) + +(defmethod stream-write-string + ((stream trivial-gray-stream-mixin) seq &optional start end) + (stream-write-sequence stream seq (or start 0) (or end (length seq)))) + +#+allegro +(progn + (defmethod excl:stream-read-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-read-sequence s seq (or start 0) (or end (length seq)))) + (defmethod stream:stream-write-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-write-sequence s seq (or start 0) (or end (length seq))))) + +#+cmu (progn - (defgeneric stream-read-sequence (stream sequence &optional start end)) - (defgeneric stream-write-sequence (stream sequence &optional start end)) + (defmethod ext:stream-read-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-read-sequence s seq (or start 0) (or end (length seq)))) + (defmethod ext:stream-write-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-write-sequence s seq (or start 0) (or end (length seq))))) +#+lispworks +(progn (defmethod stream:stream-read-sequence ((s trivial-gray-stream-mixin) seq start end) - (stream-read-sequence seq start end)) + (stream-read-sequence s seq start end)) (defmethod stream:stream-write-sequence ((s trivial-gray-stream-mixin) seq start end) - (stream-read-sequence seq start end))) + (stream-write-sequence s seq start end))) #+openmcl (progn - (defgeneric stream-read-sequence (stream sequence &optional start end)) - (defgeneric stream-write-sequence (stream sequence &optional start end)) - (defmethod ccl:stream-read-vector ((s trivial-gray-stream-mixin) seq start end) - (stream-read-sequence seq start end)) + (stream-read-sequence s seq start end)) (defmethod ccl:stream-write-vector ((s trivial-gray-stream-mixin) seq start end) - (stream-write-sequence seq start end))) + (stream-write-sequence s seq start end))) #+clisp (progn - (defgeneric stream-read-sequence (stream sequence &optional start end)) - (defgeneric stream-write-sequence (stream sequence &optional start end)) - (defmethod gray:stream-read-byte-sequence ((s trivial-gray-stream-mixin) seq @@ -41,7 +59,7 @@ (error "this stream does not support the NO-HANG argument")) (when interactive (error "this stream does not support the INTERACTIVE argument")) - (stream-read-sequence seq start end)) + (stream-read-sequence s seq start end)) (defmethod gray:stream-write-byte-sequence ((s trivial-gray-stream-mixin) @@ -51,4 +69,19 @@ (error "this stream does not support the NO-HANG argument")) (when interactive (error "this stream does not support the INTERACTIVE argument")) - (stream-write-sequence seq start end))) + (stream-write-sequence s seq start end))) + +#+sbcl +(progn + (defmethod sb-gray:stream-read-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-read-sequence s seq (or start 0) (or end (length seq)))) + (defmethod sb-gray:stream-write-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-write-sequence s seq (or start 0) (or end (length seq)))) + ;; SBCL extension: + (defmethod sb-gray:stream-line-length ((stream trivial-gray-stream-mixin)) + 80) + ;; SBCL should provide this default method, but doesn't? + (defmethod stream-terpri ((stream trivial-gray-stream-mixin)) + (write-char #\newline stream))) Index: trivial-gray-streams/package.lisp diff -u trivial-gray-streams/package.lisp:1.1.1.1 trivial-gray-streams/package.lisp:1.2 --- trivial-gray-streams/package.lisp:1.1.1.1 Wed Nov 9 23:11:00 2005 +++ trivial-gray-streams/package.lisp Fri Nov 25 21:08:44 2005 @@ -30,12 +30,6 @@ #+openmcl :ccl #+lispworks :stream #-(or sbcl allegro cmu clisp openmcl lispworks) ... - - #-(or lispworks clisp openmcl) - #:stream-read-sequence - #-(or lispworks clisp openmcl) - #:stream-write-sequence - , at common-symbols) (:export #:trivial-gray-stream-mixin #:stream-read-sequence From dlichteblau at common-lisp.net Fri Nov 25 20:13:36 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 21:13:36 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: trivial-https/trivial-https.lisp Message-ID: <20051125201336.DD3438855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-https In directory common-lisp.net:/tmp/cvs-serv30023 Modified Files: trivial-https.lisp Log Message: upgrade to current cl+ssl Date: Fri Nov 25 21:13:36 2005 Author: dlichteblau Index: trivial-https/trivial-https.lisp diff -u trivial-https/trivial-https.lisp:1.2 trivial-https/trivial-https.lisp:1.3 --- trivial-https/trivial-https.lisp:1.2 Wed Nov 16 18:08:25 2005 +++ trivial-https/trivial-https.lisp Fri Nov 25 21:13:36 2005 @@ -53,7 +53,8 @@ (stream (if (equal (url-scheme url) "https") (cl+ssl:make-ssl-client-stream - (open-stream host port :element-type '(unsigned-byte 8))) + (open-stream host port :element-type '(unsigned-byte 8)) + :external-format :iso-8859-1) (open-stream host port)))) (format stream "GET ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~A" url +crlf+ host +crlf+ +crlf+) @@ -72,7 +73,8 @@ (stream (if (equal (url-scheme url) "https") (cl+ssl:make-ssl-client-stream - (open-stream host port :element-type '(unsigned-byte 8))) + (open-stream host port :element-type '(unsigned-byte 8)) + :external-format :iso-8859-1) (open-stream host port)))) (format stream "POST ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~AContent-Type: ~A~AContent-Length: ~D~A~A~A" url +crlf+ host +crlf+ +crlf+ content-type +crlf+ (length content) +crlf+ +crlf+ content) (force-output stream) From dlichteblau at common-lisp.net Fri Nov 25 20:14:06 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 21:14:06 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: cl+ssl/bio.lisp cl+ssl/cl+ssl.asd cl+ssl/ffi.lisp cl+ssl/index.html cl+ssl/streams.lisp cl+ssl/test.lisp Message-ID: <20051125201406.1D7468855E@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/tmp/cvs-serv30043 Modified Files: bio.lisp cl+ssl.asd ffi.lisp index.html streams.lisp test.lisp Log Message: * flexi-streams benutzen * buffering Date: Fri Nov 25 21:14:04 2005 Author: dlichteblau Index: cl+ssl/bio.lisp diff -u cl+ssl/bio.lisp:1.1.1.1 cl+ssl/bio.lisp:1.2 --- cl+ssl/bio.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/bio.lisp Fri Nov 25 21:14:04 2005 @@ -85,19 +85,18 @@ +BIO_FLAGS_READ+ +BIO_FLAGS_SHOULD_RETRY+))) -;; not sure whether we should block or not... -(defvar *block* t) - (cffi:defcallback lisp-read :int ((bio :pointer) (buf :pointer) (n :int)) bio buf n (let ((i 0)) (handler-case (unless (or (cffi:null-ptr-p buf) (null n)) (clear-retry-flags bio) - (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*)) - (incf i) + (when (or *blockp* (listen *socket*)) + (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*)) + (incf i)) (loop - while (and (< i n) (or *block* (listen *socket*))) + while (and (< i n) + (or (null *partial-read-p*) (listen *socket*))) do (setf (cffi:mem-ref buf :unsigned-char i) (read-byte *socket*)) (incf i)) Index: cl+ssl/cl+ssl.asd diff -u cl+ssl/cl+ssl.asd:1.1.1.1 cl+ssl/cl+ssl.asd:1.2 --- cl+ssl/cl+ssl.asd:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/cl+ssl.asd Fri Nov 25 21:14:04 2005 @@ -15,7 +15,7 @@ (defparameter *libssl-pathname* "/usr/lib/libssl.so") (defsystem :cl+ssl - :depends-on (:cffi :trivial-gray-streams) + :depends-on (:cffi :trivial-gray-streams :flexi-streams) :serial t :components ((:file "reload") Index: cl+ssl/ffi.lisp diff -u cl+ssl/ffi.lisp:1.2 cl+ssl/ffi.lisp:1.3 --- cl+ssl/ffi.lisp:1.2 Wed Nov 16 18:07:53 2005 +++ cl+ssl/ffi.lisp Fri Nov 25 21:14:04 2005 @@ -16,6 +16,9 @@ (defvar *ssl-global-method* nil) (defvar *bio-lisp-method* nil) +(defparameter *blockp* t) +(defparameter *partial-read-p* nil) + (defun ssl-initialized-p () (and *ssl-global-context* *ssl-global-method*)) @@ -29,6 +32,12 @@ (defconstant +ssl-filetype-default+ 3) (defconstant +SSL_CTRL_SET_SESS_CACHE_MODE+ 44) + + +;;; Misc +;;; +(defmacro while (cond &body body) + `(do () ((not ,cond)) , at body)) ;;; Function definitions Index: cl+ssl/index.html diff -u cl+ssl/index.html:1.2 cl+ssl/index.html:1.3 --- cl+ssl/index.html:1.2 Wed Nov 16 18:07:53 2005 +++ cl+ssl/index.html Fri Nov 25 21:14:04 2005 @@ -16,6 +16,9 @@

Download

+

+ Anonymous CVS (browse): +

$ export CVSROOT=:pserver:anonymous at common-lisp.net:/project/cl-plus-ssl/cvsroot
 $ cvs login
 password: anonymous
@@ -76,13 +79,13 @@
       
         CL+SSL
         CFFI
-        gray, non-buffering
+        gray1, buffering output
         yes
       
       
         CL-SSL
         UFFI
-        gray, buffering [part of ACL-COMPAT]
+        gray, buffering I/O [part of ACL-COMPAT]
         no
       
       
@@ -92,6 +95,11 @@
         no
       
     
+    

+ 1 Character I/O and external formats in CL+SSL + are provided + using flexi-streams. +

API functions

@@ -102,13 +110,20 @@ load-op'ing the system.

-

Function CL+SSL:MAKE-SSL-CLIENT-STREAM (stream)
+
Function CL+SSL:MAKE-SSL-CLIENT-STREAM (stream &key external-format)
Return an SSL stream for the client socket stream. All reads and writes to this SSL stream will be pushed through the SSL connection can be closed using the standard close function.

-

Function CL+SSL:MAKE-SSL-SERVER-STREAM (stream &key certificate key)
+ If external-format is nil (the default), a plain + (unsigned-byte 8) SSL stream is returned. With a + non-null external-format, a flexi-stream capable of + character I/O will be returned instead, with the specified value + as its initial external format. +

+

+

Function CL+SSL:MAKE-SSL-SERVER-STREAM (stream &key external-format certificate key)
Return an SSL stream for the server socket stream. All reads and writes to this server stream will be pushed through the OpenSSL library. The SSL connection can be closed using the @@ -116,11 +131,11 @@ certificate is the path to a file containing the PEM-encoded certificate for your server. key is the path to the PEM-encoded key for the server, which must not be associated with a - passphrase. + passphrase. See above for external-format handling.

Function CL+SSL:RELOAD ()
- Reload libssl. Call this function after restarting a Lisp + Reload libssl. Call this function after restarting a Lisp core with CL+SSL dumped into it on Lisp implementations that do not reload shared libraries automatically.

@@ -165,13 +180,7 @@

TODO

  • Profile and optimize if needed. (CLISP?)
  • -
  • Implement remaining gray streams methods.
  • -
  • Add external format support on Unicode-capable Lisps.
  • -
-

Maybe

-
    -
  • Add buffering to gray streams layer?
  • -
  • Add simple-streams layer instead of gray streams?
  • +
  • CNAME checking!
@@ -185,7 +194,7 @@

- README + README

@@ -197,7 +206,7 @@

- README + README

Index: cl+ssl/streams.lisp diff -u cl+ssl/streams.lisp:1.2 cl+ssl/streams.lisp:1.3 --- cl+ssl/streams.lisp:1.2 Wed Nov 16 18:13:17 2005 +++ cl+ssl/streams.lisp Fri Nov 25 21:14:04 2005 @@ -13,9 +13,7 @@ (defclass ssl-stream (fundamental-binary-input-stream - fundamental-binary-output-stream - fundamental-character-input-stream - fundamental-character-output-stream + fundamental-binary-output-stream trivial-gray-stream-mixin) ((ssl-stream-socket :initarg :socket @@ -23,9 +21,18 @@ (handle :initform nil :accessor ssl-stream-handle) - (io-buffer + (output-buffer :initform (cffi-sys::make-shareable-byte-vector +initial-buffer-size+) - :accessor ssl-stream-io-buffer))) + :accessor ssl-stream-output-buffer) + (output-pointer + :initform 0 + :accessor ssl-stream-output-pointer) + (input-buffer + :initform (cffi-sys::make-shareable-byte-vector +initial-buffer-size+) + :accessor ssl-stream-input-buffer) + (peeked-byte + :initform nil + :accessor ssl-stream-peeked-byte))) (defmethod print-object ((object ssl-stream) stream) (print-unreadable-object (object stream :type t) @@ -44,104 +51,124 @@ ;;; (defmethod close ((stream ssl-stream) &key abort) (declare (ignore abort)) + (force-output stream) (ssl-free (ssl-stream-handle stream)) + (setf (ssl-stream-handle stream) nil) (close (ssl-stream-socket stream))) +(defmethod open-stream-p ((stream ssl-stream)) + (and (ssl-stream-handle stream) t)) + +(defmethod stream-listen ((stream ssl-stream)) + (or (ssl-stream-peeked-byte stream) + (setf (ssl-stream-peeked-byte stream) + (let* ((*blockp* nil) + (b (stream-read-byte stream))) + (if (eql b :eof) nil b))))) + (defmethod stream-read-byte ((stream ssl-stream)) - (let ((buf (ssl-stream-io-buffer stream))) - (handler-case - (cffi-sys::with-pointer-to-vector-data (ptr buf) - (ensure-ssl-funcall (ssl-stream-socket stream) - (ssl-stream-handle stream) - #'ssl-read - 5.5 - (ssl-stream-handle stream) - ptr - 1) - (elt buf 0)) - ;; SSL_read returns 0 on end-of-file - (ssl-error-zero-return () - :eof)))) + (or (ssl-stream-peeked-byte stream) + (let ((buf (ssl-stream-input-buffer stream))) + (handler-case + (cffi-sys::with-pointer-to-vector-data (ptr buf) + (ensure-ssl-funcall (ssl-stream-socket stream) + (ssl-stream-handle stream) + #'ssl-read + 5.5 + (ssl-stream-handle stream) + ptr + 1) + (elt buf 0)) + (ssl-error-zero-return () ;SSL_read returns 0 on end-of-file + :eof))))) + +(defmethod stream-read-sequence ((stream ssl-stream) thing start end &key) + (check-type thing (simple-array (unsigned-byte 8) (*))) + (when (and (< start end) (ssl-stream-peeked-byte stream)) + (setf (elt thing start) (ssl-stream-peeked-byte stream)) + (setf (ssl-stream-peeked-byte stream) nil) + (incf start)) + (let ((buf (ssl-stream-input-buffer stream))) + (loop + for length = (min (- end start) (length buf)) + while (plusp length) + do + (handler-case + (cffi-sys::with-pointer-to-vector-data (ptr buf) + (ensure-ssl-funcall (ssl-stream-socket stream) + (ssl-stream-handle stream) + #'ssl-read + 5.5 + (ssl-stream-handle stream) + ptr + length) + (replace thing buf :start1 start :end1 (+ start length)) + (incf start length)) + (ssl-error-zero-return () ;SSL_read returns 0 on end-of-file + (return)))) + start)) (defmethod stream-write-byte ((stream ssl-stream) b) - (let ((buf (ssl-stream-io-buffer stream)) - (handle (ssl-stream-handle stream)) - (socket (ssl-stream-socket stream))) - (setf (elt buf 0) b) - (cffi-sys::with-pointer-to-vector-data (ptr buf) - (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr 1))) + (let ((buf (ssl-stream-output-buffer stream))) + (when (eql (length buf) (ssl-stream-output-pointer stream)) + (force-output stream)) + (setf (elt buf (ssl-stream-output-pointer stream)) b) + (incf (ssl-stream-output-pointer stream))) b) -(defmethod stream-write-sequence - ((stream ssl-stream) (thing array) - &optional (start 0) end) +(defmethod stream-write-sequence ((stream ssl-stream) thing start end &key) (check-type thing (simple-array (unsigned-byte 8) (*))) - (setf end (or end (length thing))) - (let ((buf (ssl-stream-io-buffer stream)) - (handle (ssl-stream-handle stream)) - (socket (ssl-stream-socket stream)) - (length (- end start))) - (when (> length (length buf)) - (setf buf (cffi-sys::make-shareable-byte-vector (- end start))) - (setf (ssl-stream-io-buffer stream) buf)) - ;; unfortunately, we cannot count on being able to use THING as an - ;; argument to WITH-POINTER-TO-VECTOR-DATA, so we need to copy all data: - (replace buf thing :start2 start :end2 end) - (cffi-sys::with-pointer-to-vector-data (ptr buf) - (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr length))) + (let ((buf (ssl-stream-output-buffer stream)) + (socket (ssl-stream-socket stream))) + (when (> (+ (- end start) (ssl-stream-output-pointer stream)) (length buf)) + ;; not enough space left? flush buffer. + (force-output stream) + ;; still doesn't fit? + (while (> (- end start) (length buf)) + (replace buf thing :start2 start) + (incf start (length buf)) + (setf (ssl-stream-output-pointer stream) (length buf)) + (force-output stream))) + (replace buf thing + :start1 (ssl-stream-output-pointer stream) + :start2 start + :end2 end) + (incf (ssl-stream-output-pointer stream) (- end start))) thing) +(defmethod stream-finish-output ((stream ssl-stream)) + (stream-force-output stream)) -;;; minimal character stream implementation -;;; no support for external formats, no support for unread-char -;;; -(defmethod stream-read-char ((stream ssl-stream)) - (let ((b (stream-read-byte stream))) - (if (eql b :eof) - :eof - (code-char b)))) - -(defmethod stream-write-char ((stream ssl-stream) char) - (stream-write-byte stream (char-code char)) - char) - -(defmethod stream-write-sequence - ((stream ssl-stream) (thing string) &optional start end) - (let ((bytes (map '(simple-array (unsigned-byte 8) (*)) #'char-code thing))) - (stream-write-sequence stream bytes start end))) - -(defmethod stream-line-column ((stream ssl-stream)) - nil) - -(defmethod stream-listen ((stream ssl-stream)) - (warn "stream-listen") - (call-next-method)) - -(defmethod stream-read-char-no-hang ((stream ssl-stream)) - (warn "stream-read-char-no-hang") - (call-next-method)) - -(defmethod stream-peek-char ((stream ssl-stream)) - (warn "stream-peek-char") - (call-next-method)) +(defmethod stream-force-output ((stream ssl-stream)) + (let ((buf (ssl-stream-output-buffer stream)) + (fill-ptr (ssl-stream-output-pointer stream)) + (handle (ssl-stream-handle stream)) + (socket (ssl-stream-socket stream))) + (when (plusp fill-ptr) + (cffi-sys::with-pointer-to-vector-data (ptr buf) + (ensure-ssl-funcall socket handle #'ssl-write 0.5 handle ptr fill-ptr)) + (setf (ssl-stream-output-pointer stream) 0)))) ;;; interface functions ;;; -(defun make-ssl-client-stream (socket &key (method 'ssl-v23-method)) +(defun make-ssl-client-stream + (socket &key (method 'ssl-v23-method) external-format) "Returns an SSL stream for the client socket descriptor SOCKET." (ensure-initialized method) (let ((stream (make-instance 'ssl-stream :socket socket)) (handle (ssl-new *ssl-global-context*))) (setf (ssl-stream-handle stream) handle) - ;; (let ((bio (bio-new-socket socket 0))) (ssl-set-bio handle bio bio)) (ssl-set-bio handle (bio-new-lisp) (bio-new-lisp)) (ssl-set-connect-state handle) (ensure-ssl-funcall socket handle #'ssl-connect 0.25 handle) - stream)) + (if external-format + (flexi-streams:make-flexi-stream stream + :external-format external-format) + stream))) (defun make-ssl-server-stream - (socket &key certificate key (method 'ssl-v23-method)) + (socket &key certificate key (method 'ssl-v23-method) external-format) "Returns an SSL stream for the server socket descriptor SOCKET. CERTIFICATE is the path to a file containing the PEM-encoded certificate for your server. KEY is the path to the PEM-encoded key for the server, which @@ -170,4 +197,7 @@ (error 'ssl-error-initialize :reason "Can't load certificate ~A" certificate))) (ensure-ssl-funcall socket handle #'ssl-accept 0.25 handle) - stream)) + (if external-format + (flexi-streams:make-flexi-stream stream + :external-format external-format) + stream))) Index: cl+ssl/test.lisp diff -u cl+ssl/test.lisp:1.1.1.1 cl+ssl/test.lisp:1.2 --- cl+ssl/test.lisp:1.1.1.1 Wed Nov 9 23:10:44 2005 +++ cl+ssl/test.lisp Fri Nov 25 21:14:04 2005 @@ -33,7 +33,7 @@ (defun test-nntps-client (&optional (host "snews.gmane.org") (port 563)) (let* ((fd (trivial-sockets:open-stream host port :element-type '(unsigned-byte 8))) - (nntps (cl+ssl:make-ssl-client-stream fd))) + (nntps (cl+ssl:make-ssl-client-stream fd :external-format :iso-8859-1))) (format t "NNTPS> ~A~%" (read-line-crlf nntps)) (write-line "HELP" nntps) (force-output nntps) @@ -47,7 +47,7 @@ (defun test-https-client (host &optional (port 443)) (let* ((fd (trivial-sockets:open-stream host port :element-type '(unsigned-byte 8))) - (https (cl+ssl:make-ssl-client-stream fd))) + (https (cl+ssl:make-ssl-client-stream fd :external-format :iso-8859-1))) (unwind-protect (progn (format https "HEAD / HTTP/1.0~%Host: ~a~%~%" host) @@ -76,6 +76,7 @@ (trivial-sockets:accept-connection server :element-type '(unsigned-byte 8)) + :external-format :iso-8859-1 :certificate cert :key key))) (unwind-protect From dlichteblau at common-lisp.net Fri Nov 25 22:39:43 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 23:39:43 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: cl+ssl/streams.lisp Message-ID: <20051125223943.891DD880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/tmp/cvs-serv8507 Modified Files: streams.lisp Log Message: stream-element-type implementiert Date: Fri Nov 25 23:39:43 2005 Author: dlichteblau Index: cl+ssl/streams.lisp diff -u cl+ssl/streams.lisp:1.3 cl+ssl/streams.lisp:1.4 --- cl+ssl/streams.lisp:1.3 Fri Nov 25 21:14:04 2005 +++ cl+ssl/streams.lisp Fri Nov 25 23:39:42 2005 @@ -46,9 +46,9 @@ :initarg :key :accessor ssl-stream-key))) +(defmethod stream-element-type ((stream ssl-stream)) + '(unsigned-byte 8)) -;;; binary stream implementation -;;; (defmethod close ((stream ssl-stream) &key abort) (declare (ignore abort)) (force-output stream) From dlichteblau at common-lisp.net Fri Nov 25 22:40:12 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 23:40:12 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: trivial-gray-streams/mixin.lisp Message-ID: <20051125224012.AFBF3880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-gray-streams In directory common-lisp.net:/tmp/cvs-serv8529 Modified Files: mixin.lisp Log Message: stream-read/write-char-sequence fuer clisp Date: Fri Nov 25 23:40:12 2005 Author: dlichteblau Index: trivial-gray-streams/mixin.lisp diff -u trivial-gray-streams/mixin.lisp:1.2 trivial-gray-streams/mixin.lisp:1.3 --- trivial-gray-streams/mixin.lisp:1.2 Fri Nov 25 21:08:44 2005 +++ trivial-gray-streams/mixin.lisp Fri Nov 25 23:40:12 2005 @@ -69,6 +69,14 @@ (error "this stream does not support the NO-HANG argument")) (when interactive (error "this stream does not support the INTERACTIVE argument")) + (stream-write-sequence s seq start end)) + + (defmethod gray:stream-read-char-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) + (stream-read-sequence s seq start end)) + + (defmethod gray:stream-write-char-sequence + ((s trivial-gray-stream-mixin) seq &optional start end) (stream-write-sequence s seq start end))) #+sbcl From dlichteblau at common-lisp.net Fri Nov 25 22:55:19 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Fri, 25 Nov 2005 23:55:19 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: cl+ssl/index.html Message-ID: <20051125225519.5F0A5880D7@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/cl+ssl In directory common-lisp.net:/tmp/cvs-serv9672 Modified Files: index.html Log Message: tarball link Date: Fri Nov 25 23:55:18 2005 Author: dlichteblau Index: cl+ssl/index.html diff -u cl+ssl/index.html:1.3 cl+ssl/index.html:1.4 --- cl+ssl/index.html:1.3 Fri Nov 25 21:14:04 2005 +++ cl+ssl/index.html Fri Nov 25 23:55:18 2005 @@ -26,6 +26,9 @@ $ cvs co trivial-gray-streams $ cvs co trivial-https

+ Tarballs are also available. +

+

Note that you need the libssl-dev package on Debian to load this package without manual configuration.

From dlichteblau at common-lisp.net Sat Nov 26 12:01:07 2005 From: dlichteblau at common-lisp.net (David Lichteblau) Date: Sat, 26 Nov 2005 13:01:07 +0100 (CET) Subject: [cl-plus-ssl-cvs] CVS update: trivial-gray-streams/package.lisp Message-ID: <20051126120107.36B25880D5@common-lisp.net> Update of /project/cl-plus-ssl/cvsroot/trivial-gray-streams In directory common-lisp.net:/tmp/cvs-serv3220 Modified Files: package.lisp Log Message: allegro autoloading workaround Date: Sat Nov 26 13:01:05 2005 Author: dlichteblau Index: trivial-gray-streams/package.lisp diff -u trivial-gray-streams/package.lisp:1.2 trivial-gray-streams/package.lisp:1.3 --- trivial-gray-streams/package.lisp:1.2 Fri Nov 25 21:08:44 2005 +++ trivial-gray-streams/package.lisp Sat Nov 26 13:01:03 2005 @@ -4,6 +4,11 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (require :gray-streams)) +#+allegro +(eval-when (:compile-toplevel :load-toplevel :execute) + (unless (fboundp 'stream:stream-write-string) + (require "streamc.fasl"))) + (macrolet ((frob () (let