Hi, The attached patch adds the -fd parameter to s_client, to use SSL/TLS over an already established connection.
This could then be used like this from Bash: openssl s_client -fd 9 9<> /dev/tcp/encrypted.google.com/443 One application would be to negotiate the use of SSL/TLS in plain text before SSL/TLS is used for protocols which are not supported by the -starttls flag. The following snippet demonstrates this for HTTPS through an HTTP proxy (again for Bash): ============================================================================== # Open a socket on file descriptor 9 exec 9<> "/dev/tcp/$PROXYHOST/$PROXYPORT" || exit 1 # Start the HTTP proxy connection printf 'CONNECT %s:%s HTTP/1.1\r\nHost: %s:%s\r\nProxy-Connection: Keep-Alive\r\n\r\n' "$TARGETHOST" "$TARGETPORT" "$TARGETHOST" "$TARGETPORT" >&9 # Read the response until an empty line is encountered. while :; do read -r LINE if [ -z "$LINE" -o '^M' = "$LINE" ]; then break fi done <&9 # Start encryption openssl s_client -fd 9 -ign_eof ============================================================================== Regards, Serge van den Boom
diff -ur openssl-1.0.1c/apps/s_client.c openssl-1.0.1c-org/apps/s_client.c --- openssl-1.0.1c/apps/s_client.c 2012-09-07 15:03:18.000000000 +0200 +++ openssl-1.0.1c-org/apps/s_client.c 2012-03-18 19:16:05.000000000 +0100 @@ -140,7 +140,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/stat.h> #include <openssl/e_os2.h> #ifdef OPENSSL_NO_STDIO #define APPS_WIN16 @@ -289,7 +288,6 @@ BIO_printf(bio_err," -host host - use -connect instead\n"); BIO_printf(bio_err," -port port - use -connect instead\n"); BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR); - BIO_printf(bio_err," -fd fd - file descriptor to use (alternative to -connect)\n"); BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); @@ -560,7 +558,7 @@ #ifndef OPENSSL_NO_KRB5 KSSL_CTX *kctx; #endif - int s,fd=-1,k,width,state=0; + int s,k,width,state=0; char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL; int cbuf_len,cbuf_off; int sbuf_len,sbuf_off; @@ -675,13 +673,6 @@ if (!extract_host_port(*(++argv),&host,NULL,&port)) goto bad; } - else if (strcmp(*argv,"-fd") == 0) - { - if (--argc < 1) goto bad; - fd=atoi(*(++argv)); - host = ""; - port = 0; - } else if (strcmp(*argv,"-verify") == 0) { verify=SSL_VERIFY_PEER; @@ -1261,31 +1252,13 @@ re_start: - if (fd != -1) + if (init_client(&s,host,port,socket_type) == 0) { - struct stat sb; - if (fstat(fd, &sb) == -1) - { - BIO_printf(bio_err,"bad file descriptor\n"); - goto end; - } - if (!S_ISSOCK(sb.st_mode)) - { - BIO_printf(bio_err,"file descriptor is not a socket\n"); - goto end; - } - s = fd; - } - else - { - if (init_client(&s,host,port,socket_type) == 0) - { - BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); - SHUTDOWN(s); - goto end; - } - BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); + BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error()); + SHUTDOWN(s); + goto end; } + BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s); #ifdef FIONBIO if (c_nbio) diff -ur openssl-1.0.1c/doc/apps/s_client.pod openssl-1.0.1c-org/doc/apps/s_client.pod --- openssl-1.0.1c/doc/apps/s_client.pod 2012-09-12 16:26:08.000000000 +0200 +++ openssl-1.0.1c-org/doc/apps/s_client.pod 2009-06-26 13:28:51.000000000 +0200 @@ -9,7 +9,6 @@ B<openssl> B<s_client> [B<-connect host:port>] -[B<-fd fd>] [B<-verify depth>] [B<-cert filename>] [B<-certform DER|PEM>] @@ -60,10 +59,6 @@ This specifies the host and optional port to connect to. If not specified then an attempt is made to connect to the local host on port 4433. -=item B<-fd fd> - -A file descriptor of an open socket to use instead of connecting with B<-connect>. - =item B<-cert certname> The certificate to use, if one is requested by the server. The default is