M: f >insecure ;
: >secure ( addrspec -- addrspec' )
- >insecure [ dup secure? [ <secure> ] unless ] map ;
+ >insecure [ dup secure? [ f <secure> ] unless ] map ;
: configurable-addrspecs ( addrspecs -- addrspecs' )
[ inet6? not ipv6-supported? or ] filter ;
M: inet6 connect-addr [ "::1" ] dip port>> <inet6> ;
-M: secure connect-addr addrspec>> connect-addr <secure> ;
+M: secure connect-addr addrspec>> connect-addr f <secure> ;
M: local connect-addr ;
swap >>file
] with-destructors ;
-: <ssl-socket> ( winsock -- ssl )
- [
- socket-handle BIO_NOCLOSE BIO_new_socket dup ssl-error
- ] keep <ssl-handle>
- [ handle>> swap dup SSL_set_bio ] keep ;
+:: <ssl-socket> ( winsock hostname -- ssl )
+ winsock socket-handle BIO_NOCLOSE BIO_new_socket dup ssl-error :> bio
+ winsock <ssl-handle> :> handle
+ handle handle>> :> native-handle
+ hostname [
+ utf8 string>alien
+ native-handle swap SSL_set_tlsext_host_name ssl-error
+ ] when*
+ native-handle bio bio SSL_set_bio
+ handle ;
! Error handling
: syscall-error ( r -- event )
: make-input/output-secure ( input output -- )
dup handle>> non-ssl-socket? [ upgrade-on-non-socket ] unless
- [ <ssl-socket> ] change-handle
+ [ f <ssl-socket> ] change-handle
handle>> >>handle drop ;
: (send-secure-handshake) ( output -- )
-USING: io help.markup help.syntax calendar quotations io.sockets ;
+USING: io help.markup help.syntax calendar quotations strings io.sockets ;
IN: io.sockets.secure
HELP: secure-socket-timeout
{ $class-description "The class of secure socket addresses." } ;
HELP: <secure>
-{ $values { "addrspec" "an address specifier" } { "secure" secure } }
+{ $values { "addrspec" "an address specifier" } { "hostname" { $maybe string } } { "secure" secure } }
{ $description "Creates a new secure socket address, which can then be passed to " { $link <client> } " or " { $link <server> } "." } ;
ARTICLE: "ssl-addresses" "Secure socket addresses"
USING: accessors io.sockets io.sockets.secure io.sockets.secure.debug
kernel system tools.test ;
-{ "hello" 24 } [ "hello" 24 <inet> <secure> [ host>> ] [ port>> ] bi ] unit-test
+{ "hello" 24 } [ "hello" 24 <inet> "hello" <secure> [ host>> ] [ port>> ] bi ] unit-test
{ } [
<test-secure-config> [ ] with-secure-context
with-disposal
] with-scope ; inline
-TUPLE: secure { addrspec read-only } ;
+TUPLE: secure
+ { addrspec read-only }
+ { hostname read-only } ;
C: <secure> secure
CONSULT: inet secure addrspec>> ;
M: secure resolve-host ( secure -- seq )
- addrspec>> resolve-host [ <secure> ] map ;
+ [ addrspec>> resolve-host ] [ hostname>> ] bi
+ [ <secure> ] curry map ;
HOOK: check-certificate secure-socket-backend ( host handle -- )
:: server-test ( quot -- )
[
[
- "127.0.0.1" 0 <inet4> <secure> ascii <server> [
+ "127.0.0.1" 0 <inet4> f <secure> ascii <server> [
dup addr>> addrspec>> port>> "port" get fulfill
accept [
quot call
: client-test ( -- string )
<secure-config> [
- "127.0.0.1" "port" get ?promise <inet4> <secure> ascii <client> drop stream-contents
+ "127.0.0.1" "port" get ?promise <inet4> f <secure> ascii <client> drop stream-contents
] with-secure-context ;
{ } [ [ class-of name>> write ] server-test ] unit-test
[
<secure-config> [
- "localhost" "port" get ?promise <inet> <secure> ascii
+ "localhost" "port" get ?promise <inet> f <secure> ascii
<client> drop dispose
] with-secure-context
] [ certificate-verify-error? ] must-fail-with
1 seconds secure-socket-timeout [
[
[
- "127.0.0.1" 0 <inet4> <secure> ascii <server> [
+ "127.0.0.1" 0 <inet4> f <secure> ascii <server> [
dup addr>> addrspec>> port>> "port" get fulfill
accept drop &dispose dup stream-read1 drop
] with-disposal
[
[
[
- "127.0.0.1" 0 <inet4> <secure> ascii <server> [
+ "127.0.0.1" 0 <inet4> f <secure> ascii <server> [
dup addr>> addrspec>> port>> "port" get fulfill
accept drop &dispose 1 minutes sleep
] with-disposal
[
1 seconds secure-socket-timeout [
<secure-config> [
- "127.0.0.1" "port" get ?promise <inet4> <secure>
+ "127.0.0.1" "port" get ?promise <inet4> f <secure>
ascii <client> drop dispose
] with-secure-context
] with-variable
[
[
"127.0.0.1" "port" get ?promise
- <inet4> <secure> ascii <client> drop &dispose 1 minutes sleep
+ <inet4> f <secure> ascii <client> drop &dispose 1 minutes sleep
] with-test-context
] with-destructors
] "Silly client" spawn drop
[
1 seconds secure-socket-timeout [
[
- "127.0.0.1" 0 <inet4> <secure> ascii <server> [
+ "127.0.0.1" 0 <inet4> f <secure> ascii <server> [
dup addr>> addrspec>> port>> "port" get fulfill
accept drop &dispose
] with-disposal
M: unix socket-handle fd>> ;
-M: secure ((client)) ( addrspec -- handle )
- addrspec>> ((client)) <ssl-socket> ;
+M: secure ((client)) ( secure -- handle )
+ [ addrspec>> ((client)) ] [ hostname>> ] bi <ssl-socket> ;
-M: secure parse-sockaddr addrspec>> parse-sockaddr <secure> ;
+M: secure parse-sockaddr addrspec>> parse-sockaddr f <secure> ;
M: secure (get-local-address) addrspec>> (get-local-address) ;
M: secure (accept)
[
- addrspec>> (accept) [ |dispose <ssl-socket> ] dip
+ [ hostname>> ] [ addrspec>> ] bi (accept)
+ [ |dispose <ssl-socket> ] dip
] with-destructors ;
: check-shutdown-response ( handle r -- event )
M: secure (get-local-address) ( handle remote -- sockaddr )
[ file>> ] [ addrspec>> ] bi* (get-local-address) ;
-M: secure parse-sockaddr addrspec>> parse-sockaddr <secure> ;
+M: secure parse-sockaddr addrspec>> parse-sockaddr f <secure> ;
M:: secure establish-connection ( client-out addrspec -- )
client-out handle>> file>> :> socket
FUNCTION: int SSL_read ( SSL* ssl, void* buf, int num )
FUNCTION: int SSL_write ( SSL* ssl, void* buf, int num )
FUNCTION: long SSL_ctrl ( SSL* ssl, int cmd, long larg, void* parg )
-! FUNCTION: long SSL_callback_ctrl ( SSL* ssl, int cmd, long larg, void* parg )
FUNCTION: int SSL_shutdown ( SSL* ssl )
FUNCTION: void* BIO_f_ssl ( )
+: SSL_set_tlsext_host_name ( ctx hostname -- n )
+ [ SSL_CTRL_SET_TLSEXT_HOSTNAME TLSEXT_NAMETYPE_host_name ] dip
+ SSL_ctrl ;
+
: SSL_CTX_need_tmp_rsa ( ctx -- n )
SSL_CTRL_NEED_TMP_RSA 0 f SSL_CTX_ctrl ;
! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
-USING: urls urls.private io.sockets io.sockets.secure ;
+USING: kernel urls urls.private io.sockets io.sockets.secure ;
IN: urls.secure
UNION: abstract-inet inet inet4 inet6 ;
<PRIVATE
-GENERIC: >secure-addr ( addrspec -- addrspec' )
+GENERIC# >secure-addr 1 ( addrspec host -- addrspec' )
PRIVATE>
[ port>> ]
[ protocol>> protocol-port ]
tri or <inet>
- ] [ protocol>> ] bi
- secure-protocol? [ >secure-addr ] when ;
+ ]
+ [ host>> ]
+ [ protocol>> ] tri
+ secure-protocol? [ >secure-addr ] [ drop ] if ;
: set-url-addr ( url addr -- url )
[ host>> >>host ] [ port>> >>port ] bi ;
! Constructor
: <imap4ssl> ( host -- imap4 )
- IMAP4_SSL_PORT <inet> <secure> binary <client> drop
+ IMAP4_SSL_PORT <inet> f <secure> binary <client> drop
! Read the useless welcome message.
dup [ "\\*" read-response drop ] with-stream* ;