xref: /freebsd/crypto/openssl/apps/s_client.c (revision 6a599222bb564010b80b78eef3f2b6ba6c8db14a)
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>
137db522d3aSSimon L. B. Nielsen #include <openssl/ocsp.h>
13874664626SKris Kennaway #include "s_apps.h"
1393b4e3dcbSSimon L. B. Nielsen #include "timeouts.h"
14074664626SKris Kennaway 
1415c87c606SMark Murray #ifdef OPENSSL_SYS_WINCE
1425c87c606SMark Murray /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
1435c87c606SMark Murray #ifdef fileno
1445c87c606SMark Murray #undef fileno
1455c87c606SMark Murray #endif
1465c87c606SMark Murray #define fileno(a) (int)_fileno(a)
1475c87c606SMark Murray #endif
148f579bf8eSKris Kennaway 
1495c87c606SMark Murray 
1505c87c606SMark Murray #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
15174664626SKris Kennaway /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
15274664626SKris Kennaway #undef FIONBIO
15374664626SKris Kennaway #endif
15474664626SKris Kennaway 
15574664626SKris Kennaway #undef PROG
15674664626SKris Kennaway #define PROG	s_client_main
15774664626SKris Kennaway 
15874664626SKris Kennaway /*#define SSL_HOST_NAME	"www.netscape.com" */
15974664626SKris Kennaway /*#define SSL_HOST_NAME	"193.118.187.102" */
16074664626SKris Kennaway #define SSL_HOST_NAME	"localhost"
16174664626SKris Kennaway 
16274664626SKris Kennaway /*#define TEST_CERT "client.pem" */ /* no default cert. */
16374664626SKris Kennaway 
16474664626SKris Kennaway #undef BUFSIZZ
16574664626SKris Kennaway #define BUFSIZZ 1024*8
16674664626SKris Kennaway 
16774664626SKris Kennaway extern int verify_depth;
16874664626SKris Kennaway extern int verify_error;
16974664626SKris Kennaway 
17074664626SKris Kennaway #ifdef FIONBIO
17174664626SKris Kennaway static int c_nbio=0;
17274664626SKris Kennaway #endif
17374664626SKris Kennaway static int c_Pause=0;
17474664626SKris Kennaway static int c_debug=0;
175db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
176db522d3aSSimon L. B. Nielsen static int c_tlsextdebug=0;
177db522d3aSSimon L. B. Nielsen static int c_status_req=0;
178db522d3aSSimon L. B. Nielsen #endif
1795c87c606SMark Murray static int c_msg=0;
18074664626SKris Kennaway static int c_showcerts=0;
18174664626SKris Kennaway 
18274664626SKris Kennaway static void sc_usage(void);
18374664626SKris Kennaway static void print_stuff(BIO *berr,SSL *con,int full);
184db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
185db522d3aSSimon L. B. Nielsen static int ocsp_resp_cb(SSL *s, void *arg);
186db522d3aSSimon L. B. Nielsen #endif
18774664626SKris Kennaway static BIO *bio_c_out=NULL;
18874664626SKris Kennaway static int c_quiet=0;
189f579bf8eSKris Kennaway static int c_ign_eof=0;
19074664626SKris Kennaway 
19174664626SKris Kennaway static void sc_usage(void)
19274664626SKris Kennaway 	{
19374664626SKris Kennaway 	BIO_printf(bio_err,"usage: s_client args\n");
19474664626SKris Kennaway 	BIO_printf(bio_err,"\n");
19574664626SKris Kennaway 	BIO_printf(bio_err," -host host     - use -connect instead\n");
19674664626SKris Kennaway 	BIO_printf(bio_err," -port port     - use -connect instead\n");
19774664626SKris Kennaway 	BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
19874664626SKris Kennaway 
1993b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -verify depth - turn on peer certificate verification\n");
20074664626SKris Kennaway 	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
2013b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
2023b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
20374664626SKris Kennaway 	BIO_printf(bio_err,"                 not specified but cert file is.\n");
2043b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -keyform arg  - key format (PEM or DER) PEM default\n");
2053b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
20674664626SKris Kennaway 	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
20774664626SKris Kennaway 	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
20874664626SKris Kennaway 	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
20974664626SKris Kennaway 	BIO_printf(bio_err," -pause        - sleep(1) after each read(2) and write(2) system call\n");
21074664626SKris Kennaway 	BIO_printf(bio_err," -showcerts    - show all certificates in the chain\n");
21174664626SKris Kennaway 	BIO_printf(bio_err," -debug        - extra output\n");
2123b4e3dcbSSimon L. B. Nielsen #ifdef WATT32
2133b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -wdebug       - WATT-32 tcp debugging\n");
2143b4e3dcbSSimon L. B. Nielsen #endif
2155c87c606SMark Murray 	BIO_printf(bio_err," -msg          - Show protocol messages\n");
21674664626SKris Kennaway 	BIO_printf(bio_err," -nbio_test    - more ssl protocol testing\n");
21774664626SKris Kennaway 	BIO_printf(bio_err," -state        - print the 'ssl' states\n");
21874664626SKris Kennaway #ifdef FIONBIO
21974664626SKris Kennaway 	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
22074664626SKris Kennaway #endif
22174664626SKris Kennaway 	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
22274664626SKris Kennaway 	BIO_printf(bio_err," -quiet        - no s_client output\n");
223f579bf8eSKris Kennaway 	BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
224db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
22574664626SKris Kennaway 	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
22674664626SKris Kennaway 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
22774664626SKris Kennaway 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
2283b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");
2296a599222SSimon L. B. Nielsen 	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
23074664626SKris Kennaway 	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
23174664626SKris Kennaway 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
2325c87c606SMark Murray 	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences (only SSLv2)\n");
233f579bf8eSKris Kennaway 	BIO_printf(bio_err," -cipher       - preferred cipher to use, use the 'openssl ciphers'\n");
23474664626SKris Kennaway 	BIO_printf(bio_err,"                 command to see what is available\n");
2355c87c606SMark Murray 	BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
2365c87c606SMark Murray 	BIO_printf(bio_err,"                 for those protocols that support it, where\n");
2375c87c606SMark Murray 	BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
238db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
239db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err,"                 are supported.\n");
240fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
2415c87c606SMark Murray 	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
242fceca8a3SJacques Vidrine #endif
2435740a5e3SKris Kennaway 	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
244db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -sess_out arg - file to write SSL session to\n");
245db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -sess_in arg  - file to read SSL session from\n");
246db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
247db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -servername host  - Set TLS extension servername in ClientHello\n");
248db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -tlsextdebug      - hex dump of all TLS extensions received\n");
249db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -status           - request certificate status from server\n");
250db522d3aSSimon L. B. Nielsen 	BIO_printf(bio_err," -no_ticket        - disable use of RFC4507bis session tickets\n");
251db522d3aSSimon L. B. Nielsen #endif
2526a599222SSimon L. B. Nielsen 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
25374664626SKris Kennaway 	}
25474664626SKris Kennaway 
255db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
256db522d3aSSimon L. B. Nielsen 
257db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */
258db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st {
259db522d3aSSimon L. B. Nielsen    BIO * biodebug;
260db522d3aSSimon L. B. Nielsen    int ack;
261db522d3aSSimon L. B. Nielsen } tlsextctx;
262db522d3aSSimon L. B. Nielsen 
263db522d3aSSimon L. B. Nielsen 
264db522d3aSSimon L. B. Nielsen static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
265db522d3aSSimon L. B. Nielsen 	{
266db522d3aSSimon L. B. Nielsen 	tlsextctx * p = (tlsextctx *) arg;
267db522d3aSSimon L. B. Nielsen 	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
268db522d3aSSimon L. B. Nielsen 	if (SSL_get_servername_type(s) != -1)
269db522d3aSSimon L. B. Nielsen  	        p->ack = !SSL_session_reused(s) && hn != NULL;
270db522d3aSSimon L. B. Nielsen 	else
271db522d3aSSimon L. B. Nielsen 		BIO_printf(bio_err,"Can't use SSL_get_servername\n");
272db522d3aSSimon L. B. Nielsen 
273db522d3aSSimon L. B. Nielsen 	return SSL_TLSEXT_ERR_OK;
274db522d3aSSimon L. B. Nielsen 	}
275db522d3aSSimon L. B. Nielsen #endif
2765471f83eSSimon L. B. Nielsen enum
2775471f83eSSimon L. B. Nielsen {
2785471f83eSSimon L. B. Nielsen 	PROTO_OFF	= 0,
2795471f83eSSimon L. B. Nielsen 	PROTO_SMTP,
2805471f83eSSimon L. B. Nielsen 	PROTO_POP3,
2815471f83eSSimon L. B. Nielsen 	PROTO_IMAP,
282db522d3aSSimon L. B. Nielsen 	PROTO_FTP,
283db522d3aSSimon L. B. Nielsen 	PROTO_XMPP
2845471f83eSSimon L. B. Nielsen };
2855471f83eSSimon L. B. Nielsen 
286f579bf8eSKris Kennaway int MAIN(int, char **);
287f579bf8eSKris Kennaway 
28874664626SKris Kennaway int MAIN(int argc, char **argv)
28974664626SKris Kennaway 	{
2906a599222SSimon L. B. Nielsen 	int off=0, clr = 0;
29174664626SKris Kennaway 	SSL *con=NULL,*con2=NULL;
2925c87c606SMark Murray 	X509_STORE *store = NULL;
29374664626SKris Kennaway 	int s,k,width,state=0;
2945c87c606SMark Murray 	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
29574664626SKris Kennaway 	int cbuf_len,cbuf_off;
29674664626SKris Kennaway 	int sbuf_len,sbuf_off;
29774664626SKris Kennaway 	fd_set readfds,writefds;
29874664626SKris Kennaway 	short port=PORT;
29974664626SKris Kennaway 	int full_log=1;
30074664626SKris Kennaway 	char *host=SSL_HOST_NAME;
30174664626SKris Kennaway 	char *cert_file=NULL,*key_file=NULL;
3023b4e3dcbSSimon L. B. Nielsen 	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
3033b4e3dcbSSimon L. B. Nielsen 	char *passarg = NULL, *pass = NULL;
3043b4e3dcbSSimon L. B. Nielsen 	X509 *cert = NULL;
3053b4e3dcbSSimon L. B. Nielsen 	EVP_PKEY *key = NULL;
30674664626SKris Kennaway 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
30774664626SKris Kennaway 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
30874664626SKris Kennaway 	int crlf=0;
30974664626SKris Kennaway 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
31074664626SKris Kennaway 	SSL_CTX *ctx=NULL;
31174664626SKris Kennaway 	int ret=1,in_init=1,i,nbio_test=0;
3125471f83eSSimon L. B. Nielsen 	int starttls_proto = PROTO_OFF;
3135c87c606SMark Murray 	int prexit = 0, vflags = 0;
31474664626SKris Kennaway 	SSL_METHOD *meth=NULL;
3153b4e3dcbSSimon L. B. Nielsen #ifdef sock_type
3163b4e3dcbSSimon L. B. Nielsen #undef sock_type
3173b4e3dcbSSimon L. B. Nielsen #endif
3183b4e3dcbSSimon L. B. Nielsen 	int sock_type=SOCK_STREAM;
31974664626SKris Kennaway 	BIO *sbio;
3205740a5e3SKris Kennaway 	char *inrand=NULL;
3215471f83eSSimon L. B. Nielsen 	int mbuf_len=0;
3226a599222SSimon L. B. Nielsen 	struct timeval timeout, *timeoutp;
323fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
3245c87c606SMark Murray 	char *engine_id=NULL;
325db522d3aSSimon L. B. Nielsen 	char *ssl_client_engine_id=NULL;
326db522d3aSSimon L. B. Nielsen 	ENGINE *ssl_client_engine=NULL;
327fceca8a3SJacques Vidrine #endif
328db522d3aSSimon L. B. Nielsen 	ENGINE *e=NULL;
3293b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
330f579bf8eSKris Kennaway 	struct timeval tv;
331f579bf8eSKris Kennaway #endif
33274664626SKris Kennaway 
333db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
334db522d3aSSimon L. B. Nielsen 	char *servername = NULL;
335db522d3aSSimon L. B. Nielsen         tlsextctx tlsextcbp =
336db522d3aSSimon L. B. Nielsen         {NULL,0};
337db522d3aSSimon L. B. Nielsen #endif
338db522d3aSSimon L. B. Nielsen 	char *sess_in = NULL;
339db522d3aSSimon L. B. Nielsen 	char *sess_out = NULL;
3403b4e3dcbSSimon L. B. Nielsen 	struct sockaddr peer;
3413b4e3dcbSSimon L. B. Nielsen 	int peerlen = sizeof(peer);
3423b4e3dcbSSimon L. B. Nielsen 	int enable_timeouts = 0 ;
3436a599222SSimon L. B. Nielsen 	long socket_mtu = 0;
344db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
345db522d3aSSimon L. B. Nielsen 	char *jpake_secret = NULL;
346db522d3aSSimon L. B. Nielsen #endif
3473b4e3dcbSSimon L. B. Nielsen 
3485c87c606SMark Murray #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
34974664626SKris Kennaway 	meth=SSLv23_client_method();
3505c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL3)
35174664626SKris Kennaway 	meth=SSLv3_client_method();
3525c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL2)
35374664626SKris Kennaway 	meth=SSLv2_client_method();
35474664626SKris Kennaway #endif
35574664626SKris Kennaway 
35674664626SKris Kennaway 	apps_startup();
35774664626SKris Kennaway 	c_Pause=0;
35874664626SKris Kennaway 	c_quiet=0;
359f579bf8eSKris Kennaway 	c_ign_eof=0;
36074664626SKris Kennaway 	c_debug=0;
3615c87c606SMark Murray 	c_msg=0;
36274664626SKris Kennaway 	c_showcerts=0;
36374664626SKris Kennaway 
36474664626SKris Kennaway 	if (bio_err == NULL)
36574664626SKris Kennaway 		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
36674664626SKris Kennaway 
3675c87c606SMark Murray 	if (!load_config(bio_err, NULL))
3685c87c606SMark Murray 		goto end;
3695c87c606SMark Murray 
370ddd58736SKris Kennaway 	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3715c87c606SMark Murray 		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3725c87c606SMark Murray 		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
37374664626SKris Kennaway 		{
37474664626SKris Kennaway 		BIO_printf(bio_err,"out of memory\n");
37574664626SKris Kennaway 		goto end;
37674664626SKris Kennaway 		}
37774664626SKris Kennaway 
37874664626SKris Kennaway 	verify_depth=0;
37974664626SKris Kennaway 	verify_error=X509_V_OK;
38074664626SKris Kennaway #ifdef FIONBIO
38174664626SKris Kennaway 	c_nbio=0;
38274664626SKris Kennaway #endif
38374664626SKris Kennaway 
38474664626SKris Kennaway 	argc--;
38574664626SKris Kennaway 	argv++;
38674664626SKris Kennaway 	while (argc >= 1)
38774664626SKris Kennaway 		{
38874664626SKris Kennaway 		if	(strcmp(*argv,"-host") == 0)
38974664626SKris Kennaway 			{
39074664626SKris Kennaway 			if (--argc < 1) goto bad;
39174664626SKris Kennaway 			host= *(++argv);
39274664626SKris Kennaway 			}
39374664626SKris Kennaway 		else if	(strcmp(*argv,"-port") == 0)
39474664626SKris Kennaway 			{
39574664626SKris Kennaway 			if (--argc < 1) goto bad;
39674664626SKris Kennaway 			port=atoi(*(++argv));
39774664626SKris Kennaway 			if (port == 0) goto bad;
39874664626SKris Kennaway 			}
39974664626SKris Kennaway 		else if (strcmp(*argv,"-connect") == 0)
40074664626SKris Kennaway 			{
40174664626SKris Kennaway 			if (--argc < 1) goto bad;
40274664626SKris Kennaway 			if (!extract_host_port(*(++argv),&host,NULL,&port))
40374664626SKris Kennaway 				goto bad;
40474664626SKris Kennaway 			}
40574664626SKris Kennaway 		else if	(strcmp(*argv,"-verify") == 0)
40674664626SKris Kennaway 			{
40774664626SKris Kennaway 			verify=SSL_VERIFY_PEER;
40874664626SKris Kennaway 			if (--argc < 1) goto bad;
40974664626SKris Kennaway 			verify_depth=atoi(*(++argv));
41074664626SKris Kennaway 			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
41174664626SKris Kennaway 			}
41274664626SKris Kennaway 		else if	(strcmp(*argv,"-cert") == 0)
41374664626SKris Kennaway 			{
41474664626SKris Kennaway 			if (--argc < 1) goto bad;
41574664626SKris Kennaway 			cert_file= *(++argv);
41674664626SKris Kennaway 			}
417db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-sess_out") == 0)
418db522d3aSSimon L. B. Nielsen 			{
419db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
420db522d3aSSimon L. B. Nielsen 			sess_out = *(++argv);
421db522d3aSSimon L. B. Nielsen 			}
422db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-sess_in") == 0)
423db522d3aSSimon L. B. Nielsen 			{
424db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
425db522d3aSSimon L. B. Nielsen 			sess_in = *(++argv);
426db522d3aSSimon L. B. Nielsen 			}
4273b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-certform") == 0)
4283b4e3dcbSSimon L. B. Nielsen 			{
4293b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
4303b4e3dcbSSimon L. B. Nielsen 			cert_format = str2fmt(*(++argv));
4313b4e3dcbSSimon L. B. Nielsen 			}
4325c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check") == 0)
4335c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK;
4345c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check_all") == 0)
4355c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
436f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-prexit") == 0)
437f579bf8eSKris Kennaway 			prexit=1;
43874664626SKris Kennaway 		else if	(strcmp(*argv,"-crlf") == 0)
43974664626SKris Kennaway 			crlf=1;
44074664626SKris Kennaway 		else if	(strcmp(*argv,"-quiet") == 0)
441f579bf8eSKris Kennaway 			{
44274664626SKris Kennaway 			c_quiet=1;
443f579bf8eSKris Kennaway 			c_ign_eof=1;
444f579bf8eSKris Kennaway 			}
445f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-ign_eof") == 0)
446f579bf8eSKris Kennaway 			c_ign_eof=1;
447db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-no_ign_eof") == 0)
448db522d3aSSimon L. B. Nielsen 			c_ign_eof=0;
44974664626SKris Kennaway 		else if	(strcmp(*argv,"-pause") == 0)
45074664626SKris Kennaway 			c_Pause=1;
45174664626SKris Kennaway 		else if	(strcmp(*argv,"-debug") == 0)
45274664626SKris Kennaway 			c_debug=1;
453db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
454db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-tlsextdebug") == 0)
455db522d3aSSimon L. B. Nielsen 			c_tlsextdebug=1;
456db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-status") == 0)
457db522d3aSSimon L. B. Nielsen 			c_status_req=1;
458db522d3aSSimon L. B. Nielsen #endif
4593b4e3dcbSSimon L. B. Nielsen #ifdef WATT32
4603b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-wdebug") == 0)
4613b4e3dcbSSimon L. B. Nielsen 			dbug_init();
4623b4e3dcbSSimon L. B. Nielsen #endif
4635c87c606SMark Murray 		else if	(strcmp(*argv,"-msg") == 0)
4645c87c606SMark Murray 			c_msg=1;
46574664626SKris Kennaway 		else if	(strcmp(*argv,"-showcerts") == 0)
46674664626SKris Kennaway 			c_showcerts=1;
46774664626SKris Kennaway 		else if	(strcmp(*argv,"-nbio_test") == 0)
46874664626SKris Kennaway 			nbio_test=1;
46974664626SKris Kennaway 		else if	(strcmp(*argv,"-state") == 0)
47074664626SKris Kennaway 			state=1;
4715c87c606SMark Murray #ifndef OPENSSL_NO_SSL2
47274664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl2") == 0)
47374664626SKris Kennaway 			meth=SSLv2_client_method();
47474664626SKris Kennaway #endif
4755c87c606SMark Murray #ifndef OPENSSL_NO_SSL3
47674664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl3") == 0)
47774664626SKris Kennaway 			meth=SSLv3_client_method();
47874664626SKris Kennaway #endif
4795c87c606SMark Murray #ifndef OPENSSL_NO_TLS1
48074664626SKris Kennaway 		else if	(strcmp(*argv,"-tls1") == 0)
48174664626SKris Kennaway 			meth=TLSv1_client_method();
48274664626SKris Kennaway #endif
4833b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DTLS1
4843b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-dtls1") == 0)
4853b4e3dcbSSimon L. B. Nielsen 			{
4863b4e3dcbSSimon L. B. Nielsen 			meth=DTLSv1_client_method();
4873b4e3dcbSSimon L. B. Nielsen 			sock_type=SOCK_DGRAM;
4883b4e3dcbSSimon L. B. Nielsen 			}
4893b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-timeout") == 0)
4903b4e3dcbSSimon L. B. Nielsen 			enable_timeouts=1;
4913b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-mtu") == 0)
4923b4e3dcbSSimon L. B. Nielsen 			{
4933b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
4946a599222SSimon L. B. Nielsen 			socket_mtu = atol(*(++argv));
4953b4e3dcbSSimon L. B. Nielsen 			}
4963b4e3dcbSSimon L. B. Nielsen #endif
49774664626SKris Kennaway 		else if (strcmp(*argv,"-bugs") == 0)
49874664626SKris Kennaway 			bugs=1;
4993b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-keyform") == 0)
5003b4e3dcbSSimon L. B. Nielsen 			{
5013b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
5023b4e3dcbSSimon L. B. Nielsen 			key_format = str2fmt(*(++argv));
5033b4e3dcbSSimon L. B. Nielsen 			}
5043b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-pass") == 0)
5053b4e3dcbSSimon L. B. Nielsen 			{
5063b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
5073b4e3dcbSSimon L. B. Nielsen 			passarg = *(++argv);
5083b4e3dcbSSimon L. B. Nielsen 			}
50974664626SKris Kennaway 		else if	(strcmp(*argv,"-key") == 0)
51074664626SKris Kennaway 			{
51174664626SKris Kennaway 			if (--argc < 1) goto bad;
51274664626SKris Kennaway 			key_file= *(++argv);
51374664626SKris Kennaway 			}
51474664626SKris Kennaway 		else if	(strcmp(*argv,"-reconnect") == 0)
51574664626SKris Kennaway 			{
51674664626SKris Kennaway 			reconnect=5;
51774664626SKris Kennaway 			}
51874664626SKris Kennaway 		else if	(strcmp(*argv,"-CApath") == 0)
51974664626SKris Kennaway 			{
52074664626SKris Kennaway 			if (--argc < 1) goto bad;
52174664626SKris Kennaway 			CApath= *(++argv);
52274664626SKris Kennaway 			}
52374664626SKris Kennaway 		else if	(strcmp(*argv,"-CAfile") == 0)
52474664626SKris Kennaway 			{
52574664626SKris Kennaway 			if (--argc < 1) goto bad;
52674664626SKris Kennaway 			CAfile= *(++argv);
52774664626SKris Kennaway 			}
52874664626SKris Kennaway 		else if (strcmp(*argv,"-no_tls1") == 0)
52974664626SKris Kennaway 			off|=SSL_OP_NO_TLSv1;
53074664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl3") == 0)
53174664626SKris Kennaway 			off|=SSL_OP_NO_SSLv3;
53274664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl2") == 0)
53374664626SKris Kennaway 			off|=SSL_OP_NO_SSLv2;
534db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
535db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-no_ticket") == 0)
536db522d3aSSimon L. B. Nielsen 			{ off|=SSL_OP_NO_TICKET; }
537db522d3aSSimon L. B. Nielsen #endif
5385c87c606SMark Murray 		else if (strcmp(*argv,"-serverpref") == 0)
5395c87c606SMark Murray 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
5406a599222SSimon L. B. Nielsen 		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
5416a599222SSimon L. B. Nielsen 			off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
5426a599222SSimon L. B. Nielsen 		else if	(strcmp(*argv,"-legacy_server_connect") == 0)
5436a599222SSimon L. B. Nielsen 			{ off|=SSL_OP_LEGACY_SERVER_CONNECT; }
5446a599222SSimon L. B. Nielsen 		else if	(strcmp(*argv,"-no_legacy_server_connect") == 0)
5456a599222SSimon L. B. Nielsen 			{ clr|=SSL_OP_LEGACY_SERVER_CONNECT; }
54674664626SKris Kennaway 		else if	(strcmp(*argv,"-cipher") == 0)
54774664626SKris Kennaway 			{
54874664626SKris Kennaway 			if (--argc < 1) goto bad;
54974664626SKris Kennaway 			cipher= *(++argv);
55074664626SKris Kennaway 			}
55174664626SKris Kennaway #ifdef FIONBIO
55274664626SKris Kennaway 		else if (strcmp(*argv,"-nbio") == 0)
55374664626SKris Kennaway 			{ c_nbio=1; }
55474664626SKris Kennaway #endif
5555c87c606SMark Murray 		else if	(strcmp(*argv,"-starttls") == 0)
5565c87c606SMark Murray 			{
5575c87c606SMark Murray 			if (--argc < 1) goto bad;
5585c87c606SMark Murray 			++argv;
5595c87c606SMark Murray 			if (strcmp(*argv,"smtp") == 0)
5605471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_SMTP;
56150ef0093SJacques Vidrine 			else if (strcmp(*argv,"pop3") == 0)
5625471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_POP3;
5635471f83eSSimon L. B. Nielsen 			else if (strcmp(*argv,"imap") == 0)
5645471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_IMAP;
5655471f83eSSimon L. B. Nielsen 			else if (strcmp(*argv,"ftp") == 0)
5665471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_FTP;
567db522d3aSSimon L. B. Nielsen 			else if (strcmp(*argv, "xmpp") == 0)
568db522d3aSSimon L. B. Nielsen 				starttls_proto = PROTO_XMPP;
5695c87c606SMark Murray 			else
5705c87c606SMark Murray 				goto bad;
5715c87c606SMark Murray 			}
572fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
5735c87c606SMark Murray 		else if	(strcmp(*argv,"-engine") == 0)
5745c87c606SMark Murray 			{
5755c87c606SMark Murray 			if (--argc < 1) goto bad;
5765c87c606SMark Murray 			engine_id = *(++argv);
5775c87c606SMark Murray 			}
578db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
579db522d3aSSimon L. B. Nielsen 			{
580db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
581db522d3aSSimon L. B. Nielsen 			ssl_client_engine_id = *(++argv);
582db522d3aSSimon L. B. Nielsen 			}
583fceca8a3SJacques Vidrine #endif
5845740a5e3SKris Kennaway 		else if (strcmp(*argv,"-rand") == 0)
5855740a5e3SKris Kennaway 			{
5865740a5e3SKris Kennaway 			if (--argc < 1) goto bad;
5875740a5e3SKris Kennaway 			inrand= *(++argv);
5885740a5e3SKris Kennaway 			}
589db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
590db522d3aSSimon L. B. Nielsen 		else if (strcmp(*argv,"-servername") == 0)
591db522d3aSSimon L. B. Nielsen 			{
592db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
593db522d3aSSimon L. B. Nielsen 			servername= *(++argv);
594db522d3aSSimon L. B. Nielsen 			/* meth=TLSv1_client_method(); */
595db522d3aSSimon L. B. Nielsen 			}
596db522d3aSSimon L. B. Nielsen #endif
597db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
598db522d3aSSimon L. B. Nielsen 		else if (strcmp(*argv,"-jpake") == 0)
599db522d3aSSimon L. B. Nielsen 			{
600db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
601db522d3aSSimon L. B. Nielsen 			jpake_secret = *++argv;
602db522d3aSSimon L. B. Nielsen 			}
603db522d3aSSimon L. B. Nielsen #endif
60474664626SKris Kennaway 		else
60574664626SKris Kennaway 			{
60674664626SKris Kennaway 			BIO_printf(bio_err,"unknown option %s\n",*argv);
60774664626SKris Kennaway 			badop=1;
60874664626SKris Kennaway 			break;
60974664626SKris Kennaway 			}
61074664626SKris Kennaway 		argc--;
61174664626SKris Kennaway 		argv++;
61274664626SKris Kennaway 		}
61374664626SKris Kennaway 	if (badop)
61474664626SKris Kennaway 		{
61574664626SKris Kennaway bad:
61674664626SKris Kennaway 		sc_usage();
61774664626SKris Kennaway 		goto end;
61874664626SKris Kennaway 		}
61974664626SKris Kennaway 
6205c87c606SMark Murray 	OpenSSL_add_ssl_algorithms();
6215c87c606SMark Murray 	SSL_load_error_strings();
6225c87c606SMark Murray 
623fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
6245c87c606SMark Murray         e = setup_engine(bio_err, engine_id, 1);
625db522d3aSSimon L. B. Nielsen 	if (ssl_client_engine_id)
626db522d3aSSimon L. B. Nielsen 		{
627db522d3aSSimon L. B. Nielsen 		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
628db522d3aSSimon L. B. Nielsen 		if (!ssl_client_engine)
629db522d3aSSimon L. B. Nielsen 			{
630db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err,
631db522d3aSSimon L. B. Nielsen 					"Error getting client auth engine\n");
632db522d3aSSimon L. B. Nielsen 			goto end;
633db522d3aSSimon L. B. Nielsen 			}
634db522d3aSSimon L. B. Nielsen 		}
635fceca8a3SJacques Vidrine #endif
6363b4e3dcbSSimon L. B. Nielsen 	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
6373b4e3dcbSSimon L. B. Nielsen 		{
6383b4e3dcbSSimon L. B. Nielsen 		BIO_printf(bio_err, "Error getting password\n");
6393b4e3dcbSSimon L. B. Nielsen 		goto end;
6403b4e3dcbSSimon L. B. Nielsen 		}
6413b4e3dcbSSimon L. B. Nielsen 
6423b4e3dcbSSimon L. B. Nielsen 	if (key_file == NULL)
6433b4e3dcbSSimon L. B. Nielsen 		key_file = cert_file;
6443b4e3dcbSSimon L. B. Nielsen 
6453b4e3dcbSSimon L. B. Nielsen 
6463b4e3dcbSSimon L. B. Nielsen 	if (key_file)
6473b4e3dcbSSimon L. B. Nielsen 
6483b4e3dcbSSimon L. B. Nielsen 		{
6493b4e3dcbSSimon L. B. Nielsen 
6503b4e3dcbSSimon L. B. Nielsen 		key = load_key(bio_err, key_file, key_format, 0, pass, e,
6513b4e3dcbSSimon L. B. Nielsen 			       "client certificate private key file");
6523b4e3dcbSSimon L. B. Nielsen 		if (!key)
6533b4e3dcbSSimon L. B. Nielsen 			{
6543b4e3dcbSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
6553b4e3dcbSSimon L. B. Nielsen 			goto end;
6563b4e3dcbSSimon L. B. Nielsen 			}
6573b4e3dcbSSimon L. B. Nielsen 
6583b4e3dcbSSimon L. B. Nielsen 		}
6593b4e3dcbSSimon L. B. Nielsen 
6603b4e3dcbSSimon L. B. Nielsen 	if (cert_file)
6613b4e3dcbSSimon L. B. Nielsen 
6623b4e3dcbSSimon L. B. Nielsen 		{
6633b4e3dcbSSimon L. B. Nielsen 		cert = load_cert(bio_err,cert_file,cert_format,
6643b4e3dcbSSimon L. B. Nielsen 				NULL, e, "client certificate file");
6653b4e3dcbSSimon L. B. Nielsen 
6663b4e3dcbSSimon L. B. Nielsen 		if (!cert)
6673b4e3dcbSSimon L. B. Nielsen 			{
6683b4e3dcbSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
6693b4e3dcbSSimon L. B. Nielsen 			goto end;
6703b4e3dcbSSimon L. B. Nielsen 			}
6713b4e3dcbSSimon L. B. Nielsen 		}
6725c87c606SMark Murray 
6735740a5e3SKris Kennaway 	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
6745740a5e3SKris Kennaway 		&& !RAND_status())
6755740a5e3SKris Kennaway 		{
6765740a5e3SKris Kennaway 		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
6775740a5e3SKris Kennaway 		}
6785740a5e3SKris Kennaway 	if (inrand != NULL)
6795740a5e3SKris Kennaway 		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
6805740a5e3SKris Kennaway 			app_RAND_load_files(inrand));
681f579bf8eSKris Kennaway 
68274664626SKris Kennaway 	if (bio_c_out == NULL)
68374664626SKris Kennaway 		{
6845c87c606SMark Murray 		if (c_quiet && !c_debug && !c_msg)
68574664626SKris Kennaway 			{
68674664626SKris Kennaway 			bio_c_out=BIO_new(BIO_s_null());
68774664626SKris Kennaway 			}
68874664626SKris Kennaway 		else
68974664626SKris Kennaway 			{
69074664626SKris Kennaway 			if (bio_c_out == NULL)
69174664626SKris Kennaway 				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
69274664626SKris Kennaway 			}
69374664626SKris Kennaway 		}
69474664626SKris Kennaway 
69574664626SKris Kennaway 	ctx=SSL_CTX_new(meth);
69674664626SKris Kennaway 	if (ctx == NULL)
69774664626SKris Kennaway 		{
69874664626SKris Kennaway 		ERR_print_errors(bio_err);
69974664626SKris Kennaway 		goto end;
70074664626SKris Kennaway 		}
70174664626SKris Kennaway 
702db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_ENGINE
703db522d3aSSimon L. B. Nielsen 	if (ssl_client_engine)
704db522d3aSSimon L. B. Nielsen 		{
705db522d3aSSimon L. B. Nielsen 		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
706db522d3aSSimon L. B. Nielsen 			{
707db522d3aSSimon L. B. Nielsen 			BIO_puts(bio_err, "Error setting client auth engine\n");
708db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
709db522d3aSSimon L. B. Nielsen 			ENGINE_free(ssl_client_engine);
710db522d3aSSimon L. B. Nielsen 			goto end;
711db522d3aSSimon L. B. Nielsen 			}
712db522d3aSSimon L. B. Nielsen 		ENGINE_free(ssl_client_engine);
713db522d3aSSimon L. B. Nielsen 		}
714db522d3aSSimon L. B. Nielsen #endif
715db522d3aSSimon L. B. Nielsen 
71674664626SKris Kennaway 	if (bugs)
71774664626SKris Kennaway 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
71874664626SKris Kennaway 	else
71974664626SKris Kennaway 		SSL_CTX_set_options(ctx,off);
7206a599222SSimon L. B. Nielsen 
7216a599222SSimon L. B. Nielsen 	if (clr)
7226a599222SSimon L. B. Nielsen 		SSL_CTX_clear_options(ctx, clr);
7233b4e3dcbSSimon L. B. Nielsen 	/* DTLS: partial reads end up discarding unread UDP bytes :-(
7243b4e3dcbSSimon L. B. Nielsen 	 * Setting read ahead solves this problem.
7253b4e3dcbSSimon L. B. Nielsen 	 */
7263b4e3dcbSSimon L. B. Nielsen 	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
72774664626SKris Kennaway 
72874664626SKris Kennaway 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
72974664626SKris Kennaway 	if (cipher != NULL)
730f579bf8eSKris Kennaway 		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
731f579bf8eSKris Kennaway 		BIO_printf(bio_err,"error setting cipher list\n");
732f579bf8eSKris Kennaway 		ERR_print_errors(bio_err);
733f579bf8eSKris Kennaway 		goto end;
734f579bf8eSKris Kennaway 	}
73574664626SKris Kennaway #if 0
73674664626SKris Kennaway 	else
73774664626SKris Kennaway 		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
73874664626SKris Kennaway #endif
73974664626SKris Kennaway 
74074664626SKris Kennaway 	SSL_CTX_set_verify(ctx,verify,verify_callback);
7413b4e3dcbSSimon L. B. Nielsen 	if (!set_cert_key_stuff(ctx,cert,key))
74274664626SKris Kennaway 		goto end;
74374664626SKris Kennaway 
74474664626SKris Kennaway 	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
74574664626SKris Kennaway 		(!SSL_CTX_set_default_verify_paths(ctx)))
74674664626SKris Kennaway 		{
747f579bf8eSKris Kennaway 		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
74874664626SKris Kennaway 		ERR_print_errors(bio_err);
74974664626SKris Kennaway 		/* goto end; */
75074664626SKris Kennaway 		}
75174664626SKris Kennaway 
7525c87c606SMark Murray 	store = SSL_CTX_get_cert_store(ctx);
7535c87c606SMark Murray 	X509_STORE_set_flags(store, vflags);
754db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
755db522d3aSSimon L. B. Nielsen 	if (servername != NULL)
756db522d3aSSimon L. B. Nielsen 		{
757db522d3aSSimon L. B. Nielsen 		tlsextcbp.biodebug = bio_err;
758db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
759db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
760db522d3aSSimon L. B. Nielsen 		}
761db522d3aSSimon L. B. Nielsen #endif
76274664626SKris Kennaway 
763f579bf8eSKris Kennaway 	con=SSL_new(ctx);
764db522d3aSSimon L. B. Nielsen 	if (sess_in)
765db522d3aSSimon L. B. Nielsen 		{
766db522d3aSSimon L. B. Nielsen 		SSL_SESSION *sess;
767db522d3aSSimon L. B. Nielsen 		BIO *stmp = BIO_new_file(sess_in, "r");
768db522d3aSSimon L. B. Nielsen 		if (!stmp)
769db522d3aSSimon L. B. Nielsen 			{
770db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err, "Can't open session file %s\n",
771db522d3aSSimon L. B. Nielsen 						sess_in);
772db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
773db522d3aSSimon L. B. Nielsen 			goto end;
774db522d3aSSimon L. B. Nielsen 			}
775db522d3aSSimon L. B. Nielsen 		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
776db522d3aSSimon L. B. Nielsen 		BIO_free(stmp);
777db522d3aSSimon L. B. Nielsen 		if (!sess)
778db522d3aSSimon L. B. Nielsen 			{
779db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err, "Can't open session file %s\n",
780db522d3aSSimon L. B. Nielsen 						sess_in);
781db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
782db522d3aSSimon L. B. Nielsen 			goto end;
783db522d3aSSimon L. B. Nielsen 			}
784db522d3aSSimon L. B. Nielsen 		SSL_set_session(con, sess);
785db522d3aSSimon L. B. Nielsen 		SSL_SESSION_free(sess);
786db522d3aSSimon L. B. Nielsen 		}
787db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
788db522d3aSSimon L. B. Nielsen 	if (servername != NULL)
789db522d3aSSimon L. B. Nielsen 		{
790db522d3aSSimon L. B. Nielsen 		if (!SSL_set_tlsext_host_name(con,servername))
791db522d3aSSimon L. B. Nielsen 			{
792db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
793db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
794db522d3aSSimon L. B. Nielsen 			goto end;
795db522d3aSSimon L. B. Nielsen 			}
796db522d3aSSimon L. B. Nielsen 		}
797db522d3aSSimon L. B. Nielsen #endif
798db522d3aSSimon L. B. Nielsen 
7995c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
8005c87c606SMark Murray 	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
8015c87c606SMark Murray                 {
8025c87c606SMark Murray                 kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
8035c87c606SMark Murray 		}
8045c87c606SMark Murray #endif	/* OPENSSL_NO_KRB5  */
80574664626SKris Kennaway /*	SSL_set_cipher_list(con,"RC4-MD5"); */
80674664626SKris Kennaway 
80774664626SKris Kennaway re_start:
80874664626SKris Kennaway 
8093b4e3dcbSSimon L. B. Nielsen 	if (init_client(&s,host,port,sock_type) == 0)
81074664626SKris Kennaway 		{
81174664626SKris Kennaway 		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
81274664626SKris Kennaway 		SHUTDOWN(s);
81374664626SKris Kennaway 		goto end;
81474664626SKris Kennaway 		}
81574664626SKris Kennaway 	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
81674664626SKris Kennaway 
81774664626SKris Kennaway #ifdef FIONBIO
81874664626SKris Kennaway 	if (c_nbio)
81974664626SKris Kennaway 		{
82074664626SKris Kennaway 		unsigned long l=1;
82174664626SKris Kennaway 		BIO_printf(bio_c_out,"turning on non blocking io\n");
82274664626SKris Kennaway 		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
82374664626SKris Kennaway 			{
82474664626SKris Kennaway 			ERR_print_errors(bio_err);
82574664626SKris Kennaway 			goto end;
82674664626SKris Kennaway 			}
82774664626SKris Kennaway 		}
82874664626SKris Kennaway #endif
82974664626SKris Kennaway 	if (c_Pause & 0x01) con->debug=1;
8303b4e3dcbSSimon L. B. Nielsen 
8313b4e3dcbSSimon L. B. Nielsen 	if ( SSL_version(con) == DTLS1_VERSION)
8323b4e3dcbSSimon L. B. Nielsen 		{
8333b4e3dcbSSimon L. B. Nielsen 
8343b4e3dcbSSimon L. B. Nielsen 		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
8353b4e3dcbSSimon L. B. Nielsen 		if (getsockname(s, &peer, (void *)&peerlen) < 0)
8363b4e3dcbSSimon L. B. Nielsen 			{
8373b4e3dcbSSimon L. B. Nielsen 			BIO_printf(bio_err, "getsockname:errno=%d\n",
8383b4e3dcbSSimon L. B. Nielsen 				get_last_socket_error());
8393b4e3dcbSSimon L. B. Nielsen 			SHUTDOWN(s);
8403b4e3dcbSSimon L. B. Nielsen 			goto end;
8413b4e3dcbSSimon L. B. Nielsen 			}
8423b4e3dcbSSimon L. B. Nielsen 
843db522d3aSSimon L. B. Nielsen 		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
8443b4e3dcbSSimon L. B. Nielsen 
8453b4e3dcbSSimon L. B. Nielsen 		if ( enable_timeouts)
8463b4e3dcbSSimon L. B. Nielsen 			{
8473b4e3dcbSSimon L. B. Nielsen 			timeout.tv_sec = 0;
8483b4e3dcbSSimon L. B. Nielsen 			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
8493b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
8503b4e3dcbSSimon L. B. Nielsen 
8513b4e3dcbSSimon L. B. Nielsen 			timeout.tv_sec = 0;
8523b4e3dcbSSimon L. B. Nielsen 			timeout.tv_usec = DGRAM_SND_TIMEOUT;
8533b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
8543b4e3dcbSSimon L. B. Nielsen 			}
8553b4e3dcbSSimon L. B. Nielsen 
8566a599222SSimon L. B. Nielsen 		if (socket_mtu > 28)
8573b4e3dcbSSimon L. B. Nielsen 			{
8583b4e3dcbSSimon L. B. Nielsen 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
8596a599222SSimon L. B. Nielsen 			SSL_set_mtu(con, socket_mtu - 28);
8603b4e3dcbSSimon L. B. Nielsen 			}
8613b4e3dcbSSimon L. B. Nielsen 		else
8623b4e3dcbSSimon L. B. Nielsen 			/* want to do MTU discovery */
8633b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
8643b4e3dcbSSimon L. B. Nielsen 		}
8653b4e3dcbSSimon L. B. Nielsen 	else
86674664626SKris Kennaway 		sbio=BIO_new_socket(s,BIO_NOCLOSE);
86774664626SKris Kennaway 
86874664626SKris Kennaway 	if (nbio_test)
86974664626SKris Kennaway 		{
87074664626SKris Kennaway 		BIO *test;
87174664626SKris Kennaway 
87274664626SKris Kennaway 		test=BIO_new(BIO_f_nbio_test());
87374664626SKris Kennaway 		sbio=BIO_push(test,sbio);
87474664626SKris Kennaway 		}
87574664626SKris Kennaway 
87674664626SKris Kennaway 	if (c_debug)
87774664626SKris Kennaway 		{
87874664626SKris Kennaway 		con->debug=1;
8793b4e3dcbSSimon L. B. Nielsen 		BIO_set_callback(sbio,bio_dump_callback);
8805471f83eSSimon L. B. Nielsen 		BIO_set_callback_arg(sbio,(char *)bio_c_out);
88174664626SKris Kennaway 		}
8825c87c606SMark Murray 	if (c_msg)
8835c87c606SMark Murray 		{
8845c87c606SMark Murray 		SSL_set_msg_callback(con, msg_cb);
8855c87c606SMark Murray 		SSL_set_msg_callback_arg(con, bio_c_out);
8865c87c606SMark Murray 		}
887db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
888db522d3aSSimon L. B. Nielsen 	if (c_tlsextdebug)
889db522d3aSSimon L. B. Nielsen 		{
890db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_debug_callback(con, tlsext_cb);
891db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_debug_arg(con, bio_c_out);
892db522d3aSSimon L. B. Nielsen 		}
893db522d3aSSimon L. B. Nielsen 	if (c_status_req)
894db522d3aSSimon L. B. Nielsen 		{
895db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
896db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
897db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
898db522d3aSSimon L. B. Nielsen #if 0
899db522d3aSSimon L. B. Nielsen {
900db522d3aSSimon L. B. Nielsen STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
901db522d3aSSimon L. B. Nielsen OCSP_RESPID *id = OCSP_RESPID_new();
902db522d3aSSimon L. B. Nielsen id->value.byKey = ASN1_OCTET_STRING_new();
903db522d3aSSimon L. B. Nielsen id->type = V_OCSP_RESPID_KEY;
904db522d3aSSimon L. B. Nielsen ASN1_STRING_set(id->value.byKey, "Hello World", -1);
905db522d3aSSimon L. B. Nielsen sk_OCSP_RESPID_push(ids, id);
906db522d3aSSimon L. B. Nielsen SSL_set_tlsext_status_ids(con, ids);
907db522d3aSSimon L. B. Nielsen }
908db522d3aSSimon L. B. Nielsen #endif
909db522d3aSSimon L. B. Nielsen 		}
910db522d3aSSimon L. B. Nielsen #endif
911db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
912db522d3aSSimon L. B. Nielsen 	if (jpake_secret)
913db522d3aSSimon L. B. Nielsen 		jpake_client_auth(bio_c_out, sbio, jpake_secret);
914db522d3aSSimon L. B. Nielsen #endif
91574664626SKris Kennaway 
91674664626SKris Kennaway 	SSL_set_bio(con,sbio,sbio);
91774664626SKris Kennaway 	SSL_set_connect_state(con);
91874664626SKris Kennaway 
91974664626SKris Kennaway 	/* ok, lets connect */
92074664626SKris Kennaway 	width=SSL_get_fd(con)+1;
92174664626SKris Kennaway 
92274664626SKris Kennaway 	read_tty=1;
92374664626SKris Kennaway 	write_tty=0;
92474664626SKris Kennaway 	tty_on=0;
92574664626SKris Kennaway 	read_ssl=1;
92674664626SKris Kennaway 	write_ssl=1;
92774664626SKris Kennaway 
92874664626SKris Kennaway 	cbuf_len=0;
92974664626SKris Kennaway 	cbuf_off=0;
93074664626SKris Kennaway 	sbuf_len=0;
93174664626SKris Kennaway 	sbuf_off=0;
93274664626SKris Kennaway 
9335c87c606SMark Murray 	/* This is an ugly hack that does a lot of assumptions */
9345471f83eSSimon L. B. Nielsen 	/* We do have to handle multi-line responses which may come
9355471f83eSSimon L. B. Nielsen  	   in a single packet or not. We therefore have to use
9365471f83eSSimon L. B. Nielsen 	   BIO_gets() which does need a buffering BIO. So during
9375471f83eSSimon L. B. Nielsen 	   the initial chitchat we do push a buffering BIO into the
9385471f83eSSimon L. B. Nielsen 	   chain that is removed again later on to not disturb the
9395471f83eSSimon L. B. Nielsen 	   rest of the s_client operation. */
9405471f83eSSimon L. B. Nielsen 	if (starttls_proto == PROTO_SMTP)
9415c87c606SMark Murray 		{
9425471f83eSSimon L. B. Nielsen 		int foundit=0;
9435471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
9445471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
9455471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end from SMTP */
9465471f83eSSimon L. B. Nielsen 		do
9475471f83eSSimon L. B. Nielsen 			{
9485471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9495471f83eSSimon L. B. Nielsen 			}
9505471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
9515471f83eSSimon L. B. Nielsen 		/* STARTTLS command requires EHLO... */
9525471f83eSSimon L. B. Nielsen 		BIO_printf(fbio,"EHLO openssl.client.net\r\n");
953db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9545471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end EHLO SMTP response */
9555471f83eSSimon L. B. Nielsen 		do
9565471f83eSSimon L. B. Nielsen 			{
9575471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9585471f83eSSimon L. B. Nielsen 			if (strstr(mbuf,"STARTTLS"))
9595471f83eSSimon L. B. Nielsen 				foundit=1;
9605471f83eSSimon L. B. Nielsen 			}
9615471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
962db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9635471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
9645471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
9655471f83eSSimon L. B. Nielsen 		if (!foundit)
9665471f83eSSimon L. B. Nielsen 			BIO_printf(bio_err,
9675471f83eSSimon L. B. Nielsen 				   "didn't found starttls in server response,"
9685471f83eSSimon L. B. Nielsen 				   " try anyway...\n");
9695c87c606SMark Murray 		BIO_printf(sbio,"STARTTLS\r\n");
9705c87c606SMark Murray 		BIO_read(sbio,sbuf,BUFSIZZ);
9715c87c606SMark Murray 		}
9725471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_POP3)
97350ef0093SJacques Vidrine 		{
97450ef0093SJacques Vidrine 		BIO_read(sbio,mbuf,BUFSIZZ);
97550ef0093SJacques Vidrine 		BIO_printf(sbio,"STLS\r\n");
97650ef0093SJacques Vidrine 		BIO_read(sbio,sbuf,BUFSIZZ);
97750ef0093SJacques Vidrine 		}
9785471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_IMAP)
9795471f83eSSimon L. B. Nielsen 		{
9805471f83eSSimon L. B. Nielsen 		int foundit=0;
9815471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
9825471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
9835471f83eSSimon L. B. Nielsen 		BIO_gets(fbio,mbuf,BUFSIZZ);
9845471f83eSSimon L. B. Nielsen 		/* STARTTLS command requires CAPABILITY... */
9855471f83eSSimon L. B. Nielsen 		BIO_printf(fbio,". CAPABILITY\r\n");
986db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9875471f83eSSimon L. B. Nielsen 		/* wait for multi-line CAPABILITY response */
9885471f83eSSimon L. B. Nielsen 		do
9895471f83eSSimon L. B. Nielsen 			{
9905471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9915471f83eSSimon L. B. Nielsen 			if (strstr(mbuf,"STARTTLS"))
9925471f83eSSimon L. B. Nielsen 				foundit=1;
9935471f83eSSimon L. B. Nielsen 			}
9945471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[0]!='.');
995db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9965471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
9975471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
9985471f83eSSimon L. B. Nielsen 		if (!foundit)
9995471f83eSSimon L. B. Nielsen 			BIO_printf(bio_err,
10005471f83eSSimon L. B. Nielsen 				   "didn't found STARTTLS in server response,"
10015471f83eSSimon L. B. Nielsen 				   " try anyway...\n");
10025471f83eSSimon L. B. Nielsen 		BIO_printf(sbio,". STARTTLS\r\n");
10035471f83eSSimon L. B. Nielsen 		BIO_read(sbio,sbuf,BUFSIZZ);
10045471f83eSSimon L. B. Nielsen 		}
10055471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_FTP)
10065471f83eSSimon L. B. Nielsen 		{
10075471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
10085471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
10095471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end from FTP */
10105471f83eSSimon L. B. Nielsen 		do
10115471f83eSSimon L. B. Nielsen 			{
10125471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
10135471f83eSSimon L. B. Nielsen 			}
10145471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
1015db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
10165471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
10175471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
10185471f83eSSimon L. B. Nielsen 		BIO_printf(sbio,"AUTH TLS\r\n");
10195471f83eSSimon L. B. Nielsen 		BIO_read(sbio,sbuf,BUFSIZZ);
10205471f83eSSimon L. B. Nielsen 		}
1021db522d3aSSimon L. B. Nielsen 	if (starttls_proto == PROTO_XMPP)
1022db522d3aSSimon L. B. Nielsen 		{
1023db522d3aSSimon L. B. Nielsen 		int seen = 0;
1024db522d3aSSimon L. B. Nielsen 		BIO_printf(sbio,"<stream:stream "
1025db522d3aSSimon L. B. Nielsen 		    "xmlns:stream='http://etherx.jabber.org/streams' "
1026db522d3aSSimon L. B. Nielsen 		    "xmlns='jabber:client' to='%s' version='1.0'>", host);
1027db522d3aSSimon L. B. Nielsen 		seen = BIO_read(sbio,mbuf,BUFSIZZ);
1028db522d3aSSimon L. B. Nielsen 		mbuf[seen] = 0;
1029db522d3aSSimon L. B. Nielsen 		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
1030db522d3aSSimon L. B. Nielsen 			{
1031db522d3aSSimon L. B. Nielsen 			if (strstr(mbuf, "/stream:features>"))
1032db522d3aSSimon L. B. Nielsen 				goto shut;
1033db522d3aSSimon L. B. Nielsen 			seen = BIO_read(sbio,mbuf,BUFSIZZ);
1034db522d3aSSimon L. B. Nielsen 			mbuf[seen] = 0;
1035db522d3aSSimon L. B. Nielsen 			}
1036db522d3aSSimon L. B. Nielsen 		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1037db522d3aSSimon L. B. Nielsen 		seen = BIO_read(sbio,sbuf,BUFSIZZ);
1038db522d3aSSimon L. B. Nielsen 		sbuf[seen] = 0;
1039db522d3aSSimon L. B. Nielsen 		if (!strstr(sbuf, "<proceed"))
1040db522d3aSSimon L. B. Nielsen 			goto shut;
1041db522d3aSSimon L. B. Nielsen 		mbuf[0] = 0;
1042db522d3aSSimon L. B. Nielsen 		}
10435c87c606SMark Murray 
104474664626SKris Kennaway 	for (;;)
104574664626SKris Kennaway 		{
104674664626SKris Kennaway 		FD_ZERO(&readfds);
104774664626SKris Kennaway 		FD_ZERO(&writefds);
104874664626SKris Kennaway 
10496a599222SSimon L. B. Nielsen 		if ((SSL_version(con) == DTLS1_VERSION) &&
10506a599222SSimon L. B. Nielsen 			DTLSv1_get_timeout(con, &timeout))
10516a599222SSimon L. B. Nielsen 			timeoutp = &timeout;
10526a599222SSimon L. B. Nielsen 		else
10536a599222SSimon L. B. Nielsen 			timeoutp = NULL;
10546a599222SSimon L. B. Nielsen 
105574664626SKris Kennaway 		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
105674664626SKris Kennaway 			{
105774664626SKris Kennaway 			in_init=1;
105874664626SKris Kennaway 			tty_on=0;
105974664626SKris Kennaway 			}
106074664626SKris Kennaway 		else
106174664626SKris Kennaway 			{
106274664626SKris Kennaway 			tty_on=1;
106374664626SKris Kennaway 			if (in_init)
106474664626SKris Kennaway 				{
106574664626SKris Kennaway 				in_init=0;
1066db522d3aSSimon L. B. Nielsen 				if (sess_out)
1067db522d3aSSimon L. B. Nielsen 					{
1068db522d3aSSimon L. B. Nielsen 					BIO *stmp = BIO_new_file(sess_out, "w");
1069db522d3aSSimon L. B. Nielsen 					if (stmp)
1070db522d3aSSimon L. B. Nielsen 						{
1071db522d3aSSimon L. B. Nielsen 						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
1072db522d3aSSimon L. B. Nielsen 						BIO_free(stmp);
1073db522d3aSSimon L. B. Nielsen 						}
1074db522d3aSSimon L. B. Nielsen 					else
1075db522d3aSSimon L. B. Nielsen 						BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
1076db522d3aSSimon L. B. Nielsen 					}
107774664626SKris Kennaway 				print_stuff(bio_c_out,con,full_log);
107874664626SKris Kennaway 				if (full_log > 0) full_log--;
107974664626SKris Kennaway 
108050ef0093SJacques Vidrine 				if (starttls_proto)
10815c87c606SMark Murray 					{
10825c87c606SMark Murray 					BIO_printf(bio_err,"%s",mbuf);
10835c87c606SMark Murray 					/* We don't need to know any more */
10845471f83eSSimon L. B. Nielsen 					starttls_proto = PROTO_OFF;
10855c87c606SMark Murray 					}
10865c87c606SMark Murray 
108774664626SKris Kennaway 				if (reconnect)
108874664626SKris Kennaway 					{
108974664626SKris Kennaway 					reconnect--;
109074664626SKris Kennaway 					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
109174664626SKris Kennaway 					SSL_shutdown(con);
109274664626SKris Kennaway 					SSL_set_connect_state(con);
109374664626SKris Kennaway 					SHUTDOWN(SSL_get_fd(con));
109474664626SKris Kennaway 					goto re_start;
109574664626SKris Kennaway 					}
109674664626SKris Kennaway 				}
109774664626SKris Kennaway 			}
109874664626SKris Kennaway 
109974664626SKris Kennaway 		ssl_pending = read_ssl && SSL_pending(con);
110074664626SKris Kennaway 
110174664626SKris Kennaway 		if (!ssl_pending)
110274664626SKris Kennaway 			{
11033b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
110474664626SKris Kennaway 			if (tty_on)
110574664626SKris Kennaway 				{
110674664626SKris Kennaway 				if (read_tty)  FD_SET(fileno(stdin),&readfds);
110774664626SKris Kennaway 				if (write_tty) FD_SET(fileno(stdout),&writefds);
110874664626SKris Kennaway 				}
110974664626SKris Kennaway 			if (read_ssl)
111074664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&readfds);
111174664626SKris Kennaway 			if (write_ssl)
111274664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&writefds);
1113f579bf8eSKris Kennaway #else
1114f579bf8eSKris Kennaway 			if(!tty_on || !write_tty) {
1115f579bf8eSKris Kennaway 				if (read_ssl)
1116f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&readfds);
1117f579bf8eSKris Kennaway 				if (write_ssl)
1118f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&writefds);
1119f579bf8eSKris Kennaway 			}
1120f579bf8eSKris Kennaway #endif
112174664626SKris Kennaway /*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
112274664626SKris Kennaway 				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
112374664626SKris Kennaway 
112474664626SKris Kennaway 			/* Note: under VMS with SOCKETSHR the second parameter
112574664626SKris Kennaway 			 * is currently of type (int *) whereas under other
112674664626SKris Kennaway 			 * systems it is (void *) if you don't have a cast it
112774664626SKris Kennaway 			 * will choke the compiler: if you do have a cast then
112874664626SKris Kennaway 			 * you can either go for (int *) or (void *).
112974664626SKris Kennaway 			 */
113050ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
113150ef0093SJacques Vidrine                         /* Under Windows/DOS we make the assumption that we can
1132f579bf8eSKris Kennaway 			 * always write to the tty: therefore if we need to
1133f579bf8eSKris Kennaway 			 * write to the tty we just fall through. Otherwise
1134f579bf8eSKris Kennaway 			 * we timeout the select every second and see if there
1135f579bf8eSKris Kennaway 			 * are any keypresses. Note: this is a hack, in a proper
1136f579bf8eSKris Kennaway 			 * Windows application we wouldn't do this.
1137f579bf8eSKris Kennaway 			 */
1138f579bf8eSKris Kennaway 			i=0;
1139f579bf8eSKris Kennaway 			if(!write_tty) {
1140f579bf8eSKris Kennaway 				if(read_tty) {
1141f579bf8eSKris Kennaway 					tv.tv_sec = 1;
1142f579bf8eSKris Kennaway 					tv.tv_usec = 0;
1143f579bf8eSKris Kennaway 					i=select(width,(void *)&readfds,(void *)&writefds,
1144f579bf8eSKris Kennaway 						 NULL,&tv);
114550ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
11465c87c606SMark Murray 					if(!i && (!_kbhit() || !read_tty) ) continue;
11475c87c606SMark Murray #else
1148ddd58736SKris Kennaway 					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
11495c87c606SMark Murray #endif
1150f579bf8eSKris Kennaway 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
11516a599222SSimon L. B. Nielsen 					 NULL,timeoutp);
1152f579bf8eSKris Kennaway 			}
11533b4e3dcbSSimon L. B. Nielsen #elif defined(OPENSSL_SYS_NETWARE)
11543b4e3dcbSSimon L. B. Nielsen 			if(!write_tty) {
11553b4e3dcbSSimon L. B. Nielsen 				if(read_tty) {
11563b4e3dcbSSimon L. B. Nielsen 					tv.tv_sec = 1;
11573b4e3dcbSSimon L. B. Nielsen 					tv.tv_usec = 0;
11583b4e3dcbSSimon L. B. Nielsen 					i=select(width,(void *)&readfds,(void *)&writefds,
11593b4e3dcbSSimon L. B. Nielsen 						NULL,&tv);
11603b4e3dcbSSimon L. B. Nielsen 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
11616a599222SSimon L. B. Nielsen 					NULL,timeoutp);
11623b4e3dcbSSimon L. B. Nielsen 			}
1163f579bf8eSKris Kennaway #else
116474664626SKris Kennaway 			i=select(width,(void *)&readfds,(void *)&writefds,
11656a599222SSimon L. B. Nielsen 				 NULL,timeoutp);
1166f579bf8eSKris Kennaway #endif
116774664626SKris Kennaway 			if ( i < 0)
116874664626SKris Kennaway 				{
116974664626SKris Kennaway 				BIO_printf(bio_err,"bad select %d\n",
117074664626SKris Kennaway 				get_last_socket_error());
117174664626SKris Kennaway 				goto shut;
117274664626SKris Kennaway 				/* goto end; */
117374664626SKris Kennaway 				}
117474664626SKris Kennaway 			}
117574664626SKris Kennaway 
11766a599222SSimon L. B. Nielsen 		if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
11776a599222SSimon L. B. Nielsen 			{
11786a599222SSimon L. B. Nielsen 			BIO_printf(bio_err,"TIMEOUT occured\n");
11796a599222SSimon L. B. Nielsen 			}
11806a599222SSimon L. B. Nielsen 
118174664626SKris Kennaway 		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
118274664626SKris Kennaway 			{
118374664626SKris Kennaway 			k=SSL_write(con,&(cbuf[cbuf_off]),
118474664626SKris Kennaway 				(unsigned int)cbuf_len);
118574664626SKris Kennaway 			switch (SSL_get_error(con,k))
118674664626SKris Kennaway 				{
118774664626SKris Kennaway 			case SSL_ERROR_NONE:
118874664626SKris Kennaway 				cbuf_off+=k;
118974664626SKris Kennaway 				cbuf_len-=k;
119074664626SKris Kennaway 				if (k <= 0) goto end;
119174664626SKris Kennaway 				/* we have done a  write(con,NULL,0); */
119274664626SKris Kennaway 				if (cbuf_len <= 0)
119374664626SKris Kennaway 					{
119474664626SKris Kennaway 					read_tty=1;
119574664626SKris Kennaway 					write_ssl=0;
119674664626SKris Kennaway 					}
119774664626SKris Kennaway 				else /* if (cbuf_len > 0) */
119874664626SKris Kennaway 					{
119974664626SKris Kennaway 					read_tty=0;
120074664626SKris Kennaway 					write_ssl=1;
120174664626SKris Kennaway 					}
120274664626SKris Kennaway 				break;
120374664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
120474664626SKris Kennaway 				BIO_printf(bio_c_out,"write W BLOCK\n");
120574664626SKris Kennaway 				write_ssl=1;
120674664626SKris Kennaway 				read_tty=0;
120774664626SKris Kennaway 				break;
120874664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
120974664626SKris Kennaway 				BIO_printf(bio_c_out,"write R BLOCK\n");
121074664626SKris Kennaway 				write_tty=0;
121174664626SKris Kennaway 				read_ssl=1;
121274664626SKris Kennaway 				write_ssl=0;
121374664626SKris Kennaway 				break;
121474664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
121574664626SKris Kennaway 				BIO_printf(bio_c_out,"write X BLOCK\n");
121674664626SKris Kennaway 				break;
121774664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
121874664626SKris Kennaway 				if (cbuf_len != 0)
121974664626SKris Kennaway 					{
122074664626SKris Kennaway 					BIO_printf(bio_c_out,"shutdown\n");
122174664626SKris Kennaway 					goto shut;
122274664626SKris Kennaway 					}
122374664626SKris Kennaway 				else
122474664626SKris Kennaway 					{
122574664626SKris Kennaway 					read_tty=1;
122674664626SKris Kennaway 					write_ssl=0;
122774664626SKris Kennaway 					break;
122874664626SKris Kennaway 					}
122974664626SKris Kennaway 
123074664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
123174664626SKris Kennaway 				if ((k != 0) || (cbuf_len != 0))
123274664626SKris Kennaway 					{
123374664626SKris Kennaway 					BIO_printf(bio_err,"write:errno=%d\n",
123474664626SKris Kennaway 						get_last_socket_error());
123574664626SKris Kennaway 					goto shut;
123674664626SKris Kennaway 					}
123774664626SKris Kennaway 				else
123874664626SKris Kennaway 					{
123974664626SKris Kennaway 					read_tty=1;
124074664626SKris Kennaway 					write_ssl=0;
124174664626SKris Kennaway 					}
124274664626SKris Kennaway 				break;
124374664626SKris Kennaway 			case SSL_ERROR_SSL:
124474664626SKris Kennaway 				ERR_print_errors(bio_err);
124574664626SKris Kennaway 				goto shut;
124674664626SKris Kennaway 				}
124774664626SKris Kennaway 			}
12483b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
12495c87c606SMark Murray 		/* Assume Windows/DOS can always write */
1250f579bf8eSKris Kennaway 		else if (!ssl_pending && write_tty)
1251f579bf8eSKris Kennaway #else
125274664626SKris Kennaway 		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
1253f579bf8eSKris Kennaway #endif
125474664626SKris Kennaway 			{
125574664626SKris Kennaway #ifdef CHARSET_EBCDIC
125674664626SKris Kennaway 			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
125774664626SKris Kennaway #endif
125874664626SKris Kennaway 			i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
125974664626SKris Kennaway 
126074664626SKris Kennaway 			if (i <= 0)
126174664626SKris Kennaway 				{
126274664626SKris Kennaway 				BIO_printf(bio_c_out,"DONE\n");
126374664626SKris Kennaway 				goto shut;
126474664626SKris Kennaway 				/* goto end; */
126574664626SKris Kennaway 				}
126674664626SKris Kennaway 
126774664626SKris Kennaway 			sbuf_len-=i;;
126874664626SKris Kennaway 			sbuf_off+=i;
126974664626SKris Kennaway 			if (sbuf_len <= 0)
127074664626SKris Kennaway 				{
127174664626SKris Kennaway 				read_ssl=1;
127274664626SKris Kennaway 				write_tty=0;
127374664626SKris Kennaway 				}
127474664626SKris Kennaway 			}
127574664626SKris Kennaway 		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
127674664626SKris Kennaway 			{
127774664626SKris Kennaway #ifdef RENEG
127874664626SKris Kennaway { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
127974664626SKris Kennaway #endif
128074664626SKris Kennaway #if 1
128174664626SKris Kennaway 			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
128274664626SKris Kennaway #else
128374664626SKris Kennaway /* Demo for pending and peek :-) */
128474664626SKris Kennaway 			k=SSL_read(con,sbuf,16);
128574664626SKris Kennaway { char zbuf[10240];
128674664626SKris Kennaway printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
128774664626SKris Kennaway }
128874664626SKris Kennaway #endif
128974664626SKris Kennaway 
129074664626SKris Kennaway 			switch (SSL_get_error(con,k))
129174664626SKris Kennaway 				{
129274664626SKris Kennaway 			case SSL_ERROR_NONE:
129374664626SKris Kennaway 				if (k <= 0)
129474664626SKris Kennaway 					goto end;
129574664626SKris Kennaway 				sbuf_off=0;
129674664626SKris Kennaway 				sbuf_len=k;
129774664626SKris Kennaway 
129874664626SKris Kennaway 				read_ssl=0;
129974664626SKris Kennaway 				write_tty=1;
130074664626SKris Kennaway 				break;
130174664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
130274664626SKris Kennaway 				BIO_printf(bio_c_out,"read W BLOCK\n");
130374664626SKris Kennaway 				write_ssl=1;
130474664626SKris Kennaway 				read_tty=0;
130574664626SKris Kennaway 				break;
130674664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
130774664626SKris Kennaway 				BIO_printf(bio_c_out,"read R BLOCK\n");
130874664626SKris Kennaway 				write_tty=0;
130974664626SKris Kennaway 				read_ssl=1;
131074664626SKris Kennaway 				if ((read_tty == 0) && (write_ssl == 0))
131174664626SKris Kennaway 					write_ssl=1;
131274664626SKris Kennaway 				break;
131374664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
131474664626SKris Kennaway 				BIO_printf(bio_c_out,"read X BLOCK\n");
131574664626SKris Kennaway 				break;
131674664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
131774664626SKris Kennaway 				BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
131874664626SKris Kennaway 				goto shut;
131974664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
132074664626SKris Kennaway 				BIO_printf(bio_c_out,"closed\n");
132174664626SKris Kennaway 				goto shut;
132274664626SKris Kennaway 			case SSL_ERROR_SSL:
132374664626SKris Kennaway 				ERR_print_errors(bio_err);
132474664626SKris Kennaway 				goto shut;
132574664626SKris Kennaway 				/* break; */
132674664626SKris Kennaway 				}
132774664626SKris Kennaway 			}
132874664626SKris Kennaway 
132950ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
133050ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
13315c87c606SMark Murray 		else if (_kbhit())
13325c87c606SMark Murray #else
1333ddd58736SKris Kennaway 		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
13345c87c606SMark Murray #endif
13353b4e3dcbSSimon L. B. Nielsen #elif defined (OPENSSL_SYS_NETWARE)
13363b4e3dcbSSimon L. B. Nielsen         else if (_kbhit())
1337f579bf8eSKris Kennaway #else
133874664626SKris Kennaway 		else if (FD_ISSET(fileno(stdin),&readfds))
1339f579bf8eSKris Kennaway #endif
134074664626SKris Kennaway 			{
134174664626SKris Kennaway 			if (crlf)
134274664626SKris Kennaway 				{
134374664626SKris Kennaway 				int j, lf_num;
134474664626SKris Kennaway 
134574664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ/2);
134674664626SKris Kennaway 				lf_num = 0;
134774664626SKris Kennaway 				/* both loops are skipped when i <= 0 */
134874664626SKris Kennaway 				for (j = 0; j < i; j++)
134974664626SKris Kennaway 					if (cbuf[j] == '\n')
135074664626SKris Kennaway 						lf_num++;
135174664626SKris Kennaway 				for (j = i-1; j >= 0; j--)
135274664626SKris Kennaway 					{
135374664626SKris Kennaway 					cbuf[j+lf_num] = cbuf[j];
135474664626SKris Kennaway 					if (cbuf[j] == '\n')
135574664626SKris Kennaway 						{
135674664626SKris Kennaway 						lf_num--;
135774664626SKris Kennaway 						i++;
135874664626SKris Kennaway 						cbuf[j+lf_num] = '\r';
135974664626SKris Kennaway 						}
136074664626SKris Kennaway 					}
136174664626SKris Kennaway 				assert(lf_num == 0);
136274664626SKris Kennaway 				}
136374664626SKris Kennaway 			else
136474664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ);
136574664626SKris Kennaway 
1366f579bf8eSKris Kennaway 			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
136774664626SKris Kennaway 				{
136874664626SKris Kennaway 				BIO_printf(bio_err,"DONE\n");
136974664626SKris Kennaway 				goto shut;
137074664626SKris Kennaway 				}
137174664626SKris Kennaway 
1372f579bf8eSKris Kennaway 			if ((!c_ign_eof) && (cbuf[0] == 'R'))
137374664626SKris Kennaway 				{
137474664626SKris Kennaway 				BIO_printf(bio_err,"RENEGOTIATING\n");
137574664626SKris Kennaway 				SSL_renegotiate(con);
137674664626SKris Kennaway 				cbuf_len=0;
137774664626SKris Kennaway 				}
137874664626SKris Kennaway 			else
137974664626SKris Kennaway 				{
138074664626SKris Kennaway 				cbuf_len=i;
138174664626SKris Kennaway 				cbuf_off=0;
138274664626SKris Kennaway #ifdef CHARSET_EBCDIC
138374664626SKris Kennaway 				ebcdic2ascii(cbuf, cbuf, i);
138474664626SKris Kennaway #endif
138574664626SKris Kennaway 				}
138674664626SKris Kennaway 
138774664626SKris Kennaway 			write_ssl=1;
138874664626SKris Kennaway 			read_tty=0;
138974664626SKris Kennaway 			}
139074664626SKris Kennaway 		}
139174664626SKris Kennaway shut:
139274664626SKris Kennaway 	SSL_shutdown(con);
139374664626SKris Kennaway 	SHUTDOWN(SSL_get_fd(con));
139474664626SKris Kennaway 	ret=0;
139574664626SKris Kennaway end:
1396f579bf8eSKris Kennaway 	if(prexit) print_stuff(bio_c_out,con,1);
139774664626SKris Kennaway 	if (con != NULL) SSL_free(con);
139874664626SKris Kennaway 	if (con2 != NULL) SSL_free(con2);
139974664626SKris Kennaway 	if (ctx != NULL) SSL_CTX_free(ctx);
14003b4e3dcbSSimon L. B. Nielsen 	if (cert)
14013b4e3dcbSSimon L. B. Nielsen 		X509_free(cert);
14023b4e3dcbSSimon L. B. Nielsen 	if (key)
14033b4e3dcbSSimon L. B. Nielsen 		EVP_PKEY_free(key);
14043b4e3dcbSSimon L. B. Nielsen 	if (pass)
14053b4e3dcbSSimon L. B. Nielsen 		OPENSSL_free(pass);
14065c87c606SMark Murray 	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
14075c87c606SMark Murray 	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
14085c87c606SMark Murray 	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
140974664626SKris Kennaway 	if (bio_c_out != NULL)
141074664626SKris Kennaway 		{
141174664626SKris Kennaway 		BIO_free(bio_c_out);
141274664626SKris Kennaway 		bio_c_out=NULL;
141374664626SKris Kennaway 		}
14145c87c606SMark Murray 	apps_shutdown();
14155c87c606SMark Murray 	OPENSSL_EXIT(ret);
141674664626SKris Kennaway 	}
141774664626SKris Kennaway 
141874664626SKris Kennaway 
141974664626SKris Kennaway static void print_stuff(BIO *bio, SSL *s, int full)
142074664626SKris Kennaway 	{
142174664626SKris Kennaway 	X509 *peer=NULL;
142274664626SKris Kennaway 	char *p;
14233b4e3dcbSSimon L. B. Nielsen 	static const char *space="                ";
142474664626SKris Kennaway 	char buf[BUFSIZ];
142574664626SKris Kennaway 	STACK_OF(X509) *sk;
142674664626SKris Kennaway 	STACK_OF(X509_NAME) *sk2;
142774664626SKris Kennaway 	SSL_CIPHER *c;
142874664626SKris Kennaway 	X509_NAME *xn;
142974664626SKris Kennaway 	int j,i;
14303b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
14313b4e3dcbSSimon L. B. Nielsen 	const COMP_METHOD *comp, *expansion;
14323b4e3dcbSSimon L. B. Nielsen #endif
143374664626SKris Kennaway 
143474664626SKris Kennaway 	if (full)
143574664626SKris Kennaway 		{
143674664626SKris Kennaway 		int got_a_chain = 0;
143774664626SKris Kennaway 
143874664626SKris Kennaway 		sk=SSL_get_peer_cert_chain(s);
143974664626SKris Kennaway 		if (sk != NULL)
144074664626SKris Kennaway 			{
144174664626SKris Kennaway 			got_a_chain = 1; /* we don't have it for SSL2 (yet) */
144274664626SKris Kennaway 
144374664626SKris Kennaway 			BIO_printf(bio,"---\nCertificate chain\n");
144474664626SKris Kennaway 			for (i=0; i<sk_X509_num(sk); i++)
144574664626SKris Kennaway 				{
144674664626SKris Kennaway 				X509_NAME_oneline(X509_get_subject_name(
14475c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
144874664626SKris Kennaway 				BIO_printf(bio,"%2d s:%s\n",i,buf);
144974664626SKris Kennaway 				X509_NAME_oneline(X509_get_issuer_name(
14505c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
145174664626SKris Kennaway 				BIO_printf(bio,"   i:%s\n",buf);
145274664626SKris Kennaway 				if (c_showcerts)
145374664626SKris Kennaway 					PEM_write_bio_X509(bio,sk_X509_value(sk,i));
145474664626SKris Kennaway 				}
145574664626SKris Kennaway 			}
145674664626SKris Kennaway 
145774664626SKris Kennaway 		BIO_printf(bio,"---\n");
145874664626SKris Kennaway 		peer=SSL_get_peer_certificate(s);
145974664626SKris Kennaway 		if (peer != NULL)
146074664626SKris Kennaway 			{
146174664626SKris Kennaway 			BIO_printf(bio,"Server certificate\n");
146274664626SKris Kennaway 			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
146374664626SKris Kennaway 				PEM_write_bio_X509(bio,peer);
146474664626SKris Kennaway 			X509_NAME_oneline(X509_get_subject_name(peer),
14655c87c606SMark Murray 				buf,sizeof buf);
146674664626SKris Kennaway 			BIO_printf(bio,"subject=%s\n",buf);
146774664626SKris Kennaway 			X509_NAME_oneline(X509_get_issuer_name(peer),
14685c87c606SMark Murray 				buf,sizeof buf);
146974664626SKris Kennaway 			BIO_printf(bio,"issuer=%s\n",buf);
147074664626SKris Kennaway 			}
147174664626SKris Kennaway 		else
147274664626SKris Kennaway 			BIO_printf(bio,"no peer certificate available\n");
147374664626SKris Kennaway 
147474664626SKris Kennaway 		sk2=SSL_get_client_CA_list(s);
147574664626SKris Kennaway 		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
147674664626SKris Kennaway 			{
147774664626SKris Kennaway 			BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
147874664626SKris Kennaway 			for (i=0; i<sk_X509_NAME_num(sk2); i++)
147974664626SKris Kennaway 				{
148074664626SKris Kennaway 				xn=sk_X509_NAME_value(sk2,i);
148174664626SKris Kennaway 				X509_NAME_oneline(xn,buf,sizeof(buf));
148274664626SKris Kennaway 				BIO_write(bio,buf,strlen(buf));
148374664626SKris Kennaway 				BIO_write(bio,"\n",1);
148474664626SKris Kennaway 				}
148574664626SKris Kennaway 			}
148674664626SKris Kennaway 		else
148774664626SKris Kennaway 			{
148874664626SKris Kennaway 			BIO_printf(bio,"---\nNo client certificate CA names sent\n");
148974664626SKris Kennaway 			}
14905c87c606SMark Murray 		p=SSL_get_shared_ciphers(s,buf,sizeof buf);
149174664626SKris Kennaway 		if (p != NULL)
149274664626SKris Kennaway 			{
149374664626SKris Kennaway 			/* This works only for SSL 2.  In later protocol
149474664626SKris Kennaway 			 * versions, the client does not know what other
149574664626SKris Kennaway 			 * ciphers (in addition to the one to be used
149674664626SKris Kennaway 			 * in the current connection) the server supports. */
149774664626SKris Kennaway 
149874664626SKris Kennaway 			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
149974664626SKris Kennaway 			j=i=0;
150074664626SKris Kennaway 			while (*p)
150174664626SKris Kennaway 				{
150274664626SKris Kennaway 				if (*p == ':')
150374664626SKris Kennaway 					{
150474664626SKris Kennaway 					BIO_write(bio,space,15-j%25);
150574664626SKris Kennaway 					i++;
150674664626SKris Kennaway 					j=0;
150774664626SKris Kennaway 					BIO_write(bio,((i%3)?" ":"\n"),1);
150874664626SKris Kennaway 					}
150974664626SKris Kennaway 				else
151074664626SKris Kennaway 					{
151174664626SKris Kennaway 					BIO_write(bio,p,1);
151274664626SKris Kennaway 					j++;
151374664626SKris Kennaway 					}
151474664626SKris Kennaway 				p++;
151574664626SKris Kennaway 				}
151674664626SKris Kennaway 			BIO_write(bio,"\n",1);
151774664626SKris Kennaway 			}
151874664626SKris Kennaway 
151974664626SKris Kennaway 		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
152074664626SKris Kennaway 			BIO_number_read(SSL_get_rbio(s)),
152174664626SKris Kennaway 			BIO_number_written(SSL_get_wbio(s)));
152274664626SKris Kennaway 		}
152374664626SKris Kennaway 	BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
152474664626SKris Kennaway 	c=SSL_get_current_cipher(s);
152574664626SKris Kennaway 	BIO_printf(bio,"%s, Cipher is %s\n",
152674664626SKris Kennaway 		SSL_CIPHER_get_version(c),
152774664626SKris Kennaway 		SSL_CIPHER_get_name(c));
152874664626SKris Kennaway 	if (peer != NULL) {
152974664626SKris Kennaway 		EVP_PKEY *pktmp;
153074664626SKris Kennaway 		pktmp = X509_get_pubkey(peer);
153174664626SKris Kennaway 		BIO_printf(bio,"Server public key is %d bit\n",
153274664626SKris Kennaway 							 EVP_PKEY_bits(pktmp));
153374664626SKris Kennaway 		EVP_PKEY_free(pktmp);
153474664626SKris Kennaway 	}
15356a599222SSimon L. B. Nielsen 	BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
15366a599222SSimon L. B. Nielsen 			SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
15373b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
15383b4e3dcbSSimon L. B. Nielsen 	comp=SSL_get_current_compression(s);
15393b4e3dcbSSimon L. B. Nielsen 	expansion=SSL_get_current_expansion(s);
15403b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio,"Compression: %s\n",
15413b4e3dcbSSimon L. B. Nielsen 		comp ? SSL_COMP_get_name(comp) : "NONE");
15423b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio,"Expansion: %s\n",
15433b4e3dcbSSimon L. B. Nielsen 		expansion ? SSL_COMP_get_name(expansion) : "NONE");
15443b4e3dcbSSimon L. B. Nielsen #endif
154574664626SKris Kennaway 	SSL_SESSION_print(bio,SSL_get_session(s));
154674664626SKris Kennaway 	BIO_printf(bio,"---\n");
154774664626SKris Kennaway 	if (peer != NULL)
154874664626SKris Kennaway 		X509_free(peer);
1549a21b1b38SKris Kennaway 	/* flush, or debugging output gets mixed with http response */
1550db522d3aSSimon L. B. Nielsen 	(void)BIO_flush(bio);
155174664626SKris Kennaway 	}
155274664626SKris Kennaway 
1553db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1554db522d3aSSimon L. B. Nielsen 
1555db522d3aSSimon L. B. Nielsen static int ocsp_resp_cb(SSL *s, void *arg)
1556db522d3aSSimon L. B. Nielsen 	{
1557db522d3aSSimon L. B. Nielsen 	const unsigned char *p;
1558db522d3aSSimon L. B. Nielsen 	int len;
1559db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE *rsp;
1560db522d3aSSimon L. B. Nielsen 	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
1561db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "OCSP response: ");
1562db522d3aSSimon L. B. Nielsen 	if (!p)
1563db522d3aSSimon L. B. Nielsen 		{
1564db522d3aSSimon L. B. Nielsen 		BIO_puts(arg, "no response sent\n");
1565db522d3aSSimon L. B. Nielsen 		return 1;
1566db522d3aSSimon L. B. Nielsen 		}
1567db522d3aSSimon L. B. Nielsen 	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
1568db522d3aSSimon L. B. Nielsen 	if (!rsp)
1569db522d3aSSimon L. B. Nielsen 		{
1570db522d3aSSimon L. B. Nielsen 		BIO_puts(arg, "response parse error\n");
1571db522d3aSSimon L. B. Nielsen 		BIO_dump_indent(arg, (char *)p, len, 4);
1572db522d3aSSimon L. B. Nielsen 		return 0;
1573db522d3aSSimon L. B. Nielsen 		}
1574db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "\n======================================\n");
1575db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE_print(arg, rsp, 0);
1576db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "======================================\n");
1577db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE_free(rsp);
1578db522d3aSSimon L. B. Nielsen 	return 1;
1579db522d3aSSimon L. B. Nielsen 	}
1580db522d3aSSimon L. B. Nielsen #endif  /* ndef OPENSSL_NO_TLSEXT */
1581