xref: /freebsd/crypto/openssl/apps/s_client.c (revision 5c87c606cde085944937b11c908b8c1232fef219)
174664626SKris Kennaway /* apps/s_client.c */
274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
374664626SKris Kennaway  * All rights reserved.
474664626SKris Kennaway  *
574664626SKris Kennaway  * This package is an SSL implementation written
674664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
774664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
874664626SKris Kennaway  *
974664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1074664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1174664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1274664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1374664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1474664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1574664626SKris Kennaway  *
1674664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1774664626SKris Kennaway  * the code are not to be removed.
1874664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
1974664626SKris Kennaway  * as the author of the parts of the library used.
2074664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2174664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2274664626SKris Kennaway  *
2374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2474664626SKris Kennaway  * modification, are permitted provided that the following conditions
2574664626SKris Kennaway  * are met:
2674664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2774664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
2874664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3074664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3174664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3274664626SKris Kennaway  *    must display the following acknowledgement:
3374664626SKris Kennaway  *    "This product includes cryptographic software written by
3474664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3574664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3674664626SKris Kennaway  *    being used are not cryptographic related :-).
3774664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
3874664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
3974664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4074664626SKris Kennaway  *
4174664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4274664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4374664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4474664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4574664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4674664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4774664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4874664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4974664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5074664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5174664626SKris Kennaway  * SUCH DAMAGE.
5274664626SKris Kennaway  *
5374664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5474664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5574664626SKris Kennaway  * copied and put under another distribution licence
5674664626SKris Kennaway  * [including the GNU Public Licence.]
5774664626SKris Kennaway  */
585c87c606SMark Murray /* ====================================================================
595c87c606SMark Murray  * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
605c87c606SMark Murray  *
615c87c606SMark Murray  * Redistribution and use in source and binary forms, with or without
625c87c606SMark Murray  * modification, are permitted provided that the following conditions
635c87c606SMark Murray  * are met:
645c87c606SMark Murray  *
655c87c606SMark Murray  * 1. Redistributions of source code must retain the above copyright
665c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer.
675c87c606SMark Murray  *
685c87c606SMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
695c87c606SMark Murray  *    notice, this list of conditions and the following disclaimer in
705c87c606SMark Murray  *    the documentation and/or other materials provided with the
715c87c606SMark Murray  *    distribution.
725c87c606SMark Murray  *
735c87c606SMark Murray  * 3. All advertising materials mentioning features or use of this
745c87c606SMark Murray  *    software must display the following acknowledgment:
755c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
765c87c606SMark Murray  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
775c87c606SMark Murray  *
785c87c606SMark Murray  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
795c87c606SMark Murray  *    endorse or promote products derived from this software without
805c87c606SMark Murray  *    prior written permission. For written permission, please contact
815c87c606SMark Murray  *    openssl-core@openssl.org.
825c87c606SMark Murray  *
835c87c606SMark Murray  * 5. Products derived from this software may not be called "OpenSSL"
845c87c606SMark Murray  *    nor may "OpenSSL" appear in their names without prior written
855c87c606SMark Murray  *    permission of the OpenSSL Project.
865c87c606SMark Murray  *
875c87c606SMark Murray  * 6. Redistributions of any form whatsoever must retain the following
885c87c606SMark Murray  *    acknowledgment:
895c87c606SMark Murray  *    "This product includes software developed by the OpenSSL Project
905c87c606SMark Murray  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
915c87c606SMark Murray  *
925c87c606SMark Murray  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
935c87c606SMark Murray  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
945c87c606SMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
955c87c606SMark Murray  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
965c87c606SMark Murray  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
975c87c606SMark Murray  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
985c87c606SMark Murray  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
995c87c606SMark Murray  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1005c87c606SMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1015c87c606SMark Murray  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1025c87c606SMark Murray  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1035c87c606SMark Murray  * OF THE POSSIBILITY OF SUCH DAMAGE.
1045c87c606SMark Murray  * ====================================================================
1055c87c606SMark Murray  *
1065c87c606SMark Murray  * This product includes cryptographic software written by Eric Young
1075c87c606SMark Murray  * (eay@cryptsoft.com).  This product includes software written by Tim
1085c87c606SMark Murray  * Hudson (tjh@cryptsoft.com).
1095c87c606SMark Murray  *
1105c87c606SMark Murray  */
11174664626SKris Kennaway 
11274664626SKris Kennaway #include <assert.h>
11374664626SKris Kennaway #include <stdio.h>
11474664626SKris Kennaway #include <stdlib.h>
11574664626SKris Kennaway #include <string.h>
1165c87c606SMark Murray #include <openssl/e_os2.h>
1175c87c606SMark Murray #ifdef OPENSSL_NO_STDIO
11874664626SKris Kennaway #define APPS_WIN16
11974664626SKris Kennaway #endif
12074664626SKris Kennaway 
12174664626SKris Kennaway /* With IPv6, it looks like Digital has mixed up the proper order of
12274664626SKris Kennaway    recursive header file inclusion, resulting in the compiler complaining
12374664626SKris Kennaway    that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
12474664626SKris Kennaway    is needed to have fileno() declared correctly...  So let's define u_int */
1255c87c606SMark Murray #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
12674664626SKris Kennaway #define __U_INT
12774664626SKris Kennaway typedef unsigned int u_int;
12874664626SKris Kennaway #endif
12974664626SKris Kennaway 
13074664626SKris Kennaway #define USE_SOCKETS
13174664626SKris Kennaway #include "apps.h"
13274664626SKris Kennaway #include <openssl/x509.h>
13374664626SKris Kennaway #include <openssl/ssl.h>
13474664626SKris Kennaway #include <openssl/err.h>
13574664626SKris Kennaway #include <openssl/pem.h>
1365740a5e3SKris Kennaway #include <openssl/rand.h>
13774664626SKris Kennaway #include "s_apps.h"
13874664626SKris Kennaway 
1395c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS
140f579bf8eSKris Kennaway #include <conio.h>
141f579bf8eSKris Kennaway #endif
142f579bf8eSKris Kennaway 
1435c87c606SMark Murray #ifdef OPENSSL_SYS_WINCE
1445c87c606SMark Murray /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
1455c87c606SMark Murray #ifdef fileno
1465c87c606SMark Murray #undef fileno
1475c87c606SMark Murray #endif
1485c87c606SMark Murray #define fileno(a) (int)_fileno(a)
1495c87c606SMark Murray #endif
150f579bf8eSKris Kennaway 
1515c87c606SMark Murray 
1525c87c606SMark Murray #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
15374664626SKris Kennaway /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
15474664626SKris Kennaway #undef FIONBIO
15574664626SKris Kennaway #endif
15674664626SKris Kennaway 
15774664626SKris Kennaway #undef PROG
15874664626SKris Kennaway #define PROG	s_client_main
15974664626SKris Kennaway 
16074664626SKris Kennaway /*#define SSL_HOST_NAME	"www.netscape.com" */
16174664626SKris Kennaway /*#define SSL_HOST_NAME	"193.118.187.102" */
16274664626SKris Kennaway #define SSL_HOST_NAME	"localhost"
16374664626SKris Kennaway 
16474664626SKris Kennaway /*#define TEST_CERT "client.pem" */ /* no default cert. */
16574664626SKris Kennaway 
16674664626SKris Kennaway #undef BUFSIZZ
16774664626SKris Kennaway #define BUFSIZZ 1024*8
16874664626SKris Kennaway 
16974664626SKris Kennaway extern int verify_depth;
17074664626SKris Kennaway extern int verify_error;
17174664626SKris Kennaway 
17274664626SKris Kennaway #ifdef FIONBIO
17374664626SKris Kennaway static int c_nbio=0;
17474664626SKris Kennaway #endif
17574664626SKris Kennaway static int c_Pause=0;
17674664626SKris Kennaway static int c_debug=0;
1775c87c606SMark Murray static int c_msg=0;
17874664626SKris Kennaway static int c_showcerts=0;
17974664626SKris Kennaway 
18074664626SKris Kennaway static void sc_usage(void);
18174664626SKris Kennaway static void print_stuff(BIO *berr,SSL *con,int full);
18274664626SKris Kennaway static BIO *bio_c_out=NULL;
18374664626SKris Kennaway static int c_quiet=0;
184f579bf8eSKris Kennaway static int c_ign_eof=0;
18574664626SKris Kennaway 
18674664626SKris Kennaway static void sc_usage(void)
18774664626SKris Kennaway 	{
18874664626SKris Kennaway 	BIO_printf(bio_err,"usage: s_client args\n");
18974664626SKris Kennaway 	BIO_printf(bio_err,"\n");
19074664626SKris Kennaway 	BIO_printf(bio_err," -host host     - use -connect instead\n");
19174664626SKris Kennaway 	BIO_printf(bio_err," -port port     - use -connect instead\n");
19274664626SKris Kennaway 	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
19374664626SKris Kennaway 
19474664626SKris Kennaway 	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
19574664626SKris Kennaway 	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
19674664626SKris Kennaway 	BIO_printf(bio_err," -key arg      - Private key file to use, PEM format assumed, in cert file if\n");
19774664626SKris Kennaway 	BIO_printf(bio_err,"                 not specified but cert file is.\n");
19874664626SKris Kennaway 	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
19974664626SKris Kennaway 	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
20074664626SKris Kennaway 	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
20174664626SKris Kennaway 	BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
20274664626SKris Kennaway 	BIO_printf(bio_err," -showcerts    - show all certificates in the chain\n");
20374664626SKris Kennaway 	BIO_printf(bio_err," -debug        - extra output\n");
2045c87c606SMark Murray 	BIO_printf(bio_err," -msg          - Show protocol messages\n");
20574664626SKris Kennaway 	BIO_printf(bio_err," -nbio_test    - more ssl protocol testing\n");
20674664626SKris Kennaway 	BIO_printf(bio_err," -state        - print the 'ssl' states\n");
20774664626SKris Kennaway #ifdef FIONBIO
20874664626SKris Kennaway 	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
20974664626SKris Kennaway #endif
21074664626SKris Kennaway 	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
21174664626SKris Kennaway 	BIO_printf(bio_err," -quiet        - no s_client output\n");
212f579bf8eSKris Kennaway 	BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
21374664626SKris Kennaway 	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
21474664626SKris Kennaway 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
21574664626SKris Kennaway 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
21674664626SKris Kennaway 	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
21774664626SKris Kennaway 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
2185c87c606SMark Murray 	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\n");
219f579bf8eSKris Kennaway 	BIO_printf(bio_err," -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
22074664626SKris Kennaway 	BIO_printf(bio_err,"                 command to see what is available\n");
2215c87c606SMark Murray 	BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
2225c87c606SMark Murray 	BIO_printf(bio_err,"                 for those protocols that support it, where\n");
2235c87c606SMark Murray 	BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
2245c87c606SMark Murray 	BIO_printf(bio_err,"                 only \"smtp\" is supported.\n");
2255c87c606SMark Murray 	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
2265740a5e3SKris Kennaway 	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
22774664626SKris Kennaway 
22874664626SKris Kennaway 	}
22974664626SKris Kennaway 
230f579bf8eSKris Kennaway int MAIN(int, char **);
231f579bf8eSKris Kennaway 
23274664626SKris Kennaway int MAIN(int argc, char **argv)
23374664626SKris Kennaway 	{
23474664626SKris Kennaway 	int off=0;
23574664626SKris Kennaway 	SSL *con=NULL,*con2=NULL;
2365c87c606SMark Murray 	X509_STORE *store = NULL;
23774664626SKris Kennaway 	int s,k,width,state=0;
2385c87c606SMark Murray 	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
23974664626SKris Kennaway 	int cbuf_len,cbuf_off;
24074664626SKris Kennaway 	int sbuf_len,sbuf_off;
24174664626SKris Kennaway 	fd_set readfds,writefds;
24274664626SKris Kennaway 	short port=PORT;
24374664626SKris Kennaway 	int full_log=1;
24474664626SKris Kennaway 	char *host=SSL_HOST_NAME;
24574664626SKris Kennaway 	char *cert_file=NULL,*key_file=NULL;
24674664626SKris Kennaway 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
24774664626SKris Kennaway 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
24874664626SKris Kennaway 	int crlf=0;
24974664626SKris Kennaway 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
25074664626SKris Kennaway 	SSL_CTX *ctx=NULL;
25174664626SKris Kennaway 	int ret=1,in_init=1,i,nbio_test=0;
2525c87c606SMark Murray 	int smtp_starttls = 0;
2535c87c606SMark Murray 	int prexit = 0, vflags = 0;
25474664626SKris Kennaway 	SSL_METHOD *meth=NULL;
25574664626SKris Kennaway 	BIO *sbio;
2565740a5e3SKris Kennaway 	char *inrand=NULL;
2575c87c606SMark Murray 	char *engine_id=NULL;
2585c87c606SMark Murray 	ENGINE *e=NULL;
2595c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS
260f579bf8eSKris Kennaway 	struct timeval tv;
261f579bf8eSKris Kennaway #endif
26274664626SKris Kennaway 
2635c87c606SMark Murray #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
26474664626SKris Kennaway 	meth=SSLv23_client_method();
2655c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL3)
26674664626SKris Kennaway 	meth=SSLv3_client_method();
2675c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL2)
26874664626SKris Kennaway 	meth=SSLv2_client_method();
26974664626SKris Kennaway #endif
27074664626SKris Kennaway 
27174664626SKris Kennaway 	apps_startup();
27274664626SKris Kennaway 	c_Pause=0;
27374664626SKris Kennaway 	c_quiet=0;
274f579bf8eSKris Kennaway 	c_ign_eof=0;
27574664626SKris Kennaway 	c_debug=0;
2765c87c606SMark Murray 	c_msg=0;
27774664626SKris Kennaway 	c_showcerts=0;
27874664626SKris Kennaway 
27974664626SKris Kennaway 	if (bio_err == NULL)
28074664626SKris Kennaway 		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
28174664626SKris Kennaway 
2825c87c606SMark Murray 	if (!load_config(bio_err, NULL))
2835c87c606SMark Murray 		goto end;
2845c87c606SMark Murray 
285ddd58736SKris Kennaway 	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
2865c87c606SMark Murray 		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
2875c87c606SMark Murray 		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
28874664626SKris Kennaway 		{
28974664626SKris Kennaway 		BIO_printf(bio_err,"out of memory\n");
29074664626SKris Kennaway 		goto end;
29174664626SKris Kennaway 		}
29274664626SKris Kennaway 
29374664626SKris Kennaway 	verify_depth=0;
29474664626SKris Kennaway 	verify_error=X509_V_OK;
29574664626SKris Kennaway #ifdef FIONBIO
29674664626SKris Kennaway 	c_nbio=0;
29774664626SKris Kennaway #endif
29874664626SKris Kennaway 
29974664626SKris Kennaway 	argc--;
30074664626SKris Kennaway 	argv++;
30174664626SKris Kennaway 	while (argc >= 1)
30274664626SKris Kennaway 		{
30374664626SKris Kennaway 		if	(strcmp(*argv,"-host") == 0)
30474664626SKris Kennaway 			{
30574664626SKris Kennaway 			if (--argc < 1) goto bad;
30674664626SKris Kennaway 			host= *(++argv);
30774664626SKris Kennaway 			}
30874664626SKris Kennaway 		else if	(strcmp(*argv,"-port") == 0)
30974664626SKris Kennaway 			{
31074664626SKris Kennaway 			if (--argc < 1) goto bad;
31174664626SKris Kennaway 			port=atoi(*(++argv));
31274664626SKris Kennaway 			if (port == 0) goto bad;
31374664626SKris Kennaway 			}
31474664626SKris Kennaway 		else if (strcmp(*argv,"-connect") == 0)
31574664626SKris Kennaway 			{
31674664626SKris Kennaway 			if (--argc < 1) goto bad;
31774664626SKris Kennaway 			if (!extract_host_port(*(++argv),&host,NULL,&port))
31874664626SKris Kennaway 				goto bad;
31974664626SKris Kennaway 			}
32074664626SKris Kennaway 		else if	(strcmp(*argv,"-verify") == 0)
32174664626SKris Kennaway 			{
32274664626SKris Kennaway 			verify=SSL_VERIFY_PEER;
32374664626SKris Kennaway 			if (--argc < 1) goto bad;
32474664626SKris Kennaway 			verify_depth=atoi(*(++argv));
32574664626SKris Kennaway 			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
32674664626SKris Kennaway 			}
32774664626SKris Kennaway 		else if	(strcmp(*argv,"-cert") == 0)
32874664626SKris Kennaway 			{
32974664626SKris Kennaway 			if (--argc < 1) goto bad;
33074664626SKris Kennaway 			cert_file= *(++argv);
33174664626SKris Kennaway 			}
3325c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check") == 0)
3335c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK;
3345c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check_all") == 0)
3355c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
336f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-prexit") == 0)
337f579bf8eSKris Kennaway 			prexit=1;
33874664626SKris Kennaway 		else if	(strcmp(*argv,"-crlf") == 0)
33974664626SKris Kennaway 			crlf=1;
34074664626SKris Kennaway 		else if	(strcmp(*argv,"-quiet") == 0)
341f579bf8eSKris Kennaway 			{
34274664626SKris Kennaway 			c_quiet=1;
343f579bf8eSKris Kennaway 			c_ign_eof=1;
344f579bf8eSKris Kennaway 			}
345f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-ign_eof") == 0)
346f579bf8eSKris Kennaway 			c_ign_eof=1;
34774664626SKris Kennaway 		else if	(strcmp(*argv,"-pause") == 0)
34874664626SKris Kennaway 			c_Pause=1;
34974664626SKris Kennaway 		else if	(strcmp(*argv,"-debug") == 0)
35074664626SKris Kennaway 			c_debug=1;
3515c87c606SMark Murray 		else if	(strcmp(*argv,"-msg") == 0)
3525c87c606SMark Murray 			c_msg=1;
35374664626SKris Kennaway 		else if	(strcmp(*argv,"-showcerts") == 0)
35474664626SKris Kennaway 			c_showcerts=1;
35574664626SKris Kennaway 		else if	(strcmp(*argv,"-nbio_test") == 0)
35674664626SKris Kennaway 			nbio_test=1;
35774664626SKris Kennaway 		else if	(strcmp(*argv,"-state") == 0)
35874664626SKris Kennaway 			state=1;
3595c87c606SMark Murray #ifndef OPENSSL_NO_SSL2
36074664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl2") == 0)
36174664626SKris Kennaway 			meth=SSLv2_client_method();
36274664626SKris Kennaway #endif
3635c87c606SMark Murray #ifndef OPENSSL_NO_SSL3
36474664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl3") == 0)
36574664626SKris Kennaway 			meth=SSLv3_client_method();
36674664626SKris Kennaway #endif
3675c87c606SMark Murray #ifndef OPENSSL_NO_TLS1
36874664626SKris Kennaway 		else if	(strcmp(*argv,"-tls1") == 0)
36974664626SKris Kennaway 			meth=TLSv1_client_method();
37074664626SKris Kennaway #endif
37174664626SKris Kennaway 		else if (strcmp(*argv,"-bugs") == 0)
37274664626SKris Kennaway 			bugs=1;
37374664626SKris Kennaway 		else if	(strcmp(*argv,"-key") == 0)
37474664626SKris Kennaway 			{
37574664626SKris Kennaway 			if (--argc < 1) goto bad;
37674664626SKris Kennaway 			key_file= *(++argv);
37774664626SKris Kennaway 			}
37874664626SKris Kennaway 		else if	(strcmp(*argv,"-reconnect") == 0)
37974664626SKris Kennaway 			{
38074664626SKris Kennaway 			reconnect=5;
38174664626SKris Kennaway 			}
38274664626SKris Kennaway 		else if	(strcmp(*argv,"-CApath") == 0)
38374664626SKris Kennaway 			{
38474664626SKris Kennaway 			if (--argc < 1) goto bad;
38574664626SKris Kennaway 			CApath= *(++argv);
38674664626SKris Kennaway 			}
38774664626SKris Kennaway 		else if	(strcmp(*argv,"-CAfile") == 0)
38874664626SKris Kennaway 			{
38974664626SKris Kennaway 			if (--argc < 1) goto bad;
39074664626SKris Kennaway 			CAfile= *(++argv);
39174664626SKris Kennaway 			}
39274664626SKris Kennaway 		else if (strcmp(*argv,"-no_tls1") == 0)
39374664626SKris Kennaway 			off|=SSL_OP_NO_TLSv1;
39474664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl3") == 0)
39574664626SKris Kennaway 			off|=SSL_OP_NO_SSLv3;
39674664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl2") == 0)
39774664626SKris Kennaway 			off|=SSL_OP_NO_SSLv2;
3985c87c606SMark Murray 		else if (strcmp(*argv,"-serverpref") == 0)
3995c87c606SMark Murray 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
40074664626SKris Kennaway 		else if	(strcmp(*argv,"-cipher") == 0)
40174664626SKris Kennaway 			{
40274664626SKris Kennaway 			if (--argc < 1) goto bad;
40374664626SKris Kennaway 			cipher= *(++argv);
40474664626SKris Kennaway 			}
40574664626SKris Kennaway #ifdef FIONBIO
40674664626SKris Kennaway 		else if (strcmp(*argv,"-nbio") == 0)
40774664626SKris Kennaway 			{ c_nbio=1; }
40874664626SKris Kennaway #endif
4095c87c606SMark Murray 		else if	(strcmp(*argv,"-starttls") == 0)
4105c87c606SMark Murray 			{
4115c87c606SMark Murray 			if (--argc < 1) goto bad;
4125c87c606SMark Murray 			++argv;
4135c87c606SMark Murray 			if (strcmp(*argv,"smtp") == 0)
4145c87c606SMark Murray 				smtp_starttls = 1;
4155c87c606SMark Murray 			else
4165c87c606SMark Murray 				goto bad;
4175c87c606SMark Murray 			}
4185c87c606SMark Murray 		else if	(strcmp(*argv,"-engine") == 0)
4195c87c606SMark Murray 			{
4205c87c606SMark Murray 			if (--argc < 1) goto bad;
4215c87c606SMark Murray 			engine_id = *(++argv);
4225c87c606SMark Murray 			}
4235740a5e3SKris Kennaway 		else if (strcmp(*argv,"-rand") == 0)
4245740a5e3SKris Kennaway 			{
4255740a5e3SKris Kennaway 			if (--argc < 1) goto bad;
4265740a5e3SKris Kennaway 			inrand= *(++argv);
4275740a5e3SKris Kennaway 			}
42874664626SKris Kennaway 		else
42974664626SKris Kennaway 			{
43074664626SKris Kennaway 			BIO_printf(bio_err,"unknown option %s\n",*argv);
43174664626SKris Kennaway 			badop=1;
43274664626SKris Kennaway 			break;
43374664626SKris Kennaway 			}
43474664626SKris Kennaway 		argc--;
43574664626SKris Kennaway 		argv++;
43674664626SKris Kennaway 		}
43774664626SKris Kennaway 	if (badop)
43874664626SKris Kennaway 		{
43974664626SKris Kennaway bad:
44074664626SKris Kennaway 		sc_usage();
44174664626SKris Kennaway 		goto end;
44274664626SKris Kennaway 		}
44374664626SKris Kennaway 
4445c87c606SMark Murray 	OpenSSL_add_ssl_algorithms();
4455c87c606SMark Murray 	SSL_load_error_strings();
4465c87c606SMark Murray 
4475c87c606SMark Murray         e = setup_engine(bio_err, engine_id, 1);
4485c87c606SMark Murray 
4495740a5e3SKris Kennaway 	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
4505740a5e3SKris Kennaway 		&& !RAND_status())
4515740a5e3SKris Kennaway 		{
4525740a5e3SKris Kennaway 		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
4535740a5e3SKris Kennaway 		}
4545740a5e3SKris Kennaway 	if (inrand != NULL)
4555740a5e3SKris Kennaway 		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
4565740a5e3SKris Kennaway 			app_RAND_load_files(inrand));
457f579bf8eSKris Kennaway 
45874664626SKris Kennaway 	if (bio_c_out == NULL)
45974664626SKris Kennaway 		{
4605c87c606SMark Murray 		if (c_quiet && !c_debug && !c_msg)
46174664626SKris Kennaway 			{
46274664626SKris Kennaway 			bio_c_out=BIO_new(BIO_s_null());
46374664626SKris Kennaway 			}
46474664626SKris Kennaway 		else
46574664626SKris Kennaway 			{
46674664626SKris Kennaway 			if (bio_c_out == NULL)
46774664626SKris Kennaway 				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
46874664626SKris Kennaway 			}
46974664626SKris Kennaway 		}
47074664626SKris Kennaway 
47174664626SKris Kennaway 	ctx=SSL_CTX_new(meth);
47274664626SKris Kennaway 	if (ctx == NULL)
47374664626SKris Kennaway 		{
47474664626SKris Kennaway 		ERR_print_errors(bio_err);
47574664626SKris Kennaway 		goto end;
47674664626SKris Kennaway 		}
47774664626SKris Kennaway 
47874664626SKris Kennaway 	if (bugs)
47974664626SKris Kennaway 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
48074664626SKris Kennaway 	else
48174664626SKris Kennaway 		SSL_CTX_set_options(ctx,off);
48274664626SKris Kennaway 
48374664626SKris Kennaway 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
48474664626SKris Kennaway 	if (cipher != NULL)
485f579bf8eSKris Kennaway 		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
486f579bf8eSKris Kennaway 		BIO_printf(bio_err,"error setting cipher list\n");
487f579bf8eSKris Kennaway 		ERR_print_errors(bio_err);
488f579bf8eSKris Kennaway 		goto end;
489f579bf8eSKris Kennaway 	}
49074664626SKris Kennaway #if 0
49174664626SKris Kennaway 	else
49274664626SKris Kennaway 		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
49374664626SKris Kennaway #endif
49474664626SKris Kennaway 
49574664626SKris Kennaway 	SSL_CTX_set_verify(ctx,verify,verify_callback);
49674664626SKris Kennaway 	if (!set_cert_stuff(ctx,cert_file,key_file))
49774664626SKris Kennaway 		goto end;
49874664626SKris Kennaway 
49974664626SKris Kennaway 	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
50074664626SKris Kennaway 		(!SSL_CTX_set_default_verify_paths(ctx)))
50174664626SKris Kennaway 		{
502f579bf8eSKris Kennaway 		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
50374664626SKris Kennaway 		ERR_print_errors(bio_err);
50474664626SKris Kennaway 		/* goto end; */
50574664626SKris Kennaway 		}
50674664626SKris Kennaway 
5075c87c606SMark Murray 	store = SSL_CTX_get_cert_store(ctx);
5085c87c606SMark Murray 	X509_STORE_set_flags(store, vflags);
50974664626SKris Kennaway 
510f579bf8eSKris Kennaway 	con=SSL_new(ctx);
5115c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
5125c87c606SMark Murray 	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
5135c87c606SMark Murray                 {
5145c87c606SMark Murray                 kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
5155c87c606SMark Murray 		}
5165c87c606SMark Murray #endif	/* OPENSSL_NO_KRB5  */
51774664626SKris Kennaway /*	SSL_set_cipher_list(con,"RC4-MD5"); */
51874664626SKris Kennaway 
51974664626SKris Kennaway re_start:
52074664626SKris Kennaway 
52174664626SKris Kennaway 	if (init_client(&s,host,port) == 0)
52274664626SKris Kennaway 		{
52374664626SKris Kennaway 		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
52474664626SKris Kennaway 		SHUTDOWN(s);
52574664626SKris Kennaway 		goto end;
52674664626SKris Kennaway 		}
52774664626SKris Kennaway 	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
52874664626SKris Kennaway 
52974664626SKris Kennaway #ifdef FIONBIO
53074664626SKris Kennaway 	if (c_nbio)
53174664626SKris Kennaway 		{
53274664626SKris Kennaway 		unsigned long l=1;
53374664626SKris Kennaway 		BIO_printf(bio_c_out,"turning on non blocking io\n");
53474664626SKris Kennaway 		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
53574664626SKris Kennaway 			{
53674664626SKris Kennaway 			ERR_print_errors(bio_err);
53774664626SKris Kennaway 			goto end;
53874664626SKris Kennaway 			}
53974664626SKris Kennaway 		}
54074664626SKris Kennaway #endif
54174664626SKris Kennaway 	if (c_Pause & 0x01) con->debug=1;
54274664626SKris Kennaway 	sbio=BIO_new_socket(s,BIO_NOCLOSE);
54374664626SKris Kennaway 
54474664626SKris Kennaway 	if (nbio_test)
54574664626SKris Kennaway 		{
54674664626SKris Kennaway 		BIO *test;
54774664626SKris Kennaway 
54874664626SKris Kennaway 		test=BIO_new(BIO_f_nbio_test());
54974664626SKris Kennaway 		sbio=BIO_push(test,sbio);
55074664626SKris Kennaway 		}
55174664626SKris Kennaway 
55274664626SKris Kennaway 	if (c_debug)
55374664626SKris Kennaway 		{
55474664626SKris Kennaway 		con->debug=1;
55574664626SKris Kennaway 		BIO_set_callback(sbio,bio_dump_cb);
55674664626SKris Kennaway 		BIO_set_callback_arg(sbio,bio_c_out);
55774664626SKris Kennaway 		}
5585c87c606SMark Murray 	if (c_msg)
5595c87c606SMark Murray 		{
5605c87c606SMark Murray 		SSL_set_msg_callback(con, msg_cb);
5615c87c606SMark Murray 		SSL_set_msg_callback_arg(con, bio_c_out);
5625c87c606SMark Murray 		}
56374664626SKris Kennaway 
56474664626SKris Kennaway 	SSL_set_bio(con,sbio,sbio);
56574664626SKris Kennaway 	SSL_set_connect_state(con);
56674664626SKris Kennaway 
56774664626SKris Kennaway 	/* ok, lets connect */
56874664626SKris Kennaway 	width=SSL_get_fd(con)+1;
56974664626SKris Kennaway 
57074664626SKris Kennaway 	read_tty=1;
57174664626SKris Kennaway 	write_tty=0;
57274664626SKris Kennaway 	tty_on=0;
57374664626SKris Kennaway 	read_ssl=1;
57474664626SKris Kennaway 	write_ssl=1;
57574664626SKris Kennaway 
57674664626SKris Kennaway 	cbuf_len=0;
57774664626SKris Kennaway 	cbuf_off=0;
57874664626SKris Kennaway 	sbuf_len=0;
57974664626SKris Kennaway 	sbuf_off=0;
58074664626SKris Kennaway 
5815c87c606SMark Murray 	/* This is an ugly hack that does a lot of assumptions */
5825c87c606SMark Murray 	if (smtp_starttls)
5835c87c606SMark Murray 		{
5845c87c606SMark Murray 		BIO_read(sbio,mbuf,BUFSIZZ);
5855c87c606SMark Murray 		BIO_printf(sbio,"STARTTLS\r\n");
5865c87c606SMark Murray 		BIO_read(sbio,sbuf,BUFSIZZ);
5875c87c606SMark Murray 		}
5885c87c606SMark Murray 
58974664626SKris Kennaway 	for (;;)
59074664626SKris Kennaway 		{
59174664626SKris Kennaway 		FD_ZERO(&readfds);
59274664626SKris Kennaway 		FD_ZERO(&writefds);
59374664626SKris Kennaway 
59474664626SKris Kennaway 		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
59574664626SKris Kennaway 			{
59674664626SKris Kennaway 			in_init=1;
59774664626SKris Kennaway 			tty_on=0;
59874664626SKris Kennaway 			}
59974664626SKris Kennaway 		else
60074664626SKris Kennaway 			{
60174664626SKris Kennaway 			tty_on=1;
60274664626SKris Kennaway 			if (in_init)
60374664626SKris Kennaway 				{
60474664626SKris Kennaway 				in_init=0;
60574664626SKris Kennaway 				print_stuff(bio_c_out,con,full_log);
60674664626SKris Kennaway 				if (full_log > 0) full_log--;
60774664626SKris Kennaway 
6085c87c606SMark Murray 				if (smtp_starttls)
6095c87c606SMark Murray 					{
6105c87c606SMark Murray 					BIO_printf(bio_err,"%s",mbuf);
6115c87c606SMark Murray 					/* We don't need to know any more */
6125c87c606SMark Murray 					smtp_starttls = 0;
6135c87c606SMark Murray 					}
6145c87c606SMark Murray 
61574664626SKris Kennaway 				if (reconnect)
61674664626SKris Kennaway 					{
61774664626SKris Kennaway 					reconnect--;
61874664626SKris Kennaway 					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
61974664626SKris Kennaway 					SSL_shutdown(con);
62074664626SKris Kennaway 					SSL_set_connect_state(con);
62174664626SKris Kennaway 					SHUTDOWN(SSL_get_fd(con));
62274664626SKris Kennaway 					goto re_start;
62374664626SKris Kennaway 					}
62474664626SKris Kennaway 				}
62574664626SKris Kennaway 			}
62674664626SKris Kennaway 
62774664626SKris Kennaway 		ssl_pending = read_ssl && SSL_pending(con);
62874664626SKris Kennaway 
62974664626SKris Kennaway 		if (!ssl_pending)
63074664626SKris Kennaway 			{
6315c87c606SMark Murray #ifndef OPENSSL_SYS_WINDOWS
63274664626SKris Kennaway 			if (tty_on)
63374664626SKris Kennaway 				{
63474664626SKris Kennaway 				if (read_tty)  FD_SET(fileno(stdin),&readfds);
63574664626SKris Kennaway 				if (write_tty) FD_SET(fileno(stdout),&writefds);
63674664626SKris Kennaway 				}
63774664626SKris Kennaway 			if (read_ssl)
63874664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&readfds);
63974664626SKris Kennaway 			if (write_ssl)
64074664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&writefds);
641f579bf8eSKris Kennaway #else
642f579bf8eSKris Kennaway 			if(!tty_on || !write_tty) {
643f579bf8eSKris Kennaway 				if (read_ssl)
644f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&readfds);
645f579bf8eSKris Kennaway 				if (write_ssl)
646f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&writefds);
647f579bf8eSKris Kennaway 			}
648f579bf8eSKris Kennaway #endif
64974664626SKris Kennaway /*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
65074664626SKris Kennaway 				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
65174664626SKris Kennaway 
65274664626SKris Kennaway 			/* Note: under VMS with SOCKETSHR the second parameter
65374664626SKris Kennaway 			 * is currently of type (int *) whereas under other
65474664626SKris Kennaway 			 * systems it is (void *) if you don't have a cast it
65574664626SKris Kennaway 			 * will choke the compiler: if you do have a cast then
65674664626SKris Kennaway 			 * you can either go for (int *) or (void *).
65774664626SKris Kennaway 			 */
6585c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS
659f579bf8eSKris Kennaway 			/* Under Windows we make the assumption that we can
660f579bf8eSKris Kennaway 			 * always write to the tty: therefore if we need to
661f579bf8eSKris Kennaway 			 * write to the tty we just fall through. Otherwise
662f579bf8eSKris Kennaway 			 * we timeout the select every second and see if there
663f579bf8eSKris Kennaway 			 * are any keypresses. Note: this is a hack, in a proper
664f579bf8eSKris Kennaway 			 * Windows application we wouldn't do this.
665f579bf8eSKris Kennaway 			 */
666f579bf8eSKris Kennaway 			i=0;
667f579bf8eSKris Kennaway 			if(!write_tty) {
668f579bf8eSKris Kennaway 				if(read_tty) {
669f579bf8eSKris Kennaway 					tv.tv_sec = 1;
670f579bf8eSKris Kennaway 					tv.tv_usec = 0;
671f579bf8eSKris Kennaway 					i=select(width,(void *)&readfds,(void *)&writefds,
672f579bf8eSKris Kennaway 						 NULL,&tv);
6735c87c606SMark Murray #ifdef OPENSSL_SYS_WINCE
6745c87c606SMark Murray 					if(!i && (!_kbhit() || !read_tty) ) continue;
6755c87c606SMark Murray #else
676ddd58736SKris Kennaway 					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
6775c87c606SMark Murray #endif
678f579bf8eSKris Kennaway 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
679f579bf8eSKris Kennaway 					 NULL,NULL);
680f579bf8eSKris Kennaway 			}
681f579bf8eSKris Kennaway #else
68274664626SKris Kennaway 			i=select(width,(void *)&readfds,(void *)&writefds,
68374664626SKris Kennaway 				 NULL,NULL);
684f579bf8eSKris Kennaway #endif
68574664626SKris Kennaway 			if ( i < 0)
68674664626SKris Kennaway 				{
68774664626SKris Kennaway 				BIO_printf(bio_err,"bad select %d\n",
68874664626SKris Kennaway 				get_last_socket_error());
68974664626SKris Kennaway 				goto shut;
69074664626SKris Kennaway 				/* goto end; */
69174664626SKris Kennaway 				}
69274664626SKris Kennaway 			}
69374664626SKris Kennaway 
69474664626SKris Kennaway 		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
69574664626SKris Kennaway 			{
69674664626SKris Kennaway 			k=SSL_write(con,&(cbuf[cbuf_off]),
69774664626SKris Kennaway 				(unsigned int)cbuf_len);
69874664626SKris Kennaway 			switch (SSL_get_error(con,k))
69974664626SKris Kennaway 				{
70074664626SKris Kennaway 			case SSL_ERROR_NONE:
70174664626SKris Kennaway 				cbuf_off+=k;
70274664626SKris Kennaway 				cbuf_len-=k;
70374664626SKris Kennaway 				if (k <= 0) goto end;
70474664626SKris Kennaway 				/* we have done a  write(con,NULL,0); */
70574664626SKris Kennaway 				if (cbuf_len <= 0)
70674664626SKris Kennaway 					{
70774664626SKris Kennaway 					read_tty=1;
70874664626SKris Kennaway 					write_ssl=0;
70974664626SKris Kennaway 					}
71074664626SKris Kennaway 				else /* if (cbuf_len > 0) */
71174664626SKris Kennaway 					{
71274664626SKris Kennaway 					read_tty=0;
71374664626SKris Kennaway 					write_ssl=1;
71474664626SKris Kennaway 					}
71574664626SKris Kennaway 				break;
71674664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
71774664626SKris Kennaway 				BIO_printf(bio_c_out,"write W BLOCK\n");
71874664626SKris Kennaway 				write_ssl=1;
71974664626SKris Kennaway 				read_tty=0;
72074664626SKris Kennaway 				break;
72174664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
72274664626SKris Kennaway 				BIO_printf(bio_c_out,"write R BLOCK\n");
72374664626SKris Kennaway 				write_tty=0;
72474664626SKris Kennaway 				read_ssl=1;
72574664626SKris Kennaway 				write_ssl=0;
72674664626SKris Kennaway 				break;
72774664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
72874664626SKris Kennaway 				BIO_printf(bio_c_out,"write X BLOCK\n");
72974664626SKris Kennaway 				break;
73074664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
73174664626SKris Kennaway 				if (cbuf_len != 0)
73274664626SKris Kennaway 					{
73374664626SKris Kennaway 					BIO_printf(bio_c_out,"shutdown\n");
73474664626SKris Kennaway 					goto shut;
73574664626SKris Kennaway 					}
73674664626SKris Kennaway 				else
73774664626SKris Kennaway 					{
73874664626SKris Kennaway 					read_tty=1;
73974664626SKris Kennaway 					write_ssl=0;
74074664626SKris Kennaway 					break;
74174664626SKris Kennaway 					}
74274664626SKris Kennaway 
74374664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
74474664626SKris Kennaway 				if ((k != 0) || (cbuf_len != 0))
74574664626SKris Kennaway 					{
74674664626SKris Kennaway 					BIO_printf(bio_err,"write:errno=%d\n",
74774664626SKris Kennaway 						get_last_socket_error());
74874664626SKris Kennaway 					goto shut;
74974664626SKris Kennaway 					}
75074664626SKris Kennaway 				else
75174664626SKris Kennaway 					{
75274664626SKris Kennaway 					read_tty=1;
75374664626SKris Kennaway 					write_ssl=0;
75474664626SKris Kennaway 					}
75574664626SKris Kennaway 				break;
75674664626SKris Kennaway 			case SSL_ERROR_SSL:
75774664626SKris Kennaway 				ERR_print_errors(bio_err);
75874664626SKris Kennaway 				goto shut;
75974664626SKris Kennaway 				}
76074664626SKris Kennaway 			}
7615c87c606SMark Murray #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
7625c87c606SMark Murray 		/* Assume Windows/DOS can always write */
763f579bf8eSKris Kennaway 		else if (!ssl_pending && write_tty)
764f579bf8eSKris Kennaway #else
76574664626SKris Kennaway 		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
766f579bf8eSKris Kennaway #endif
76774664626SKris Kennaway 			{
76874664626SKris Kennaway #ifdef CHARSET_EBCDIC
76974664626SKris Kennaway 			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
77074664626SKris Kennaway #endif
77174664626SKris Kennaway 			i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
77274664626SKris Kennaway 
77374664626SKris Kennaway 			if (i <= 0)
77474664626SKris Kennaway 				{
77574664626SKris Kennaway 				BIO_printf(bio_c_out,"DONE\n");
77674664626SKris Kennaway 				goto shut;
77774664626SKris Kennaway 				/* goto end; */
77874664626SKris Kennaway 				}
77974664626SKris Kennaway 
78074664626SKris Kennaway 			sbuf_len-=i;;
78174664626SKris Kennaway 			sbuf_off+=i;
78274664626SKris Kennaway 			if (sbuf_len <= 0)
78374664626SKris Kennaway 				{
78474664626SKris Kennaway 				read_ssl=1;
78574664626SKris Kennaway 				write_tty=0;
78674664626SKris Kennaway 				}
78774664626SKris Kennaway 			}
78874664626SKris Kennaway 		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
78974664626SKris Kennaway 			{
79074664626SKris Kennaway #ifdef RENEG
79174664626SKris Kennaway { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
79274664626SKris Kennaway #endif
79374664626SKris Kennaway #if 1
79474664626SKris Kennaway 			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
79574664626SKris Kennaway #else
79674664626SKris Kennaway /* Demo for pending and peek :-) */
79774664626SKris Kennaway 			k=SSL_read(con,sbuf,16);
79874664626SKris Kennaway { char zbuf[10240];
79974664626SKris Kennaway printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
80074664626SKris Kennaway }
80174664626SKris Kennaway #endif
80274664626SKris Kennaway 
80374664626SKris Kennaway 			switch (SSL_get_error(con,k))
80474664626SKris Kennaway 				{
80574664626SKris Kennaway 			case SSL_ERROR_NONE:
80674664626SKris Kennaway 				if (k <= 0)
80774664626SKris Kennaway 					goto end;
80874664626SKris Kennaway 				sbuf_off=0;
80974664626SKris Kennaway 				sbuf_len=k;
81074664626SKris Kennaway 
81174664626SKris Kennaway 				read_ssl=0;
81274664626SKris Kennaway 				write_tty=1;
81374664626SKris Kennaway 				break;
81474664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
81574664626SKris Kennaway 				BIO_printf(bio_c_out,"read W BLOCK\n");
81674664626SKris Kennaway 				write_ssl=1;
81774664626SKris Kennaway 				read_tty=0;
81874664626SKris Kennaway 				break;
81974664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
82074664626SKris Kennaway 				BIO_printf(bio_c_out,"read R BLOCK\n");
82174664626SKris Kennaway 				write_tty=0;
82274664626SKris Kennaway 				read_ssl=1;
82374664626SKris Kennaway 				if ((read_tty == 0) && (write_ssl == 0))
82474664626SKris Kennaway 					write_ssl=1;
82574664626SKris Kennaway 				break;
82674664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
82774664626SKris Kennaway 				BIO_printf(bio_c_out,"read X BLOCK\n");
82874664626SKris Kennaway 				break;
82974664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
83074664626SKris Kennaway 				BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
83174664626SKris Kennaway 				goto shut;
83274664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
83374664626SKris Kennaway 				BIO_printf(bio_c_out,"closed\n");
83474664626SKris Kennaway 				goto shut;
83574664626SKris Kennaway 			case SSL_ERROR_SSL:
83674664626SKris Kennaway 				ERR_print_errors(bio_err);
83774664626SKris Kennaway 				goto shut;
83874664626SKris Kennaway 				/* break; */
83974664626SKris Kennaway 				}
84074664626SKris Kennaway 			}
84174664626SKris Kennaway 
8425c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS
8435c87c606SMark Murray #ifdef OPENSSL_SYS_WINCE
8445c87c606SMark Murray 		else if (_kbhit())
8455c87c606SMark Murray #else
846ddd58736SKris Kennaway 		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
8475c87c606SMark Murray #endif
848f579bf8eSKris Kennaway #else
84974664626SKris Kennaway 		else if (FD_ISSET(fileno(stdin),&readfds))
850f579bf8eSKris Kennaway #endif
85174664626SKris Kennaway 			{
85274664626SKris Kennaway 			if (crlf)
85374664626SKris Kennaway 				{
85474664626SKris Kennaway 				int j, lf_num;
85574664626SKris Kennaway 
85674664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ/2);
85774664626SKris Kennaway 				lf_num = 0;
85874664626SKris Kennaway 				/* both loops are skipped when i <= 0 */
85974664626SKris Kennaway 				for (j = 0; j < i; j++)
86074664626SKris Kennaway 					if (cbuf[j] == '\n')
86174664626SKris Kennaway 						lf_num++;
86274664626SKris Kennaway 				for (j = i-1; j >= 0; j--)
86374664626SKris Kennaway 					{
86474664626SKris Kennaway 					cbuf[j+lf_num] = cbuf[j];
86574664626SKris Kennaway 					if (cbuf[j] == '\n')
86674664626SKris Kennaway 						{
86774664626SKris Kennaway 						lf_num--;
86874664626SKris Kennaway 						i++;
86974664626SKris Kennaway 						cbuf[j+lf_num] = '\r';
87074664626SKris Kennaway 						}
87174664626SKris Kennaway 					}
87274664626SKris Kennaway 				assert(lf_num == 0);
87374664626SKris Kennaway 				}
87474664626SKris Kennaway 			else
87574664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ);
87674664626SKris Kennaway 
877f579bf8eSKris Kennaway 			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
87874664626SKris Kennaway 				{
87974664626SKris Kennaway 				BIO_printf(bio_err,"DONE\n");
88074664626SKris Kennaway 				goto shut;
88174664626SKris Kennaway 				}
88274664626SKris Kennaway 
883f579bf8eSKris Kennaway 			if ((!c_ign_eof) && (cbuf[0] == 'R'))
88474664626SKris Kennaway 				{
88574664626SKris Kennaway 				BIO_printf(bio_err,"RENEGOTIATING\n");
88674664626SKris Kennaway 				SSL_renegotiate(con);
88774664626SKris Kennaway 				cbuf_len=0;
88874664626SKris Kennaway 				}
88974664626SKris Kennaway 			else
89074664626SKris Kennaway 				{
89174664626SKris Kennaway 				cbuf_len=i;
89274664626SKris Kennaway 				cbuf_off=0;
89374664626SKris Kennaway #ifdef CHARSET_EBCDIC
89474664626SKris Kennaway 				ebcdic2ascii(cbuf, cbuf, i);
89574664626SKris Kennaway #endif
89674664626SKris Kennaway 				}
89774664626SKris Kennaway 
89874664626SKris Kennaway 			write_ssl=1;
89974664626SKris Kennaway 			read_tty=0;
90074664626SKris Kennaway 			}
90174664626SKris Kennaway 		}
90274664626SKris Kennaway shut:
90374664626SKris Kennaway 	SSL_shutdown(con);
90474664626SKris Kennaway 	SHUTDOWN(SSL_get_fd(con));
90574664626SKris Kennaway 	ret=0;
90674664626SKris Kennaway end:
907f579bf8eSKris Kennaway 	if(prexit) print_stuff(bio_c_out,con,1);
90874664626SKris Kennaway 	if (con != NULL) SSL_free(con);
90974664626SKris Kennaway 	if (con2 != NULL) SSL_free(con2);
91074664626SKris Kennaway 	if (ctx != NULL) SSL_CTX_free(ctx);
9115c87c606SMark Murray 	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
9125c87c606SMark Murray 	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
9135c87c606SMark Murray 	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
91474664626SKris Kennaway 	if (bio_c_out != NULL)
91574664626SKris Kennaway 		{
91674664626SKris Kennaway 		BIO_free(bio_c_out);
91774664626SKris Kennaway 		bio_c_out=NULL;
91874664626SKris Kennaway 		}
9195c87c606SMark Murray 	apps_shutdown();
9205c87c606SMark Murray 	OPENSSL_EXIT(ret);
92174664626SKris Kennaway 	}
92274664626SKris Kennaway 
92374664626SKris Kennaway 
92474664626SKris Kennaway static void print_stuff(BIO *bio, SSL *s, int full)
92574664626SKris Kennaway 	{
92674664626SKris Kennaway 	X509 *peer=NULL;
92774664626SKris Kennaway 	char *p;
92874664626SKris Kennaway 	static char *space="                ";
92974664626SKris Kennaway 	char buf[BUFSIZ];
93074664626SKris Kennaway 	STACK_OF(X509) *sk;
93174664626SKris Kennaway 	STACK_OF(X509_NAME) *sk2;
93274664626SKris Kennaway 	SSL_CIPHER *c;
93374664626SKris Kennaway 	X509_NAME *xn;
93474664626SKris Kennaway 	int j,i;
93574664626SKris Kennaway 
93674664626SKris Kennaway 	if (full)
93774664626SKris Kennaway 		{
93874664626SKris Kennaway 		int got_a_chain = 0;
93974664626SKris Kennaway 
94074664626SKris Kennaway 		sk=SSL_get_peer_cert_chain(s);
94174664626SKris Kennaway 		if (sk != NULL)
94274664626SKris Kennaway 			{
94374664626SKris Kennaway 			got_a_chain = 1; /* we don't have it for SSL2 (yet) */
94474664626SKris Kennaway 
94574664626SKris Kennaway 			BIO_printf(bio,"---\nCertificate chain\n");
94674664626SKris Kennaway 			for (i=0; i<sk_X509_num(sk); i++)
94774664626SKris Kennaway 				{
94874664626SKris Kennaway 				X509_NAME_oneline(X509_get_subject_name(
9495c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
95074664626SKris Kennaway 				BIO_printf(bio,"%2d s:%s\n",i,buf);
95174664626SKris Kennaway 				X509_NAME_oneline(X509_get_issuer_name(
9525c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
95374664626SKris Kennaway 				BIO_printf(bio,"   i:%s\n",buf);
95474664626SKris Kennaway 				if (c_showcerts)
95574664626SKris Kennaway 					PEM_write_bio_X509(bio,sk_X509_value(sk,i));
95674664626SKris Kennaway 				}
95774664626SKris Kennaway 			}
95874664626SKris Kennaway 
95974664626SKris Kennaway 		BIO_printf(bio,"---\n");
96074664626SKris Kennaway 		peer=SSL_get_peer_certificate(s);
96174664626SKris Kennaway 		if (peer != NULL)
96274664626SKris Kennaway 			{
96374664626SKris Kennaway 			BIO_printf(bio,"Server certificate\n");
96474664626SKris Kennaway 			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
96574664626SKris Kennaway 				PEM_write_bio_X509(bio,peer);
96674664626SKris Kennaway 			X509_NAME_oneline(X509_get_subject_name(peer),
9675c87c606SMark Murray 				buf,sizeof buf);
96874664626SKris Kennaway 			BIO_printf(bio,"subject=%s\n",buf);
96974664626SKris Kennaway 			X509_NAME_oneline(X509_get_issuer_name(peer),
9705c87c606SMark Murray 				buf,sizeof buf);
97174664626SKris Kennaway 			BIO_printf(bio,"issuer=%s\n",buf);
97274664626SKris Kennaway 			}
97374664626SKris Kennaway 		else
97474664626SKris Kennaway 			BIO_printf(bio,"no peer certificate available\n");
97574664626SKris Kennaway 
97674664626SKris Kennaway 		sk2=SSL_get_client_CA_list(s);
97774664626SKris Kennaway 		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
97874664626SKris Kennaway 			{
97974664626SKris Kennaway 			BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
98074664626SKris Kennaway 			for (i=0; i<sk_X509_NAME_num(sk2); i++)
98174664626SKris Kennaway 				{
98274664626SKris Kennaway 				xn=sk_X509_NAME_value(sk2,i);
98374664626SKris Kennaway 				X509_NAME_oneline(xn,buf,sizeof(buf));
98474664626SKris Kennaway 				BIO_write(bio,buf,strlen(buf));
98574664626SKris Kennaway 				BIO_write(bio,"\n",1);
98674664626SKris Kennaway 				}
98774664626SKris Kennaway 			}
98874664626SKris Kennaway 		else
98974664626SKris Kennaway 			{
99074664626SKris Kennaway 			BIO_printf(bio,"---\nNo client certificate CA names sent\n");
99174664626SKris Kennaway 			}
9925c87c606SMark Murray 		p=SSL_get_shared_ciphers(s,buf,sizeof buf);
99374664626SKris Kennaway 		if (p != NULL)
99474664626SKris Kennaway 			{
99574664626SKris Kennaway 			/* This works only for SSL 2.  In later protocol
99674664626SKris Kennaway 			 * versions, the client does not know what other
99774664626SKris Kennaway 			 * ciphers (in addition to the one to be used
99874664626SKris Kennaway 			 * in the current connection) the server supports. */
99974664626SKris Kennaway 
100074664626SKris Kennaway 			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
100174664626SKris Kennaway 			j=i=0;
100274664626SKris Kennaway 			while (*p)
100374664626SKris Kennaway 				{
100474664626SKris Kennaway 				if (*p == ':')
100574664626SKris Kennaway 					{
100674664626SKris Kennaway 					BIO_write(bio,space,15-j%25);
100774664626SKris Kennaway 					i++;
100874664626SKris Kennaway 					j=0;
100974664626SKris Kennaway 					BIO_write(bio,((i%3)?" ":"\n"),1);
101074664626SKris Kennaway 					}
101174664626SKris Kennaway 				else
101274664626SKris Kennaway 					{
101374664626SKris Kennaway 					BIO_write(bio,p,1);
101474664626SKris Kennaway 					j++;
101574664626SKris Kennaway 					}
101674664626SKris Kennaway 				p++;
101774664626SKris Kennaway 				}
101874664626SKris Kennaway 			BIO_write(bio,"\n",1);
101974664626SKris Kennaway 			}
102074664626SKris Kennaway 
102174664626SKris Kennaway 		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
102274664626SKris Kennaway 			BIO_number_read(SSL_get_rbio(s)),
102374664626SKris Kennaway 			BIO_number_written(SSL_get_wbio(s)));
102474664626SKris Kennaway 		}
102574664626SKris Kennaway 	BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
102674664626SKris Kennaway 	c=SSL_get_current_cipher(s);
102774664626SKris Kennaway 	BIO_printf(bio,"%s, Cipher is %s\n",
102874664626SKris Kennaway 		SSL_CIPHER_get_version(c),
102974664626SKris Kennaway 		SSL_CIPHER_get_name(c));
103074664626SKris Kennaway 	if (peer != NULL) {
103174664626SKris Kennaway 		EVP_PKEY *pktmp;
103274664626SKris Kennaway 		pktmp = X509_get_pubkey(peer);
103374664626SKris Kennaway 		BIO_printf(bio,"Server public key is %d bit\n",
103474664626SKris Kennaway 							 EVP_PKEY_bits(pktmp));
103574664626SKris Kennaway 		EVP_PKEY_free(pktmp);
103674664626SKris Kennaway 	}
103774664626SKris Kennaway 	SSL_SESSION_print(bio,SSL_get_session(s));
103874664626SKris Kennaway 	BIO_printf(bio,"---\n");
103974664626SKris Kennaway 	if (peer != NULL)
104074664626SKris Kennaway 		X509_free(peer);
1041a21b1b38SKris Kennaway 	/* flush, or debugging output gets mixed with http response */
1042a21b1b38SKris Kennaway 	BIO_flush(bio);
104374664626SKris Kennaway 	}
104474664626SKris Kennaway 
1045