Remove needless bio_err argument
[openssl.git] / apps / s_client.c
index 900efe7c86e5a0ccec00fd54dc37164ed6ea91bd..9d0d6f0cb40a13345b8546880bf8a2ab525581c6 100644 (file)
@@ -385,7 +385,7 @@ static int ssl_srp_verify_param_cb(SSL *s, void *arg)
 static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
 {
     SRP_ARG *srp_arg = (SRP_ARG *)arg;
-    char *pass = (char *)OPENSSL_malloc(PWD_STRLEN + 1);
+    char *pass = OPENSSL_malloc(PWD_STRLEN + 1);
     PW_CB_DATA cb_tmp;
     int l;
 
@@ -468,7 +468,7 @@ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
 
 typedef enum OPTION_choice {
     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
-    OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, OPT_VERIFY,
+    OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, OPT_XMPPHOST, OPT_VERIFY,
     OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
     OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
     OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
@@ -484,11 +484,11 @@ typedef enum OPTION_choice {
     OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_KRB5SVC,
     OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN,
     OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_JPAKE,
-    OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
+    OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
     OPT_V_ENUM,
     OPT_X_ENUM,
     OPT_S_ENUM,
-    OPT_FALLBACKSCSV
+    OPT_FALLBACKSCSV, OPT_NOCMDS
 } OPTION_CHOICE;
 
 OPTIONS s_client_options[] = {
@@ -533,6 +533,7 @@ OPTIONS s_client_options[] = {
     {"mtu", OPT_MTU, 'p', "Set the link layer MTU"},
     {"starttls", OPT_STARTTLS, 's',
      "Use the STARTTLS command before starting TLS"},
+    {"xmpphost", OPT_XMPPHOST, 's', "Host to use with \"-starttls xmpp\""},
     {"rand", OPT_RAND, 's',
      "Load the file(s) into the random number generator"},
     {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"},
@@ -569,6 +570,7 @@ OPTIONS s_client_options[] = {
      "Tolerate other than the known g N values."},
     {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal mength in bits for N"},
 #endif
+    {"name", OPT_SMTPHOST, 's', "Hostname to use for \"-starttls smtp\""},
 #ifndef OPENSSL_NO_TLSEXT
     {"servername", OPT_SERVERNAME, 's',
      "Set TLS extension servername in ClientHello"},
@@ -591,7 +593,6 @@ OPTIONS s_client_options[] = {
     {"verify_quiet", OPT_VERIFY_QUIET, '-'},
     {"brief", OPT_BRIEF, '-'},
     {"prexit", OPT_PREXIT, '-'},
-    {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's'},
     {"trace", OPT_TRACE, '-'},
     {"security_debug", OPT_SECURITY_DEBUG, '-'},
     {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-'},
@@ -601,8 +602,10 @@ OPTIONS s_client_options[] = {
     {"build_chain", OPT_BUILD_CHAIN, '-'},
     {"chainCAfile", OPT_CHAINCAFILE, '<'},
     {"verifyCAfile", OPT_VERIFYCAFILE, '<'},
+    {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
 #ifndef OPENSSL_NO_ENGINE
     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+    {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's'},
 #endif
     OPT_S_OPTIONS,
     OPT_V_OPTIONS,
@@ -616,6 +619,7 @@ typedef enum PROTOCOL_choice {
     PROTO_POP3,
     PROTO_IMAP,
     PROTO_FTP,
+    PROTO_TELNET,
     PROTO_XMPP
 } PROTOCOL_CHOICE;
 
@@ -625,6 +629,7 @@ static OPT_PAIR services[] = {
     {"imap", PROTO_IMAP},
     {"ftp", PROTO_FTP},
     {"xmpp", PROTO_XMPP},
+    {"telnet", PROTO_TELNET},
     {NULL}
 };
 
@@ -649,9 +654,9 @@ int s_client_main(int argc, char **argv)
         NULL;
     char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
     char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p;
-    char *engine_id = NULL, *ssl_client_engine_id = NULL;
-    char *jpake_secret = NULL;
+    char *jpake_secret = NULL, *xmpphost = NULL;
     const char *unix_path = NULL;
+    const char *ehlo = "mail.example.com";
     struct sockaddr peer;
     struct timeval timeout, *timeoutp;
     fd_set readfds, writefds;
@@ -661,7 +666,7 @@ int s_client_main(int argc, char **argv)
     int enable_timeouts = 0, sdebug = 0, peerlen = sizeof peer;
     int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
     int ret = 1, in_init = 1, i, nbio_test = 0, s, k, width, state = 0;
-    int sbuf_len, sbuf_off, socket_type = SOCK_STREAM;
+    int sbuf_len, sbuf_off, socket_type = SOCK_STREAM, cmdletters = 1;
     int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
     int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
     int fallback_scsv = 0;
@@ -674,8 +679,8 @@ int s_client_main(int argc, char **argv)
 #endif
 #ifndef OPENSSL_NO_ENGINE
     ENGINE *ssl_client_engine = NULL;
-    ENGINE *e = NULL;
 #endif
+    ENGINE *e = NULL;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
     struct timeval tv;
 #endif
@@ -754,6 +759,12 @@ int s_client_main(int argc, char **argv)
         case OPT_UNIX:
             unix_path = opt_arg();
             break;
+        case OPT_XMPPHOST:
+            xmpphost = opt_arg();
+            break;
+        case OPT_SMTPHOST:
+            ehlo = opt_arg();
+            break;
         case OPT_VERIFY:
             verify = SSL_VERIFY_PEER;
             verify_depth = atoi(opt_arg());
@@ -823,16 +834,26 @@ int s_client_main(int argc, char **argv)
         case OPT_NBIO:
             c_nbio = 1;
             break;
+        case OPT_NOCMDS:
+            cmdletters = 0;
+            break;
         case OPT_KRB5SVC:
 #ifndef OPENSSL_NO_KRB5
             krb5svc = opt_arg();
 #endif
             break;
         case OPT_ENGINE:
-            engine_id = opt_arg();
+            e = setup_engine(opt_arg(), 1);
             break;
         case OPT_SSL_CLIENT_ENGINE:
-            ssl_client_engine_id = opt_arg();
+#ifndef OPENSSL_NO_ENGINE
+            ssl_client_engine = ENGINE_by_id(opt_arg());
+            if (ssl_client_engine == NULL) {
+                BIO_printf(bio_err, "Error getting client auth engine\n");
+                goto opthelp;
+            }
+            break;
+#endif
             break;
         case OPT_RAND:
             inrand = opt_arg();
@@ -1075,17 +1096,6 @@ int s_client_main(int argc, char **argv)
         next_proto.data = NULL;
 #endif
 
-#ifndef OPENSSL_NO_ENGINE
-    e = setup_engine(engine_id, 1);
-    if (ssl_client_engine_id) {
-        ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
-        if (ssl_client_engine == NULL) {
-            BIO_printf(bio_err, "Error getting client auth engine\n");
-            goto end;
-        }
-    }
-#endif
-
     if (!app_passwd(passarg, NULL, &pass, NULL)) {
         BIO_printf(bio_err, "Error getting password\n");
         goto end;
@@ -1171,7 +1181,7 @@ int s_client_main(int argc, char **argv)
     }
 
     if (sdebug)
-        ssl_ctx_security_debug(ctx, bio_err, sdebug);
+        ssl_ctx_security_debug(ctx, sdebug);
 
     if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
         BIO_printf(bio_err, "Error setting verify params\n");
@@ -1483,7 +1493,7 @@ int s_client_main(int argc, char **argv)
                 mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
             }
             while (mbuf_len > 3 && mbuf[3] == '-');
-            BIO_printf(fbio, "EHLO openssl.client.net\r\n");
+            BIO_printf(fbio, "EHLO %s\r\n", ehlo);
             (void)BIO_flush(fbio);
             /* wait for multi-line response to end EHLO SMTP response */
             do {
@@ -1563,7 +1573,7 @@ int s_client_main(int argc, char **argv)
             BIO_printf(sbio, "<stream:stream "
                        "xmlns:stream='http://etherx.jabber.org/streams' "
                        "xmlns='jabber:client' to='%s' version='1.0'>",
-                       host);
+                       xmpphost ? xmpphost : host);
             seen = BIO_read(sbio, mbuf, BUFSIZZ);
             mbuf[seen] = 0;
             while (!strstr
@@ -1587,6 +1597,35 @@ int s_client_main(int argc, char **argv)
             mbuf[0] = 0;
         }
         break;
+    case PROTO_TELNET:
+        {
+            static const unsigned char tls_do[] = {
+                /* IAC    DO   START_TLS */
+                   255,   253, 46
+            };
+            static const unsigned char tls_will[] = {
+                /* IAC  WILL START_TLS */
+                   255, 251, 46
+            };
+            static const unsigned char tls_follows[] = {
+                /* IAC  SB   START_TLS FOLLOWS IAC  SE */
+                   255, 250, 46,       1,      255, 240
+            };
+            int bytes;
+
+            /* Telnet server should demand we issue START_TLS */
+            bytes = BIO_read(sbio, mbuf, BUFSIZZ);
+            if (bytes != 3 || memcmp(mbuf, tls_do, 3) != 0)
+                goto shut;
+            /* Agree to issue START_TLS and send the FOLLOWS sub-command */
+            BIO_write(sbio, tls_will, 3);
+            BIO_write(sbio, tls_follows, 6);
+            (void)BIO_flush(sbio);
+            /* Telnet server also sent the FOLLOWS sub-command */
+            bytes = BIO_read(sbio, mbuf, BUFSIZZ);
+            if (bytes != 6 || memcmp(mbuf, tls_follows, 6) != 0)
+                goto shut;
+        }
     }
 
     for (;;) {
@@ -1624,7 +1663,7 @@ int s_client_main(int argc, char **argv)
                 }
                 if (c_brief) {
                     BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
-                    print_ssl_summary(bio_err, con);
+                    print_ssl_summary(con);
                 }
 
                 print_stuff(bio_c_out, con, full_log);
@@ -1911,19 +1950,19 @@ int s_client_main(int argc, char **argv)
             } else
                 i = raw_read_stdin(cbuf, BUFSIZZ);
 
-            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q'))) {
+            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) {
                 BIO_printf(bio_err, "DONE\n");
                 ret = 0;
                 goto shut;
             }
 
-            if ((!c_ign_eof) && (cbuf[0] == 'R')) {
+            if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) {
                 BIO_printf(bio_err, "RENEGOTIATING\n");
                 SSL_renegotiate(con);
                 cbuf_len = 0;
             }
 #ifndef OPENSSL_NO_HEARTBEATS
-            else if ((!c_ign_eof) && (cbuf[0] == 'B')) {
+            else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
                 BIO_printf(bio_err, "HEARTBEATING\n");
                 SSL_heartbeat(con);
                 cbuf_len = 0;