Allow detection of input EOF in quiet mode by adding -no_ign_eof option
[openssl.git] / apps / s_client.c
index 0c3545a4ca61a569a66b0aa6e4e2b808974fde45..f038a553238e3a1ea55b8af71d38d7872d7463ff 100644 (file)
@@ -162,6 +162,7 @@ typedef unsigned int u_int;
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 #include <openssl/ocsp.h>
+#include <openssl/bn.h>
 #include "s_apps.h"
 #include "timeouts.h"
 
@@ -204,7 +205,9 @@ static int c_showcerts=0;
 
 static void sc_usage(void);
 static void print_stuff(BIO *berr,SSL *con,int full);
+#ifndef OPENSSL_NO_TLSEXT
 static int ocsp_resp_cb(SSL *s, void *arg);
+#endif
 static BIO *bio_c_out=NULL;
 static int c_quiet=0;
 static int c_ign_eof=0;
@@ -305,6 +308,7 @@ static void sc_usage(void)
        BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
        BIO_printf(bio_err," -quiet        - no s_client output\n");
        BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
+       BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
 #ifndef OPENSSL_NO_PSK
        BIO_printf(bio_err," -psk_identity arg - PSK identity\n");
        BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
@@ -322,7 +326,8 @@ static void sc_usage(void)
        BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
        BIO_printf(bio_err,"                 for those protocols that support it, where\n");
        BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
-       BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", and \"ftp\" are supported.\n");
+       BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
+       BIO_printf(bio_err,"                 are supported.\n");
 #ifndef OPENSSL_NO_ENGINE
        BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
 #endif
@@ -365,7 +370,8 @@ enum
        PROTO_SMTP,
        PROTO_POP3,
        PROTO_IMAP,
-       PROTO_FTP
+       PROTO_FTP,
+       PROTO_XMPP
 };
 
 int MAIN(int, char **);
@@ -403,7 +409,8 @@ int MAIN(int argc, char **argv)
        int mbuf_len=0;
 #ifndef OPENSSL_NO_ENGINE
        char *engine_id=NULL;
-       ENGINE *e=NULL;
+       char *ssl_client_engine_id=NULL;
+       ENGINE *e=NULL, *ssl_client_engine=NULL;
 #endif
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
        struct timeval tv;
@@ -525,6 +532,8 @@ int MAIN(int argc, char **argv)
                        }
                else if (strcmp(*argv,"-ign_eof") == 0)
                        c_ign_eof=1;
+               else if (strcmp(*argv,"-no_ign_eof") == 0)
+                       c_ign_eof=0;
                else if (strcmp(*argv,"-pause") == 0)
                        c_Pause=1;
                else if (strcmp(*argv,"-debug") == 0)
@@ -660,6 +669,8 @@ int MAIN(int argc, char **argv)
                                starttls_proto = PROTO_IMAP;
                        else if (strcmp(*argv,"ftp") == 0)
                                starttls_proto = PROTO_FTP;
+                       else if (strcmp(*argv, "xmpp") == 0)
+                               starttls_proto = PROTO_XMPP;
                        else
                                goto bad;
                        }
@@ -669,6 +680,11 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        engine_id = *(++argv);
                        }
+               else if (strcmp(*argv,"-ssl_client_engine") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       ssl_client_engine_id = *(++argv);
+                       }
 #endif
                else if (strcmp(*argv,"-rand") == 0)
                        {
@@ -704,6 +720,17 @@ bad:
 
 #ifndef OPENSSL_NO_ENGINE
         e = setup_engine(bio_err, engine_id, 1);
+       if (ssl_client_engine_id)
+               {
+               ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
+               if (!ssl_client_engine)
+                       {
+                       BIO_printf(bio_err,
+                                       "Error getting client auth engine\n");
+                       goto end;
+                       }
+               }
+
 #endif
        if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
                {
@@ -771,6 +798,20 @@ bad:
                goto end;
                }
 
+#ifndef OPENSSL_NO_ENGINE
+       if (ssl_client_engine)
+               {
+               if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
+                       {
+                       BIO_puts(bio_err, "Error setting client auth engine\n");
+                       ERR_print_errors(bio_err);
+                       ENGINE_free(ssl_client_engine);
+                       goto end;
+                       }
+               ENGINE_free(ssl_client_engine);
+               }
+#endif
+
 #ifndef OPENSSL_NO_PSK
        if (psk_key != NULL)
                {
@@ -1084,6 +1125,28 @@ SSL_set_tlsext_status_ids(con, ids);
                BIO_printf(sbio,"AUTH TLS\r\n");
                BIO_read(sbio,sbuf,BUFSIZZ);
                }
+       if (starttls_proto == PROTO_XMPP)
+               {
+               int seen = 0;
+               BIO_printf(sbio,"<stream:stream "
+                   "xmlns:stream='http://etherx.jabber.org/streams' "
+                   "xmlns='jabber:client' to='%s' version='1.0'>", host);
+               seen = BIO_read(sbio,mbuf,BUFSIZZ);
+               mbuf[seen] = 0;
+               while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+                       {
+                       if (strstr(mbuf, "/stream:features>"))
+                               goto shut;
+                       seen = BIO_read(sbio,mbuf,BUFSIZZ);
+                       mbuf[seen] = 0;
+                       }
+               BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+               seen = BIO_read(sbio,sbuf,BUFSIZZ);
+               sbuf[seen] = 0;
+               if (!strstr(sbuf, "<proceed"))
+                       goto shut;
+               mbuf[0] = 0;
+               }
 
        for (;;)
                {
@@ -1497,7 +1560,7 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        char buf[BUFSIZ];
        STACK_OF(X509) *sk;
        STACK_OF(X509_NAME) *sk2;
-       SSL_CIPHER *c;
+       const SSL_CIPHER *c;
        X509_NAME *xn;
        int j,i;
 #ifndef OPENSSL_NO_COMP
@@ -1621,6 +1684,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        (void)BIO_flush(bio);
        }
 
+#ifndef OPENSSL_NO_TLSEXT
+
 static int ocsp_resp_cb(SSL *s, void *arg)
        {
        const unsigned char *p;
@@ -1646,3 +1711,5 @@ static int ocsp_resp_cb(SSL *s, void *arg)
        OCSP_RESPONSE_free(rsp);
        return 1;
        }
+
+#endif