2008-05-12 19:53:22 -04:00
|
|
|
! Copyright (C) 2007, 2008, Slava Pestov, Elie CHAFTARI.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: accessors byte-arrays kernel debugger sequences namespaces math
|
|
|
|
math.order combinators init alien alien.c-types alien.strings libc
|
|
|
|
continuations destructors
|
|
|
|
openssl openssl.libcrypto openssl.libssl
|
2008-05-13 19:24:46 -04:00
|
|
|
io.files io.ports io.unix.backend io.unix.sockets
|
2008-05-12 19:53:22 -04:00
|
|
|
io.encodings.ascii io.buffers io.sockets io.sockets.secure
|
2008-05-17 18:45:56 -04:00
|
|
|
unix system inspector ;
|
2008-05-12 19:53:22 -04:00
|
|
|
IN: io.unix.sockets.secure
|
|
|
|
|
2008-05-14 04:55:33 -04:00
|
|
|
M: ssl-handle handle-fd file>> handle-fd ;
|
2008-05-12 19:53:22 -04:00
|
|
|
|
2008-05-14 04:55:33 -04:00
|
|
|
: syscall-error ( r -- * )
|
2008-05-12 19:53:22 -04:00
|
|
|
ERR_get_error dup zero? [
|
|
|
|
drop
|
|
|
|
{
|
2008-05-13 19:24:46 -04:00
|
|
|
{ -1 [ (io-error) ] }
|
2008-05-17 18:45:56 -04:00
|
|
|
{ 0 [ premature-close ] }
|
2008-05-12 19:53:22 -04:00
|
|
|
} case
|
|
|
|
] [
|
2008-05-13 19:24:46 -04:00
|
|
|
nip (ssl-error)
|
|
|
|
] if ;
|
2008-05-12 19:53:22 -04:00
|
|
|
|
|
|
|
: check-response ( port r -- port r n )
|
|
|
|
over handle>> handle>> over SSL_get_error ; inline
|
|
|
|
|
|
|
|
! Input ports
|
2008-05-17 18:45:56 -04:00
|
|
|
: check-read-response ( port r -- event ) USING: namespaces io prettyprint ;
|
2008-05-12 19:53:22 -04:00
|
|
|
check-response
|
|
|
|
{
|
2008-05-13 19:24:46 -04:00
|
|
|
{ SSL_ERROR_NONE [ swap buffer>> n>buffer f ] }
|
2008-05-18 20:02:50 -04:00
|
|
|
{ SSL_ERROR_ZERO_RETURN [ 2drop f ] }
|
2008-05-13 19:24:46 -04:00
|
|
|
{ SSL_ERROR_WANT_READ [ 2drop +input+ ] }
|
|
|
|
{ SSL_ERROR_WANT_WRITE [ 2drop +output+ ] }
|
|
|
|
{ SSL_ERROR_SYSCALL [ syscall-error ] }
|
|
|
|
{ SSL_ERROR_SSL [ (ssl-error) ] }
|
2008-05-12 19:53:22 -04:00
|
|
|
} case ;
|
|
|
|
|
|
|
|
M: ssl-handle refill
|
2008-05-13 19:24:46 -04:00
|
|
|
handle>> ! ssl
|
|
|
|
over buffer>>
|
|
|
|
[ buffer-end ] ! buf
|
|
|
|
[ buffer-capacity ] bi ! len
|
|
|
|
SSL_read
|
|
|
|
check-read-response ;
|
2008-05-12 19:53:22 -04:00
|
|
|
|
|
|
|
! Output ports
|
2008-05-13 19:24:46 -04:00
|
|
|
: check-write-response ( port r -- event )
|
2008-05-12 19:53:22 -04:00
|
|
|
check-response
|
|
|
|
{
|
|
|
|
{ SSL_ERROR_NONE [ swap buffer>> buffer-consume f ] }
|
2008-05-13 19:24:46 -04:00
|
|
|
{ SSL_ERROR_WANT_READ [ 2drop +input+ ] }
|
|
|
|
{ SSL_ERROR_WANT_WRITE [ 2drop +output+ ] }
|
|
|
|
{ SSL_ERROR_SYSCALL [ syscall-error ] }
|
|
|
|
{ SSL_ERROR_SSL [ (ssl-error) ] }
|
2008-05-12 19:53:22 -04:00
|
|
|
} case ;
|
|
|
|
|
|
|
|
M: ssl-handle drain
|
2008-05-13 19:24:46 -04:00
|
|
|
handle>> ! ssl
|
|
|
|
over buffer>>
|
|
|
|
[ buffer@ ] ! buf
|
|
|
|
[ buffer-length ] bi ! len
|
2008-05-12 19:53:22 -04:00
|
|
|
SSL_write
|
|
|
|
check-write-response ;
|
|
|
|
|
|
|
|
! Client sockets
|
2008-05-14 04:55:33 -04:00
|
|
|
: <ssl-socket> ( fd -- ssl )
|
|
|
|
[ fd>> BIO_NOCLOSE BIO_new_socket dup ssl-error ] keep <ssl-handle>
|
|
|
|
[ handle>> swap dup SSL_set_bio ] keep ;
|
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure ((client)) ( addrspec -- handle )
|
2008-05-14 04:55:33 -04:00
|
|
|
addrspec>> ((client)) <ssl-socket> ;
|
2008-05-12 19:53:22 -04:00
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure parse-sockaddr addrspec>> parse-sockaddr <secure> ;
|
2008-05-14 00:36:15 -04:00
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure (get-local-address) addrspec>> (get-local-address) ;
|
2008-05-15 06:19:59 -04:00
|
|
|
|
2008-05-13 19:24:46 -04:00
|
|
|
: check-connect-response ( port r -- event )
|
2008-05-12 19:53:22 -04:00
|
|
|
check-response
|
|
|
|
{
|
2008-05-13 19:24:46 -04:00
|
|
|
{ SSL_ERROR_NONE [ 2drop f ] }
|
|
|
|
{ SSL_ERROR_WANT_READ [ 2drop +input+ ] }
|
|
|
|
{ SSL_ERROR_WANT_WRITE [ 2drop +output+ ] }
|
|
|
|
{ SSL_ERROR_SYSCALL [ syscall-error ] }
|
|
|
|
{ SSL_ERROR_SSL [ (ssl-error) ] }
|
2008-05-12 19:53:22 -04:00
|
|
|
} case ;
|
|
|
|
|
2008-05-15 06:19:59 -04:00
|
|
|
: do-ssl-connect ( port -- )
|
|
|
|
dup dup handle>> handle>> SSL_connect
|
|
|
|
check-connect-response dup
|
|
|
|
[ dupd wait-for-port do-ssl-connect ] [ 2drop ] if ;
|
2008-05-13 19:24:46 -04:00
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure establish-connection ( client-out remote -- )
|
2008-05-15 06:19:59 -04:00
|
|
|
[ addrspec>> establish-connection ]
|
|
|
|
[ drop do-ssl-connect ]
|
|
|
|
[ drop handle>> t >>connected drop ]
|
2008-05-14 20:41:39 -04:00
|
|
|
2tri ;
|
2008-05-14 04:55:33 -04:00
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure (server) addrspec>> (server) ;
|
2008-05-14 04:55:33 -04:00
|
|
|
|
|
|
|
: check-accept-response ( handle r -- event )
|
|
|
|
over handle>> over SSL_get_error
|
|
|
|
{
|
|
|
|
{ SSL_ERROR_NONE [ 2drop f ] }
|
|
|
|
{ SSL_ERROR_WANT_READ [ 2drop +input+ ] }
|
|
|
|
{ SSL_ERROR_WANT_WRITE [ 2drop +output+ ] }
|
|
|
|
{ SSL_ERROR_SYSCALL [ syscall-error ] }
|
|
|
|
{ SSL_ERROR_SSL [ (ssl-error) ] }
|
|
|
|
} case ;
|
|
|
|
|
|
|
|
: do-ssl-accept ( ssl-handle -- )
|
|
|
|
dup dup handle>> SSL_accept check-accept-response dup
|
2008-05-18 00:50:11 -04:00
|
|
|
[ >r dup file>> r> wait-for-fd drop do-ssl-accept ] [ 2drop ] if ;
|
2008-05-14 04:55:33 -04:00
|
|
|
|
2008-05-17 18:45:56 -04:00
|
|
|
M: secure (accept)
|
2008-05-14 04:55:33 -04:00
|
|
|
[
|
2008-05-17 18:45:56 -04:00
|
|
|
addrspec>> (accept) >r
|
|
|
|
|dispose <ssl-socket> t >>connected |dispose
|
|
|
|
dup do-ssl-accept r>
|
2008-05-14 04:55:33 -04:00
|
|
|
] with-destructors ;
|
|
|
|
|
|
|
|
: check-shutdown-response ( handle r -- event )
|
2008-05-15 06:19:59 -04:00
|
|
|
#! SSL_shutdown always returns 0 due to openssl bugs?
|
2008-05-14 04:55:33 -04:00
|
|
|
{
|
2008-05-15 06:19:59 -04:00
|
|
|
{ 1 [ drop f ] }
|
|
|
|
{ 0 [
|
2008-05-17 18:45:56 -04:00
|
|
|
dup handle>> SSL_want
|
|
|
|
{
|
|
|
|
{ SSL_NOTHING [ dup handle>> SSL_shutdown check-shutdown-response ] }
|
2008-05-15 06:19:59 -04:00
|
|
|
{ SSL_READING [ drop +input+ ] }
|
|
|
|
{ SSL_WRITING [ drop +output+ ] }
|
|
|
|
} case
|
|
|
|
] }
|
|
|
|
{ -1 [
|
2008-05-17 18:45:56 -04:00
|
|
|
handle>> -1 SSL_get_error
|
2008-05-15 06:19:59 -04:00
|
|
|
{
|
|
|
|
{ SSL_ERROR_WANT_READ [ +input+ ] }
|
|
|
|
{ SSL_ERROR_WANT_WRITE [ +output+ ] }
|
|
|
|
{ SSL_ERROR_SYSCALL [ -1 syscall-error ] }
|
|
|
|
{ SSL_ERROR_SSL [ (ssl-error) ] }
|
|
|
|
} case
|
|
|
|
] }
|
2008-05-14 04:55:33 -04:00
|
|
|
} case ;
|
|
|
|
|
|
|
|
M: unix ssl-shutdown
|
|
|
|
dup connected>> [
|
2008-05-17 18:45:56 -04:00
|
|
|
dup dup handle>> SSL_shutdown check-shutdown-response
|
2008-05-18 00:50:11 -04:00
|
|
|
dup [ dupd wait-for-fd drop ssl-shutdown ] [ 2drop ] if
|
2008-05-14 04:55:33 -04:00
|
|
|
] [ drop ] if ;
|