xref: /freebsd/crypto/openssl/apps/s_client.c (revision db522d3ae42d8f706499b4b4bc97836292ab180b)
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");
2293b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio_err," -mtu          - set the 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
25274664626SKris Kennaway 	}
25374664626SKris Kennaway 
254db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
255db522d3aSSimon L. B. Nielsen 
256db522d3aSSimon L. B. Nielsen /* This is a context that we pass to callbacks */
257db522d3aSSimon L. B. Nielsen typedef struct tlsextctx_st {
258db522d3aSSimon L. B. Nielsen    BIO * biodebug;
259db522d3aSSimon L. B. Nielsen    int ack;
260db522d3aSSimon L. B. Nielsen } tlsextctx;
261db522d3aSSimon L. B. Nielsen 
262db522d3aSSimon L. B. Nielsen 
263db522d3aSSimon L. B. Nielsen static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
264db522d3aSSimon L. B. Nielsen 	{
265db522d3aSSimon L. B. Nielsen 	tlsextctx * p = (tlsextctx *) arg;
266db522d3aSSimon L. B. Nielsen 	const char * hn= SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
267db522d3aSSimon L. B. Nielsen 	if (SSL_get_servername_type(s) != -1)
268db522d3aSSimon L. B. Nielsen  	        p->ack = !SSL_session_reused(s) && hn != NULL;
269db522d3aSSimon L. B. Nielsen 	else
270db522d3aSSimon L. B. Nielsen 		BIO_printf(bio_err,"Can't use SSL_get_servername\n");
271db522d3aSSimon L. B. Nielsen 
272db522d3aSSimon L. B. Nielsen 	return SSL_TLSEXT_ERR_OK;
273db522d3aSSimon L. B. Nielsen 	}
274db522d3aSSimon L. B. Nielsen #endif
2755471f83eSSimon L. B. Nielsen enum
2765471f83eSSimon L. B. Nielsen {
2775471f83eSSimon L. B. Nielsen 	PROTO_OFF	= 0,
2785471f83eSSimon L. B. Nielsen 	PROTO_SMTP,
2795471f83eSSimon L. B. Nielsen 	PROTO_POP3,
2805471f83eSSimon L. B. Nielsen 	PROTO_IMAP,
281db522d3aSSimon L. B. Nielsen 	PROTO_FTP,
282db522d3aSSimon L. B. Nielsen 	PROTO_XMPP
2835471f83eSSimon L. B. Nielsen };
2845471f83eSSimon L. B. Nielsen 
285f579bf8eSKris Kennaway int MAIN(int, char **);
286f579bf8eSKris Kennaway 
28774664626SKris Kennaway int MAIN(int argc, char **argv)
28874664626SKris Kennaway 	{
28974664626SKris Kennaway 	int off=0;
29074664626SKris Kennaway 	SSL *con=NULL,*con2=NULL;
2915c87c606SMark Murray 	X509_STORE *store = NULL;
29274664626SKris Kennaway 	int s,k,width,state=0;
2935c87c606SMark Murray 	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
29474664626SKris Kennaway 	int cbuf_len,cbuf_off;
29574664626SKris Kennaway 	int sbuf_len,sbuf_off;
29674664626SKris Kennaway 	fd_set readfds,writefds;
29774664626SKris Kennaway 	short port=PORT;
29874664626SKris Kennaway 	int full_log=1;
29974664626SKris Kennaway 	char *host=SSL_HOST_NAME;
30074664626SKris Kennaway 	char *cert_file=NULL,*key_file=NULL;
3013b4e3dcbSSimon L. B. Nielsen 	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
3023b4e3dcbSSimon L. B. Nielsen 	char *passarg = NULL, *pass = NULL;
3033b4e3dcbSSimon L. B. Nielsen 	X509 *cert = NULL;
3043b4e3dcbSSimon L. B. Nielsen 	EVP_PKEY *key = NULL;
30574664626SKris Kennaway 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
30674664626SKris Kennaway 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
30774664626SKris Kennaway 	int crlf=0;
30874664626SKris Kennaway 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
30974664626SKris Kennaway 	SSL_CTX *ctx=NULL;
31074664626SKris Kennaway 	int ret=1,in_init=1,i,nbio_test=0;
3115471f83eSSimon L. B. Nielsen 	int starttls_proto = PROTO_OFF;
3125c87c606SMark Murray 	int prexit = 0, vflags = 0;
31374664626SKris Kennaway 	SSL_METHOD *meth=NULL;
3143b4e3dcbSSimon L. B. Nielsen #ifdef sock_type
3153b4e3dcbSSimon L. B. Nielsen #undef sock_type
3163b4e3dcbSSimon L. B. Nielsen #endif
3173b4e3dcbSSimon L. B. Nielsen 	int sock_type=SOCK_STREAM;
31874664626SKris Kennaway 	BIO *sbio;
3195740a5e3SKris Kennaway 	char *inrand=NULL;
3205471f83eSSimon L. B. Nielsen 	int mbuf_len=0;
321fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
3225c87c606SMark Murray 	char *engine_id=NULL;
323db522d3aSSimon L. B. Nielsen 	char *ssl_client_engine_id=NULL;
324db522d3aSSimon L. B. Nielsen 	ENGINE *ssl_client_engine=NULL;
325fceca8a3SJacques Vidrine #endif
326db522d3aSSimon L. B. Nielsen 	ENGINE *e=NULL;
3273b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
328f579bf8eSKris Kennaway 	struct timeval tv;
329f579bf8eSKris Kennaway #endif
33074664626SKris Kennaway 
331db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
332db522d3aSSimon L. B. Nielsen 	char *servername = NULL;
333db522d3aSSimon L. B. Nielsen         tlsextctx tlsextcbp =
334db522d3aSSimon L. B. Nielsen         {NULL,0};
335db522d3aSSimon L. B. Nielsen #endif
336db522d3aSSimon L. B. Nielsen 	char *sess_in = NULL;
337db522d3aSSimon L. B. Nielsen 	char *sess_out = NULL;
3383b4e3dcbSSimon L. B. Nielsen 	struct sockaddr peer;
3393b4e3dcbSSimon L. B. Nielsen 	int peerlen = sizeof(peer);
3403b4e3dcbSSimon L. B. Nielsen 	int enable_timeouts = 0 ;
3413b4e3dcbSSimon L. B. Nielsen 	long mtu = 0;
342db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
343db522d3aSSimon L. B. Nielsen 	char *jpake_secret = NULL;
344db522d3aSSimon L. B. Nielsen #endif
3453b4e3dcbSSimon L. B. Nielsen 
3465c87c606SMark Murray #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
34774664626SKris Kennaway 	meth=SSLv23_client_method();
3485c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL3)
34974664626SKris Kennaway 	meth=SSLv3_client_method();
3505c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL2)
35174664626SKris Kennaway 	meth=SSLv2_client_method();
35274664626SKris Kennaway #endif
35374664626SKris Kennaway 
35474664626SKris Kennaway 	apps_startup();
35574664626SKris Kennaway 	c_Pause=0;
35674664626SKris Kennaway 	c_quiet=0;
357f579bf8eSKris Kennaway 	c_ign_eof=0;
35874664626SKris Kennaway 	c_debug=0;
3595c87c606SMark Murray 	c_msg=0;
36074664626SKris Kennaway 	c_showcerts=0;
36174664626SKris Kennaway 
36274664626SKris Kennaway 	if (bio_err == NULL)
36374664626SKris Kennaway 		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
36474664626SKris Kennaway 
3655c87c606SMark Murray 	if (!load_config(bio_err, NULL))
3665c87c606SMark Murray 		goto end;
3675c87c606SMark Murray 
368ddd58736SKris Kennaway 	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3695c87c606SMark Murray 		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
3705c87c606SMark Murray 		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
37174664626SKris Kennaway 		{
37274664626SKris Kennaway 		BIO_printf(bio_err,"out of memory\n");
37374664626SKris Kennaway 		goto end;
37474664626SKris Kennaway 		}
37574664626SKris Kennaway 
37674664626SKris Kennaway 	verify_depth=0;
37774664626SKris Kennaway 	verify_error=X509_V_OK;
37874664626SKris Kennaway #ifdef FIONBIO
37974664626SKris Kennaway 	c_nbio=0;
38074664626SKris Kennaway #endif
38174664626SKris Kennaway 
38274664626SKris Kennaway 	argc--;
38374664626SKris Kennaway 	argv++;
38474664626SKris Kennaway 	while (argc >= 1)
38574664626SKris Kennaway 		{
38674664626SKris Kennaway 		if	(strcmp(*argv,"-host") == 0)
38774664626SKris Kennaway 			{
38874664626SKris Kennaway 			if (--argc < 1) goto bad;
38974664626SKris Kennaway 			host= *(++argv);
39074664626SKris Kennaway 			}
39174664626SKris Kennaway 		else if	(strcmp(*argv,"-port") == 0)
39274664626SKris Kennaway 			{
39374664626SKris Kennaway 			if (--argc < 1) goto bad;
39474664626SKris Kennaway 			port=atoi(*(++argv));
39574664626SKris Kennaway 			if (port == 0) goto bad;
39674664626SKris Kennaway 			}
39774664626SKris Kennaway 		else if (strcmp(*argv,"-connect") == 0)
39874664626SKris Kennaway 			{
39974664626SKris Kennaway 			if (--argc < 1) goto bad;
40074664626SKris Kennaway 			if (!extract_host_port(*(++argv),&host,NULL,&port))
40174664626SKris Kennaway 				goto bad;
40274664626SKris Kennaway 			}
40374664626SKris Kennaway 		else if	(strcmp(*argv,"-verify") == 0)
40474664626SKris Kennaway 			{
40574664626SKris Kennaway 			verify=SSL_VERIFY_PEER;
40674664626SKris Kennaway 			if (--argc < 1) goto bad;
40774664626SKris Kennaway 			verify_depth=atoi(*(++argv));
40874664626SKris Kennaway 			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
40974664626SKris Kennaway 			}
41074664626SKris Kennaway 		else if	(strcmp(*argv,"-cert") == 0)
41174664626SKris Kennaway 			{
41274664626SKris Kennaway 			if (--argc < 1) goto bad;
41374664626SKris Kennaway 			cert_file= *(++argv);
41474664626SKris Kennaway 			}
415db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-sess_out") == 0)
416db522d3aSSimon L. B. Nielsen 			{
417db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
418db522d3aSSimon L. B. Nielsen 			sess_out = *(++argv);
419db522d3aSSimon L. B. Nielsen 			}
420db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-sess_in") == 0)
421db522d3aSSimon L. B. Nielsen 			{
422db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
423db522d3aSSimon L. B. Nielsen 			sess_in = *(++argv);
424db522d3aSSimon L. B. Nielsen 			}
4253b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-certform") == 0)
4263b4e3dcbSSimon L. B. Nielsen 			{
4273b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
4283b4e3dcbSSimon L. B. Nielsen 			cert_format = str2fmt(*(++argv));
4293b4e3dcbSSimon L. B. Nielsen 			}
4305c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check") == 0)
4315c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK;
4325c87c606SMark Murray 		else if	(strcmp(*argv,"-crl_check_all") == 0)
4335c87c606SMark Murray 			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
434f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-prexit") == 0)
435f579bf8eSKris Kennaway 			prexit=1;
43674664626SKris Kennaway 		else if	(strcmp(*argv,"-crlf") == 0)
43774664626SKris Kennaway 			crlf=1;
43874664626SKris Kennaway 		else if	(strcmp(*argv,"-quiet") == 0)
439f579bf8eSKris Kennaway 			{
44074664626SKris Kennaway 			c_quiet=1;
441f579bf8eSKris Kennaway 			c_ign_eof=1;
442f579bf8eSKris Kennaway 			}
443f579bf8eSKris Kennaway 		else if	(strcmp(*argv,"-ign_eof") == 0)
444f579bf8eSKris Kennaway 			c_ign_eof=1;
445db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-no_ign_eof") == 0)
446db522d3aSSimon L. B. Nielsen 			c_ign_eof=0;
44774664626SKris Kennaway 		else if	(strcmp(*argv,"-pause") == 0)
44874664626SKris Kennaway 			c_Pause=1;
44974664626SKris Kennaway 		else if	(strcmp(*argv,"-debug") == 0)
45074664626SKris Kennaway 			c_debug=1;
451db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
452db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-tlsextdebug") == 0)
453db522d3aSSimon L. B. Nielsen 			c_tlsextdebug=1;
454db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-status") == 0)
455db522d3aSSimon L. B. Nielsen 			c_status_req=1;
456db522d3aSSimon L. B. Nielsen #endif
4573b4e3dcbSSimon L. B. Nielsen #ifdef WATT32
4583b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-wdebug") == 0)
4593b4e3dcbSSimon L. B. Nielsen 			dbug_init();
4603b4e3dcbSSimon L. B. Nielsen #endif
4615c87c606SMark Murray 		else if	(strcmp(*argv,"-msg") == 0)
4625c87c606SMark Murray 			c_msg=1;
46374664626SKris Kennaway 		else if	(strcmp(*argv,"-showcerts") == 0)
46474664626SKris Kennaway 			c_showcerts=1;
46574664626SKris Kennaway 		else if	(strcmp(*argv,"-nbio_test") == 0)
46674664626SKris Kennaway 			nbio_test=1;
46774664626SKris Kennaway 		else if	(strcmp(*argv,"-state") == 0)
46874664626SKris Kennaway 			state=1;
4695c87c606SMark Murray #ifndef OPENSSL_NO_SSL2
47074664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl2") == 0)
47174664626SKris Kennaway 			meth=SSLv2_client_method();
47274664626SKris Kennaway #endif
4735c87c606SMark Murray #ifndef OPENSSL_NO_SSL3
47474664626SKris Kennaway 		else if	(strcmp(*argv,"-ssl3") == 0)
47574664626SKris Kennaway 			meth=SSLv3_client_method();
47674664626SKris Kennaway #endif
4775c87c606SMark Murray #ifndef OPENSSL_NO_TLS1
47874664626SKris Kennaway 		else if	(strcmp(*argv,"-tls1") == 0)
47974664626SKris Kennaway 			meth=TLSv1_client_method();
48074664626SKris Kennaway #endif
4813b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DTLS1
4823b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-dtls1") == 0)
4833b4e3dcbSSimon L. B. Nielsen 			{
4843b4e3dcbSSimon L. B. Nielsen 			meth=DTLSv1_client_method();
4853b4e3dcbSSimon L. B. Nielsen 			sock_type=SOCK_DGRAM;
4863b4e3dcbSSimon L. B. Nielsen 			}
4873b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-timeout") == 0)
4883b4e3dcbSSimon L. B. Nielsen 			enable_timeouts=1;
4893b4e3dcbSSimon L. B. Nielsen 		else if (strcmp(*argv,"-mtu") == 0)
4903b4e3dcbSSimon L. B. Nielsen 			{
4913b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
4923b4e3dcbSSimon L. B. Nielsen 			mtu = atol(*(++argv));
4933b4e3dcbSSimon L. B. Nielsen 			}
4943b4e3dcbSSimon L. B. Nielsen #endif
49574664626SKris Kennaway 		else if (strcmp(*argv,"-bugs") == 0)
49674664626SKris Kennaway 			bugs=1;
4973b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-keyform") == 0)
4983b4e3dcbSSimon L. B. Nielsen 			{
4993b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
5003b4e3dcbSSimon L. B. Nielsen 			key_format = str2fmt(*(++argv));
5013b4e3dcbSSimon L. B. Nielsen 			}
5023b4e3dcbSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-pass") == 0)
5033b4e3dcbSSimon L. B. Nielsen 			{
5043b4e3dcbSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
5053b4e3dcbSSimon L. B. Nielsen 			passarg = *(++argv);
5063b4e3dcbSSimon L. B. Nielsen 			}
50774664626SKris Kennaway 		else if	(strcmp(*argv,"-key") == 0)
50874664626SKris Kennaway 			{
50974664626SKris Kennaway 			if (--argc < 1) goto bad;
51074664626SKris Kennaway 			key_file= *(++argv);
51174664626SKris Kennaway 			}
51274664626SKris Kennaway 		else if	(strcmp(*argv,"-reconnect") == 0)
51374664626SKris Kennaway 			{
51474664626SKris Kennaway 			reconnect=5;
51574664626SKris Kennaway 			}
51674664626SKris Kennaway 		else if	(strcmp(*argv,"-CApath") == 0)
51774664626SKris Kennaway 			{
51874664626SKris Kennaway 			if (--argc < 1) goto bad;
51974664626SKris Kennaway 			CApath= *(++argv);
52074664626SKris Kennaway 			}
52174664626SKris Kennaway 		else if	(strcmp(*argv,"-CAfile") == 0)
52274664626SKris Kennaway 			{
52374664626SKris Kennaway 			if (--argc < 1) goto bad;
52474664626SKris Kennaway 			CAfile= *(++argv);
52574664626SKris Kennaway 			}
52674664626SKris Kennaway 		else if (strcmp(*argv,"-no_tls1") == 0)
52774664626SKris Kennaway 			off|=SSL_OP_NO_TLSv1;
52874664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl3") == 0)
52974664626SKris Kennaway 			off|=SSL_OP_NO_SSLv3;
53074664626SKris Kennaway 		else if (strcmp(*argv,"-no_ssl2") == 0)
53174664626SKris Kennaway 			off|=SSL_OP_NO_SSLv2;
532db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
533db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-no_ticket") == 0)
534db522d3aSSimon L. B. Nielsen 			{ off|=SSL_OP_NO_TICKET; }
535db522d3aSSimon L. B. Nielsen #endif
5365c87c606SMark Murray 		else if (strcmp(*argv,"-serverpref") == 0)
5375c87c606SMark Murray 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
53874664626SKris Kennaway 		else if	(strcmp(*argv,"-cipher") == 0)
53974664626SKris Kennaway 			{
54074664626SKris Kennaway 			if (--argc < 1) goto bad;
54174664626SKris Kennaway 			cipher= *(++argv);
54274664626SKris Kennaway 			}
54374664626SKris Kennaway #ifdef FIONBIO
54474664626SKris Kennaway 		else if (strcmp(*argv,"-nbio") == 0)
54574664626SKris Kennaway 			{ c_nbio=1; }
54674664626SKris Kennaway #endif
5475c87c606SMark Murray 		else if	(strcmp(*argv,"-starttls") == 0)
5485c87c606SMark Murray 			{
5495c87c606SMark Murray 			if (--argc < 1) goto bad;
5505c87c606SMark Murray 			++argv;
5515c87c606SMark Murray 			if (strcmp(*argv,"smtp") == 0)
5525471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_SMTP;
55350ef0093SJacques Vidrine 			else if (strcmp(*argv,"pop3") == 0)
5545471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_POP3;
5555471f83eSSimon L. B. Nielsen 			else if (strcmp(*argv,"imap") == 0)
5565471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_IMAP;
5575471f83eSSimon L. B. Nielsen 			else if (strcmp(*argv,"ftp") == 0)
5585471f83eSSimon L. B. Nielsen 				starttls_proto = PROTO_FTP;
559db522d3aSSimon L. B. Nielsen 			else if (strcmp(*argv, "xmpp") == 0)
560db522d3aSSimon L. B. Nielsen 				starttls_proto = PROTO_XMPP;
5615c87c606SMark Murray 			else
5625c87c606SMark Murray 				goto bad;
5635c87c606SMark Murray 			}
564fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
5655c87c606SMark Murray 		else if	(strcmp(*argv,"-engine") == 0)
5665c87c606SMark Murray 			{
5675c87c606SMark Murray 			if (--argc < 1) goto bad;
5685c87c606SMark Murray 			engine_id = *(++argv);
5695c87c606SMark Murray 			}
570db522d3aSSimon L. B. Nielsen 		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
571db522d3aSSimon L. B. Nielsen 			{
572db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
573db522d3aSSimon L. B. Nielsen 			ssl_client_engine_id = *(++argv);
574db522d3aSSimon L. B. Nielsen 			}
575fceca8a3SJacques Vidrine #endif
5765740a5e3SKris Kennaway 		else if (strcmp(*argv,"-rand") == 0)
5775740a5e3SKris Kennaway 			{
5785740a5e3SKris Kennaway 			if (--argc < 1) goto bad;
5795740a5e3SKris Kennaway 			inrand= *(++argv);
5805740a5e3SKris Kennaway 			}
581db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
582db522d3aSSimon L. B. Nielsen 		else if (strcmp(*argv,"-servername") == 0)
583db522d3aSSimon L. B. Nielsen 			{
584db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
585db522d3aSSimon L. B. Nielsen 			servername= *(++argv);
586db522d3aSSimon L. B. Nielsen 			/* meth=TLSv1_client_method(); */
587db522d3aSSimon L. B. Nielsen 			}
588db522d3aSSimon L. B. Nielsen #endif
589db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
590db522d3aSSimon L. B. Nielsen 		else if (strcmp(*argv,"-jpake") == 0)
591db522d3aSSimon L. B. Nielsen 			{
592db522d3aSSimon L. B. Nielsen 			if (--argc < 1) goto bad;
593db522d3aSSimon L. B. Nielsen 			jpake_secret = *++argv;
594db522d3aSSimon L. B. Nielsen 			}
595db522d3aSSimon L. B. Nielsen #endif
59674664626SKris Kennaway 		else
59774664626SKris Kennaway 			{
59874664626SKris Kennaway 			BIO_printf(bio_err,"unknown option %s\n",*argv);
59974664626SKris Kennaway 			badop=1;
60074664626SKris Kennaway 			break;
60174664626SKris Kennaway 			}
60274664626SKris Kennaway 		argc--;
60374664626SKris Kennaway 		argv++;
60474664626SKris Kennaway 		}
60574664626SKris Kennaway 	if (badop)
60674664626SKris Kennaway 		{
60774664626SKris Kennaway bad:
60874664626SKris Kennaway 		sc_usage();
60974664626SKris Kennaway 		goto end;
61074664626SKris Kennaway 		}
61174664626SKris Kennaway 
6125c87c606SMark Murray 	OpenSSL_add_ssl_algorithms();
6135c87c606SMark Murray 	SSL_load_error_strings();
6145c87c606SMark Murray 
615fceca8a3SJacques Vidrine #ifndef OPENSSL_NO_ENGINE
6165c87c606SMark Murray         e = setup_engine(bio_err, engine_id, 1);
617db522d3aSSimon L. B. Nielsen 	if (ssl_client_engine_id)
618db522d3aSSimon L. B. Nielsen 		{
619db522d3aSSimon L. B. Nielsen 		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
620db522d3aSSimon L. B. Nielsen 		if (!ssl_client_engine)
621db522d3aSSimon L. B. Nielsen 			{
622db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err,
623db522d3aSSimon L. B. Nielsen 					"Error getting client auth engine\n");
624db522d3aSSimon L. B. Nielsen 			goto end;
625db522d3aSSimon L. B. Nielsen 			}
626db522d3aSSimon L. B. Nielsen 		}
627fceca8a3SJacques Vidrine #endif
6283b4e3dcbSSimon L. B. Nielsen 	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
6293b4e3dcbSSimon L. B. Nielsen 		{
6303b4e3dcbSSimon L. B. Nielsen 		BIO_printf(bio_err, "Error getting password\n");
6313b4e3dcbSSimon L. B. Nielsen 		goto end;
6323b4e3dcbSSimon L. B. Nielsen 		}
6333b4e3dcbSSimon L. B. Nielsen 
6343b4e3dcbSSimon L. B. Nielsen 	if (key_file == NULL)
6353b4e3dcbSSimon L. B. Nielsen 		key_file = cert_file;
6363b4e3dcbSSimon L. B. Nielsen 
6373b4e3dcbSSimon L. B. Nielsen 
6383b4e3dcbSSimon L. B. Nielsen 	if (key_file)
6393b4e3dcbSSimon L. B. Nielsen 
6403b4e3dcbSSimon L. B. Nielsen 		{
6413b4e3dcbSSimon L. B. Nielsen 
6423b4e3dcbSSimon L. B. Nielsen 		key = load_key(bio_err, key_file, key_format, 0, pass, e,
6433b4e3dcbSSimon L. B. Nielsen 			       "client certificate private key file");
6443b4e3dcbSSimon L. B. Nielsen 		if (!key)
6453b4e3dcbSSimon L. B. Nielsen 			{
6463b4e3dcbSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
6473b4e3dcbSSimon L. B. Nielsen 			goto end;
6483b4e3dcbSSimon L. B. Nielsen 			}
6493b4e3dcbSSimon L. B. Nielsen 
6503b4e3dcbSSimon L. B. Nielsen 		}
6513b4e3dcbSSimon L. B. Nielsen 
6523b4e3dcbSSimon L. B. Nielsen 	if (cert_file)
6533b4e3dcbSSimon L. B. Nielsen 
6543b4e3dcbSSimon L. B. Nielsen 		{
6553b4e3dcbSSimon L. B. Nielsen 		cert = load_cert(bio_err,cert_file,cert_format,
6563b4e3dcbSSimon L. B. Nielsen 				NULL, e, "client certificate file");
6573b4e3dcbSSimon L. B. Nielsen 
6583b4e3dcbSSimon L. B. Nielsen 		if (!cert)
6593b4e3dcbSSimon L. B. Nielsen 			{
6603b4e3dcbSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
6613b4e3dcbSSimon L. B. Nielsen 			goto end;
6623b4e3dcbSSimon L. B. Nielsen 			}
6633b4e3dcbSSimon L. B. Nielsen 		}
6645c87c606SMark Murray 
6655740a5e3SKris Kennaway 	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
6665740a5e3SKris Kennaway 		&& !RAND_status())
6675740a5e3SKris Kennaway 		{
6685740a5e3SKris Kennaway 		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
6695740a5e3SKris Kennaway 		}
6705740a5e3SKris Kennaway 	if (inrand != NULL)
6715740a5e3SKris Kennaway 		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
6725740a5e3SKris Kennaway 			app_RAND_load_files(inrand));
673f579bf8eSKris Kennaway 
67474664626SKris Kennaway 	if (bio_c_out == NULL)
67574664626SKris Kennaway 		{
6765c87c606SMark Murray 		if (c_quiet && !c_debug && !c_msg)
67774664626SKris Kennaway 			{
67874664626SKris Kennaway 			bio_c_out=BIO_new(BIO_s_null());
67974664626SKris Kennaway 			}
68074664626SKris Kennaway 		else
68174664626SKris Kennaway 			{
68274664626SKris Kennaway 			if (bio_c_out == NULL)
68374664626SKris Kennaway 				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
68474664626SKris Kennaway 			}
68574664626SKris Kennaway 		}
68674664626SKris Kennaway 
68774664626SKris Kennaway 	ctx=SSL_CTX_new(meth);
68874664626SKris Kennaway 	if (ctx == NULL)
68974664626SKris Kennaway 		{
69074664626SKris Kennaway 		ERR_print_errors(bio_err);
69174664626SKris Kennaway 		goto end;
69274664626SKris Kennaway 		}
69374664626SKris Kennaway 
694db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_ENGINE
695db522d3aSSimon L. B. Nielsen 	if (ssl_client_engine)
696db522d3aSSimon L. B. Nielsen 		{
697db522d3aSSimon L. B. Nielsen 		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
698db522d3aSSimon L. B. Nielsen 			{
699db522d3aSSimon L. B. Nielsen 			BIO_puts(bio_err, "Error setting client auth engine\n");
700db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
701db522d3aSSimon L. B. Nielsen 			ENGINE_free(ssl_client_engine);
702db522d3aSSimon L. B. Nielsen 			goto end;
703db522d3aSSimon L. B. Nielsen 			}
704db522d3aSSimon L. B. Nielsen 		ENGINE_free(ssl_client_engine);
705db522d3aSSimon L. B. Nielsen 		}
706db522d3aSSimon L. B. Nielsen #endif
707db522d3aSSimon L. B. Nielsen 
70874664626SKris Kennaway 	if (bugs)
70974664626SKris Kennaway 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
71074664626SKris Kennaway 	else
71174664626SKris Kennaway 		SSL_CTX_set_options(ctx,off);
7123b4e3dcbSSimon L. B. Nielsen 	/* DTLS: partial reads end up discarding unread UDP bytes :-(
7133b4e3dcbSSimon L. B. Nielsen 	 * Setting read ahead solves this problem.
7143b4e3dcbSSimon L. B. Nielsen 	 */
7153b4e3dcbSSimon L. B. Nielsen 	if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
71674664626SKris Kennaway 
71774664626SKris Kennaway 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
71874664626SKris Kennaway 	if (cipher != NULL)
719f579bf8eSKris Kennaway 		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
720f579bf8eSKris Kennaway 		BIO_printf(bio_err,"error setting cipher list\n");
721f579bf8eSKris Kennaway 		ERR_print_errors(bio_err);
722f579bf8eSKris Kennaway 		goto end;
723f579bf8eSKris Kennaway 	}
72474664626SKris Kennaway #if 0
72574664626SKris Kennaway 	else
72674664626SKris Kennaway 		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
72774664626SKris Kennaway #endif
72874664626SKris Kennaway 
72974664626SKris Kennaway 	SSL_CTX_set_verify(ctx,verify,verify_callback);
7303b4e3dcbSSimon L. B. Nielsen 	if (!set_cert_key_stuff(ctx,cert,key))
73174664626SKris Kennaway 		goto end;
73274664626SKris Kennaway 
73374664626SKris Kennaway 	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
73474664626SKris Kennaway 		(!SSL_CTX_set_default_verify_paths(ctx)))
73574664626SKris Kennaway 		{
736f579bf8eSKris Kennaway 		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
73774664626SKris Kennaway 		ERR_print_errors(bio_err);
73874664626SKris Kennaway 		/* goto end; */
73974664626SKris Kennaway 		}
74074664626SKris Kennaway 
7415c87c606SMark Murray 	store = SSL_CTX_get_cert_store(ctx);
7425c87c606SMark Murray 	X509_STORE_set_flags(store, vflags);
743db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
744db522d3aSSimon L. B. Nielsen 	if (servername != NULL)
745db522d3aSSimon L. B. Nielsen 		{
746db522d3aSSimon L. B. Nielsen 		tlsextcbp.biodebug = bio_err;
747db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
748db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
749db522d3aSSimon L. B. Nielsen 		}
750db522d3aSSimon L. B. Nielsen #endif
75174664626SKris Kennaway 
752f579bf8eSKris Kennaway 	con=SSL_new(ctx);
753db522d3aSSimon L. B. Nielsen 	if (sess_in)
754db522d3aSSimon L. B. Nielsen 		{
755db522d3aSSimon L. B. Nielsen 		SSL_SESSION *sess;
756db522d3aSSimon L. B. Nielsen 		BIO *stmp = BIO_new_file(sess_in, "r");
757db522d3aSSimon L. B. Nielsen 		if (!stmp)
758db522d3aSSimon L. B. Nielsen 			{
759db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err, "Can't open session file %s\n",
760db522d3aSSimon L. B. Nielsen 						sess_in);
761db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
762db522d3aSSimon L. B. Nielsen 			goto end;
763db522d3aSSimon L. B. Nielsen 			}
764db522d3aSSimon L. B. Nielsen 		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
765db522d3aSSimon L. B. Nielsen 		BIO_free(stmp);
766db522d3aSSimon L. B. Nielsen 		if (!sess)
767db522d3aSSimon L. B. Nielsen 			{
768db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err, "Can't open session file %s\n",
769db522d3aSSimon L. B. Nielsen 						sess_in);
770db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
771db522d3aSSimon L. B. Nielsen 			goto end;
772db522d3aSSimon L. B. Nielsen 			}
773db522d3aSSimon L. B. Nielsen 		SSL_set_session(con, sess);
774db522d3aSSimon L. B. Nielsen 		SSL_SESSION_free(sess);
775db522d3aSSimon L. B. Nielsen 		}
776db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
777db522d3aSSimon L. B. Nielsen 	if (servername != NULL)
778db522d3aSSimon L. B. Nielsen 		{
779db522d3aSSimon L. B. Nielsen 		if (!SSL_set_tlsext_host_name(con,servername))
780db522d3aSSimon L. B. Nielsen 			{
781db522d3aSSimon L. B. Nielsen 			BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
782db522d3aSSimon L. B. Nielsen 			ERR_print_errors(bio_err);
783db522d3aSSimon L. B. Nielsen 			goto end;
784db522d3aSSimon L. B. Nielsen 			}
785db522d3aSSimon L. B. Nielsen 		}
786db522d3aSSimon L. B. Nielsen #endif
787db522d3aSSimon L. B. Nielsen 
7885c87c606SMark Murray #ifndef OPENSSL_NO_KRB5
7895c87c606SMark Murray 	if (con  &&  (con->kssl_ctx = kssl_ctx_new()) != NULL)
7905c87c606SMark Murray                 {
7915c87c606SMark Murray                 kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVER, host);
7925c87c606SMark Murray 		}
7935c87c606SMark Murray #endif	/* OPENSSL_NO_KRB5  */
79474664626SKris Kennaway /*	SSL_set_cipher_list(con,"RC4-MD5"); */
79574664626SKris Kennaway 
79674664626SKris Kennaway re_start:
79774664626SKris Kennaway 
7983b4e3dcbSSimon L. B. Nielsen 	if (init_client(&s,host,port,sock_type) == 0)
79974664626SKris Kennaway 		{
80074664626SKris Kennaway 		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
80174664626SKris Kennaway 		SHUTDOWN(s);
80274664626SKris Kennaway 		goto end;
80374664626SKris Kennaway 		}
80474664626SKris Kennaway 	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
80574664626SKris Kennaway 
80674664626SKris Kennaway #ifdef FIONBIO
80774664626SKris Kennaway 	if (c_nbio)
80874664626SKris Kennaway 		{
80974664626SKris Kennaway 		unsigned long l=1;
81074664626SKris Kennaway 		BIO_printf(bio_c_out,"turning on non blocking io\n");
81174664626SKris Kennaway 		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
81274664626SKris Kennaway 			{
81374664626SKris Kennaway 			ERR_print_errors(bio_err);
81474664626SKris Kennaway 			goto end;
81574664626SKris Kennaway 			}
81674664626SKris Kennaway 		}
81774664626SKris Kennaway #endif
81874664626SKris Kennaway 	if (c_Pause & 0x01) con->debug=1;
8193b4e3dcbSSimon L. B. Nielsen 
8203b4e3dcbSSimon L. B. Nielsen 	if ( SSL_version(con) == DTLS1_VERSION)
8213b4e3dcbSSimon L. B. Nielsen 		{
8223b4e3dcbSSimon L. B. Nielsen 		struct timeval timeout;
8233b4e3dcbSSimon L. B. Nielsen 
8243b4e3dcbSSimon L. B. Nielsen 		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
8253b4e3dcbSSimon L. B. Nielsen 		if (getsockname(s, &peer, (void *)&peerlen) < 0)
8263b4e3dcbSSimon L. B. Nielsen 			{
8273b4e3dcbSSimon L. B. Nielsen 			BIO_printf(bio_err, "getsockname:errno=%d\n",
8283b4e3dcbSSimon L. B. Nielsen 				get_last_socket_error());
8293b4e3dcbSSimon L. B. Nielsen 			SHUTDOWN(s);
8303b4e3dcbSSimon L. B. Nielsen 			goto end;
8313b4e3dcbSSimon L. B. Nielsen 			}
8323b4e3dcbSSimon L. B. Nielsen 
833db522d3aSSimon L. B. Nielsen 		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
8343b4e3dcbSSimon L. B. Nielsen 
8353b4e3dcbSSimon L. B. Nielsen 		if ( enable_timeouts)
8363b4e3dcbSSimon L. B. Nielsen 			{
8373b4e3dcbSSimon L. B. Nielsen 			timeout.tv_sec = 0;
8383b4e3dcbSSimon L. B. Nielsen 			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
8393b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
8403b4e3dcbSSimon L. B. Nielsen 
8413b4e3dcbSSimon L. B. Nielsen 			timeout.tv_sec = 0;
8423b4e3dcbSSimon L. B. Nielsen 			timeout.tv_usec = DGRAM_SND_TIMEOUT;
8433b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
8443b4e3dcbSSimon L. B. Nielsen 			}
8453b4e3dcbSSimon L. B. Nielsen 
8463b4e3dcbSSimon L. B. Nielsen 		if ( mtu > 0)
8473b4e3dcbSSimon L. B. Nielsen 			{
8483b4e3dcbSSimon L. B. Nielsen 			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
8493b4e3dcbSSimon L. B. Nielsen 			SSL_set_mtu(con, mtu);
8503b4e3dcbSSimon L. B. Nielsen 			}
8513b4e3dcbSSimon L. B. Nielsen 		else
8523b4e3dcbSSimon L. B. Nielsen 			/* want to do MTU discovery */
8533b4e3dcbSSimon L. B. Nielsen 			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
8543b4e3dcbSSimon L. B. Nielsen 		}
8553b4e3dcbSSimon L. B. Nielsen 	else
85674664626SKris Kennaway 		sbio=BIO_new_socket(s,BIO_NOCLOSE);
85774664626SKris Kennaway 
85874664626SKris Kennaway 	if (nbio_test)
85974664626SKris Kennaway 		{
86074664626SKris Kennaway 		BIO *test;
86174664626SKris Kennaway 
86274664626SKris Kennaway 		test=BIO_new(BIO_f_nbio_test());
86374664626SKris Kennaway 		sbio=BIO_push(test,sbio);
86474664626SKris Kennaway 		}
86574664626SKris Kennaway 
86674664626SKris Kennaway 	if (c_debug)
86774664626SKris Kennaway 		{
86874664626SKris Kennaway 		con->debug=1;
8693b4e3dcbSSimon L. B. Nielsen 		BIO_set_callback(sbio,bio_dump_callback);
8705471f83eSSimon L. B. Nielsen 		BIO_set_callback_arg(sbio,(char *)bio_c_out);
87174664626SKris Kennaway 		}
8725c87c606SMark Murray 	if (c_msg)
8735c87c606SMark Murray 		{
8745c87c606SMark Murray 		SSL_set_msg_callback(con, msg_cb);
8755c87c606SMark Murray 		SSL_set_msg_callback_arg(con, bio_c_out);
8765c87c606SMark Murray 		}
877db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
878db522d3aSSimon L. B. Nielsen 	if (c_tlsextdebug)
879db522d3aSSimon L. B. Nielsen 		{
880db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_debug_callback(con, tlsext_cb);
881db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_debug_arg(con, bio_c_out);
882db522d3aSSimon L. B. Nielsen 		}
883db522d3aSSimon L. B. Nielsen 	if (c_status_req)
884db522d3aSSimon L. B. Nielsen 		{
885db522d3aSSimon L. B. Nielsen 		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
886db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
887db522d3aSSimon L. B. Nielsen 		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
888db522d3aSSimon L. B. Nielsen #if 0
889db522d3aSSimon L. B. Nielsen {
890db522d3aSSimon L. B. Nielsen STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
891db522d3aSSimon L. B. Nielsen OCSP_RESPID *id = OCSP_RESPID_new();
892db522d3aSSimon L. B. Nielsen id->value.byKey = ASN1_OCTET_STRING_new();
893db522d3aSSimon L. B. Nielsen id->type = V_OCSP_RESPID_KEY;
894db522d3aSSimon L. B. Nielsen ASN1_STRING_set(id->value.byKey, "Hello World", -1);
895db522d3aSSimon L. B. Nielsen sk_OCSP_RESPID_push(ids, id);
896db522d3aSSimon L. B. Nielsen SSL_set_tlsext_status_ids(con, ids);
897db522d3aSSimon L. B. Nielsen }
898db522d3aSSimon L. B. Nielsen #endif
899db522d3aSSimon L. B. Nielsen 		}
900db522d3aSSimon L. B. Nielsen #endif
901db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_JPAKE
902db522d3aSSimon L. B. Nielsen 	if (jpake_secret)
903db522d3aSSimon L. B. Nielsen 		jpake_client_auth(bio_c_out, sbio, jpake_secret);
904db522d3aSSimon L. B. Nielsen #endif
90574664626SKris Kennaway 
90674664626SKris Kennaway 	SSL_set_bio(con,sbio,sbio);
90774664626SKris Kennaway 	SSL_set_connect_state(con);
90874664626SKris Kennaway 
90974664626SKris Kennaway 	/* ok, lets connect */
91074664626SKris Kennaway 	width=SSL_get_fd(con)+1;
91174664626SKris Kennaway 
91274664626SKris Kennaway 	read_tty=1;
91374664626SKris Kennaway 	write_tty=0;
91474664626SKris Kennaway 	tty_on=0;
91574664626SKris Kennaway 	read_ssl=1;
91674664626SKris Kennaway 	write_ssl=1;
91774664626SKris Kennaway 
91874664626SKris Kennaway 	cbuf_len=0;
91974664626SKris Kennaway 	cbuf_off=0;
92074664626SKris Kennaway 	sbuf_len=0;
92174664626SKris Kennaway 	sbuf_off=0;
92274664626SKris Kennaway 
9235c87c606SMark Murray 	/* This is an ugly hack that does a lot of assumptions */
9245471f83eSSimon L. B. Nielsen 	/* We do have to handle multi-line responses which may come
9255471f83eSSimon L. B. Nielsen  	   in a single packet or not. We therefore have to use
9265471f83eSSimon L. B. Nielsen 	   BIO_gets() which does need a buffering BIO. So during
9275471f83eSSimon L. B. Nielsen 	   the initial chitchat we do push a buffering BIO into the
9285471f83eSSimon L. B. Nielsen 	   chain that is removed again later on to not disturb the
9295471f83eSSimon L. B. Nielsen 	   rest of the s_client operation. */
9305471f83eSSimon L. B. Nielsen 	if (starttls_proto == PROTO_SMTP)
9315c87c606SMark Murray 		{
9325471f83eSSimon L. B. Nielsen 		int foundit=0;
9335471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
9345471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
9355471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end from SMTP */
9365471f83eSSimon L. B. Nielsen 		do
9375471f83eSSimon L. B. Nielsen 			{
9385471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9395471f83eSSimon L. B. Nielsen 			}
9405471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
9415471f83eSSimon L. B. Nielsen 		/* STARTTLS command requires EHLO... */
9425471f83eSSimon L. B. Nielsen 		BIO_printf(fbio,"EHLO openssl.client.net\r\n");
943db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9445471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end EHLO SMTP response */
9455471f83eSSimon L. B. Nielsen 		do
9465471f83eSSimon L. B. Nielsen 			{
9475471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9485471f83eSSimon L. B. Nielsen 			if (strstr(mbuf,"STARTTLS"))
9495471f83eSSimon L. B. Nielsen 				foundit=1;
9505471f83eSSimon L. B. Nielsen 			}
9515471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
952db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9535471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
9545471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
9555471f83eSSimon L. B. Nielsen 		if (!foundit)
9565471f83eSSimon L. B. Nielsen 			BIO_printf(bio_err,
9575471f83eSSimon L. B. Nielsen 				   "didn't found starttls in server response,"
9585471f83eSSimon L. B. Nielsen 				   " try anyway...\n");
9595c87c606SMark Murray 		BIO_printf(sbio,"STARTTLS\r\n");
9605c87c606SMark Murray 		BIO_read(sbio,sbuf,BUFSIZZ);
9615c87c606SMark Murray 		}
9625471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_POP3)
96350ef0093SJacques Vidrine 		{
96450ef0093SJacques Vidrine 		BIO_read(sbio,mbuf,BUFSIZZ);
96550ef0093SJacques Vidrine 		BIO_printf(sbio,"STLS\r\n");
96650ef0093SJacques Vidrine 		BIO_read(sbio,sbuf,BUFSIZZ);
96750ef0093SJacques Vidrine 		}
9685471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_IMAP)
9695471f83eSSimon L. B. Nielsen 		{
9705471f83eSSimon L. B. Nielsen 		int foundit=0;
9715471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
9725471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
9735471f83eSSimon L. B. Nielsen 		BIO_gets(fbio,mbuf,BUFSIZZ);
9745471f83eSSimon L. B. Nielsen 		/* STARTTLS command requires CAPABILITY... */
9755471f83eSSimon L. B. Nielsen 		BIO_printf(fbio,". CAPABILITY\r\n");
976db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9775471f83eSSimon L. B. Nielsen 		/* wait for multi-line CAPABILITY response */
9785471f83eSSimon L. B. Nielsen 		do
9795471f83eSSimon L. B. Nielsen 			{
9805471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
9815471f83eSSimon L. B. Nielsen 			if (strstr(mbuf,"STARTTLS"))
9825471f83eSSimon L. B. Nielsen 				foundit=1;
9835471f83eSSimon L. B. Nielsen 			}
9845471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[0]!='.');
985db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
9865471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
9875471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
9885471f83eSSimon L. B. Nielsen 		if (!foundit)
9895471f83eSSimon L. B. Nielsen 			BIO_printf(bio_err,
9905471f83eSSimon L. B. Nielsen 				   "didn't found STARTTLS in server response,"
9915471f83eSSimon L. B. Nielsen 				   " try anyway...\n");
9925471f83eSSimon L. B. Nielsen 		BIO_printf(sbio,". STARTTLS\r\n");
9935471f83eSSimon L. B. Nielsen 		BIO_read(sbio,sbuf,BUFSIZZ);
9945471f83eSSimon L. B. Nielsen 		}
9955471f83eSSimon L. B. Nielsen 	else if (starttls_proto == PROTO_FTP)
9965471f83eSSimon L. B. Nielsen 		{
9975471f83eSSimon L. B. Nielsen 		BIO *fbio = BIO_new(BIO_f_buffer());
9985471f83eSSimon L. B. Nielsen 		BIO_push(fbio, sbio);
9995471f83eSSimon L. B. Nielsen 		/* wait for multi-line response to end from FTP */
10005471f83eSSimon L. B. Nielsen 		do
10015471f83eSSimon L. B. Nielsen 			{
10025471f83eSSimon L. B. Nielsen 			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
10035471f83eSSimon L. B. Nielsen 			}
10045471f83eSSimon L. B. Nielsen 		while (mbuf_len>3 && mbuf[3]=='-');
1005db522d3aSSimon L. B. Nielsen 		(void)BIO_flush(fbio);
10065471f83eSSimon L. B. Nielsen 		BIO_pop(fbio);
10075471f83eSSimon L. B. Nielsen 		BIO_free(fbio);
10085471f83eSSimon L. B. Nielsen 		BIO_printf(sbio,"AUTH TLS\r\n");
10095471f83eSSimon L. B. Nielsen 		BIO_read(sbio,sbuf,BUFSIZZ);
10105471f83eSSimon L. B. Nielsen 		}
1011db522d3aSSimon L. B. Nielsen 	if (starttls_proto == PROTO_XMPP)
1012db522d3aSSimon L. B. Nielsen 		{
1013db522d3aSSimon L. B. Nielsen 		int seen = 0;
1014db522d3aSSimon L. B. Nielsen 		BIO_printf(sbio,"<stream:stream "
1015db522d3aSSimon L. B. Nielsen 		    "xmlns:stream='http://etherx.jabber.org/streams' "
1016db522d3aSSimon L. B. Nielsen 		    "xmlns='jabber:client' to='%s' version='1.0'>", host);
1017db522d3aSSimon L. B. Nielsen 		seen = BIO_read(sbio,mbuf,BUFSIZZ);
1018db522d3aSSimon L. B. Nielsen 		mbuf[seen] = 0;
1019db522d3aSSimon L. B. Nielsen 		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
1020db522d3aSSimon L. B. Nielsen 			{
1021db522d3aSSimon L. B. Nielsen 			if (strstr(mbuf, "/stream:features>"))
1022db522d3aSSimon L. B. Nielsen 				goto shut;
1023db522d3aSSimon L. B. Nielsen 			seen = BIO_read(sbio,mbuf,BUFSIZZ);
1024db522d3aSSimon L. B. Nielsen 			mbuf[seen] = 0;
1025db522d3aSSimon L. B. Nielsen 			}
1026db522d3aSSimon L. B. Nielsen 		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
1027db522d3aSSimon L. B. Nielsen 		seen = BIO_read(sbio,sbuf,BUFSIZZ);
1028db522d3aSSimon L. B. Nielsen 		sbuf[seen] = 0;
1029db522d3aSSimon L. B. Nielsen 		if (!strstr(sbuf, "<proceed"))
1030db522d3aSSimon L. B. Nielsen 			goto shut;
1031db522d3aSSimon L. B. Nielsen 		mbuf[0] = 0;
1032db522d3aSSimon L. B. Nielsen 		}
10335c87c606SMark Murray 
103474664626SKris Kennaway 	for (;;)
103574664626SKris Kennaway 		{
103674664626SKris Kennaway 		FD_ZERO(&readfds);
103774664626SKris Kennaway 		FD_ZERO(&writefds);
103874664626SKris Kennaway 
103974664626SKris Kennaway 		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
104074664626SKris Kennaway 			{
104174664626SKris Kennaway 			in_init=1;
104274664626SKris Kennaway 			tty_on=0;
104374664626SKris Kennaway 			}
104474664626SKris Kennaway 		else
104574664626SKris Kennaway 			{
104674664626SKris Kennaway 			tty_on=1;
104774664626SKris Kennaway 			if (in_init)
104874664626SKris Kennaway 				{
104974664626SKris Kennaway 				in_init=0;
1050db522d3aSSimon L. B. Nielsen 				if (sess_out)
1051db522d3aSSimon L. B. Nielsen 					{
1052db522d3aSSimon L. B. Nielsen 					BIO *stmp = BIO_new_file(sess_out, "w");
1053db522d3aSSimon L. B. Nielsen 					if (stmp)
1054db522d3aSSimon L. B. Nielsen 						{
1055db522d3aSSimon L. B. Nielsen 						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
1056db522d3aSSimon L. B. Nielsen 						BIO_free(stmp);
1057db522d3aSSimon L. B. Nielsen 						}
1058db522d3aSSimon L. B. Nielsen 					else
1059db522d3aSSimon L. B. Nielsen 						BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
1060db522d3aSSimon L. B. Nielsen 					}
106174664626SKris Kennaway 				print_stuff(bio_c_out,con,full_log);
106274664626SKris Kennaway 				if (full_log > 0) full_log--;
106374664626SKris Kennaway 
106450ef0093SJacques Vidrine 				if (starttls_proto)
10655c87c606SMark Murray 					{
10665c87c606SMark Murray 					BIO_printf(bio_err,"%s",mbuf);
10675c87c606SMark Murray 					/* We don't need to know any more */
10685471f83eSSimon L. B. Nielsen 					starttls_proto = PROTO_OFF;
10695c87c606SMark Murray 					}
10705c87c606SMark Murray 
107174664626SKris Kennaway 				if (reconnect)
107274664626SKris Kennaway 					{
107374664626SKris Kennaway 					reconnect--;
107474664626SKris Kennaway 					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
107574664626SKris Kennaway 					SSL_shutdown(con);
107674664626SKris Kennaway 					SSL_set_connect_state(con);
107774664626SKris Kennaway 					SHUTDOWN(SSL_get_fd(con));
107874664626SKris Kennaway 					goto re_start;
107974664626SKris Kennaway 					}
108074664626SKris Kennaway 				}
108174664626SKris Kennaway 			}
108274664626SKris Kennaway 
108374664626SKris Kennaway 		ssl_pending = read_ssl && SSL_pending(con);
108474664626SKris Kennaway 
108574664626SKris Kennaway 		if (!ssl_pending)
108674664626SKris Kennaway 			{
10873b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
108874664626SKris Kennaway 			if (tty_on)
108974664626SKris Kennaway 				{
109074664626SKris Kennaway 				if (read_tty)  FD_SET(fileno(stdin),&readfds);
109174664626SKris Kennaway 				if (write_tty) FD_SET(fileno(stdout),&writefds);
109274664626SKris Kennaway 				}
109374664626SKris Kennaway 			if (read_ssl)
109474664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&readfds);
109574664626SKris Kennaway 			if (write_ssl)
109674664626SKris Kennaway 				FD_SET(SSL_get_fd(con),&writefds);
1097f579bf8eSKris Kennaway #else
1098f579bf8eSKris Kennaway 			if(!tty_on || !write_tty) {
1099f579bf8eSKris Kennaway 				if (read_ssl)
1100f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&readfds);
1101f579bf8eSKris Kennaway 				if (write_ssl)
1102f579bf8eSKris Kennaway 					FD_SET(SSL_get_fd(con),&writefds);
1103f579bf8eSKris Kennaway 			}
1104f579bf8eSKris Kennaway #endif
110574664626SKris Kennaway /*			printf("mode tty(%d %d%d) ssl(%d%d)\n",
110674664626SKris Kennaway 				tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
110774664626SKris Kennaway 
110874664626SKris Kennaway 			/* Note: under VMS with SOCKETSHR the second parameter
110974664626SKris Kennaway 			 * is currently of type (int *) whereas under other
111074664626SKris Kennaway 			 * systems it is (void *) if you don't have a cast it
111174664626SKris Kennaway 			 * will choke the compiler: if you do have a cast then
111274664626SKris Kennaway 			 * you can either go for (int *) or (void *).
111374664626SKris Kennaway 			 */
111450ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
111550ef0093SJacques Vidrine                         /* Under Windows/DOS we make the assumption that we can
1116f579bf8eSKris Kennaway 			 * always write to the tty: therefore if we need to
1117f579bf8eSKris Kennaway 			 * write to the tty we just fall through. Otherwise
1118f579bf8eSKris Kennaway 			 * we timeout the select every second and see if there
1119f579bf8eSKris Kennaway 			 * are any keypresses. Note: this is a hack, in a proper
1120f579bf8eSKris Kennaway 			 * Windows application we wouldn't do this.
1121f579bf8eSKris Kennaway 			 */
1122f579bf8eSKris Kennaway 			i=0;
1123f579bf8eSKris Kennaway 			if(!write_tty) {
1124f579bf8eSKris Kennaway 				if(read_tty) {
1125f579bf8eSKris Kennaway 					tv.tv_sec = 1;
1126f579bf8eSKris Kennaway 					tv.tv_usec = 0;
1127f579bf8eSKris Kennaway 					i=select(width,(void *)&readfds,(void *)&writefds,
1128f579bf8eSKris Kennaway 						 NULL,&tv);
112950ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
11305c87c606SMark Murray 					if(!i && (!_kbhit() || !read_tty) ) continue;
11315c87c606SMark Murray #else
1132ddd58736SKris Kennaway 					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
11335c87c606SMark Murray #endif
1134f579bf8eSKris Kennaway 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
1135f579bf8eSKris Kennaway 					 NULL,NULL);
1136f579bf8eSKris Kennaway 			}
11373b4e3dcbSSimon L. B. Nielsen #elif defined(OPENSSL_SYS_NETWARE)
11383b4e3dcbSSimon L. B. Nielsen 			if(!write_tty) {
11393b4e3dcbSSimon L. B. Nielsen 				if(read_tty) {
11403b4e3dcbSSimon L. B. Nielsen 					tv.tv_sec = 1;
11413b4e3dcbSSimon L. B. Nielsen 					tv.tv_usec = 0;
11423b4e3dcbSSimon L. B. Nielsen 					i=select(width,(void *)&readfds,(void *)&writefds,
11433b4e3dcbSSimon L. B. Nielsen 						NULL,&tv);
11443b4e3dcbSSimon L. B. Nielsen 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
11453b4e3dcbSSimon L. B. Nielsen 					NULL,NULL);
11463b4e3dcbSSimon L. B. Nielsen 			}
1147f579bf8eSKris Kennaway #else
114874664626SKris Kennaway 			i=select(width,(void *)&readfds,(void *)&writefds,
114974664626SKris Kennaway 				 NULL,NULL);
1150f579bf8eSKris Kennaway #endif
115174664626SKris Kennaway 			if ( i < 0)
115274664626SKris Kennaway 				{
115374664626SKris Kennaway 				BIO_printf(bio_err,"bad select %d\n",
115474664626SKris Kennaway 				get_last_socket_error());
115574664626SKris Kennaway 				goto shut;
115674664626SKris Kennaway 				/* goto end; */
115774664626SKris Kennaway 				}
115874664626SKris Kennaway 			}
115974664626SKris Kennaway 
116074664626SKris Kennaway 		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
116174664626SKris Kennaway 			{
116274664626SKris Kennaway 			k=SSL_write(con,&(cbuf[cbuf_off]),
116374664626SKris Kennaway 				(unsigned int)cbuf_len);
116474664626SKris Kennaway 			switch (SSL_get_error(con,k))
116574664626SKris Kennaway 				{
116674664626SKris Kennaway 			case SSL_ERROR_NONE:
116774664626SKris Kennaway 				cbuf_off+=k;
116874664626SKris Kennaway 				cbuf_len-=k;
116974664626SKris Kennaway 				if (k <= 0) goto end;
117074664626SKris Kennaway 				/* we have done a  write(con,NULL,0); */
117174664626SKris Kennaway 				if (cbuf_len <= 0)
117274664626SKris Kennaway 					{
117374664626SKris Kennaway 					read_tty=1;
117474664626SKris Kennaway 					write_ssl=0;
117574664626SKris Kennaway 					}
117674664626SKris Kennaway 				else /* if (cbuf_len > 0) */
117774664626SKris Kennaway 					{
117874664626SKris Kennaway 					read_tty=0;
117974664626SKris Kennaway 					write_ssl=1;
118074664626SKris Kennaway 					}
118174664626SKris Kennaway 				break;
118274664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
118374664626SKris Kennaway 				BIO_printf(bio_c_out,"write W BLOCK\n");
118474664626SKris Kennaway 				write_ssl=1;
118574664626SKris Kennaway 				read_tty=0;
118674664626SKris Kennaway 				break;
118774664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
118874664626SKris Kennaway 				BIO_printf(bio_c_out,"write R BLOCK\n");
118974664626SKris Kennaway 				write_tty=0;
119074664626SKris Kennaway 				read_ssl=1;
119174664626SKris Kennaway 				write_ssl=0;
119274664626SKris Kennaway 				break;
119374664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
119474664626SKris Kennaway 				BIO_printf(bio_c_out,"write X BLOCK\n");
119574664626SKris Kennaway 				break;
119674664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
119774664626SKris Kennaway 				if (cbuf_len != 0)
119874664626SKris Kennaway 					{
119974664626SKris Kennaway 					BIO_printf(bio_c_out,"shutdown\n");
120074664626SKris Kennaway 					goto shut;
120174664626SKris Kennaway 					}
120274664626SKris Kennaway 				else
120374664626SKris Kennaway 					{
120474664626SKris Kennaway 					read_tty=1;
120574664626SKris Kennaway 					write_ssl=0;
120674664626SKris Kennaway 					break;
120774664626SKris Kennaway 					}
120874664626SKris Kennaway 
120974664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
121074664626SKris Kennaway 				if ((k != 0) || (cbuf_len != 0))
121174664626SKris Kennaway 					{
121274664626SKris Kennaway 					BIO_printf(bio_err,"write:errno=%d\n",
121374664626SKris Kennaway 						get_last_socket_error());
121474664626SKris Kennaway 					goto shut;
121574664626SKris Kennaway 					}
121674664626SKris Kennaway 				else
121774664626SKris Kennaway 					{
121874664626SKris Kennaway 					read_tty=1;
121974664626SKris Kennaway 					write_ssl=0;
122074664626SKris Kennaway 					}
122174664626SKris Kennaway 				break;
122274664626SKris Kennaway 			case SSL_ERROR_SSL:
122374664626SKris Kennaway 				ERR_print_errors(bio_err);
122474664626SKris Kennaway 				goto shut;
122574664626SKris Kennaway 				}
122674664626SKris Kennaway 			}
12273b4e3dcbSSimon L. B. Nielsen #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
12285c87c606SMark Murray 		/* Assume Windows/DOS can always write */
1229f579bf8eSKris Kennaway 		else if (!ssl_pending && write_tty)
1230f579bf8eSKris Kennaway #else
123174664626SKris Kennaway 		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
1232f579bf8eSKris Kennaway #endif
123374664626SKris Kennaway 			{
123474664626SKris Kennaway #ifdef CHARSET_EBCDIC
123574664626SKris Kennaway 			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
123674664626SKris Kennaway #endif
123774664626SKris Kennaway 			i=write(fileno(stdout),&(sbuf[sbuf_off]),sbuf_len);
123874664626SKris Kennaway 
123974664626SKris Kennaway 			if (i <= 0)
124074664626SKris Kennaway 				{
124174664626SKris Kennaway 				BIO_printf(bio_c_out,"DONE\n");
124274664626SKris Kennaway 				goto shut;
124374664626SKris Kennaway 				/* goto end; */
124474664626SKris Kennaway 				}
124574664626SKris Kennaway 
124674664626SKris Kennaway 			sbuf_len-=i;;
124774664626SKris Kennaway 			sbuf_off+=i;
124874664626SKris Kennaway 			if (sbuf_len <= 0)
124974664626SKris Kennaway 				{
125074664626SKris Kennaway 				read_ssl=1;
125174664626SKris Kennaway 				write_tty=0;
125274664626SKris Kennaway 				}
125374664626SKris Kennaway 			}
125474664626SKris Kennaway 		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
125574664626SKris Kennaway 			{
125674664626SKris Kennaway #ifdef RENEG
125774664626SKris Kennaway { static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
125874664626SKris Kennaway #endif
125974664626SKris Kennaway #if 1
126074664626SKris Kennaway 			k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
126174664626SKris Kennaway #else
126274664626SKris Kennaway /* Demo for pending and peek :-) */
126374664626SKris Kennaway 			k=SSL_read(con,sbuf,16);
126474664626SKris Kennaway { char zbuf[10240];
126574664626SKris Kennaway printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
126674664626SKris Kennaway }
126774664626SKris Kennaway #endif
126874664626SKris Kennaway 
126974664626SKris Kennaway 			switch (SSL_get_error(con,k))
127074664626SKris Kennaway 				{
127174664626SKris Kennaway 			case SSL_ERROR_NONE:
127274664626SKris Kennaway 				if (k <= 0)
127374664626SKris Kennaway 					goto end;
127474664626SKris Kennaway 				sbuf_off=0;
127574664626SKris Kennaway 				sbuf_len=k;
127674664626SKris Kennaway 
127774664626SKris Kennaway 				read_ssl=0;
127874664626SKris Kennaway 				write_tty=1;
127974664626SKris Kennaway 				break;
128074664626SKris Kennaway 			case SSL_ERROR_WANT_WRITE:
128174664626SKris Kennaway 				BIO_printf(bio_c_out,"read W BLOCK\n");
128274664626SKris Kennaway 				write_ssl=1;
128374664626SKris Kennaway 				read_tty=0;
128474664626SKris Kennaway 				break;
128574664626SKris Kennaway 			case SSL_ERROR_WANT_READ:
128674664626SKris Kennaway 				BIO_printf(bio_c_out,"read R BLOCK\n");
128774664626SKris Kennaway 				write_tty=0;
128874664626SKris Kennaway 				read_ssl=1;
128974664626SKris Kennaway 				if ((read_tty == 0) && (write_ssl == 0))
129074664626SKris Kennaway 					write_ssl=1;
129174664626SKris Kennaway 				break;
129274664626SKris Kennaway 			case SSL_ERROR_WANT_X509_LOOKUP:
129374664626SKris Kennaway 				BIO_printf(bio_c_out,"read X BLOCK\n");
129474664626SKris Kennaway 				break;
129574664626SKris Kennaway 			case SSL_ERROR_SYSCALL:
129674664626SKris Kennaway 				BIO_printf(bio_err,"read:errno=%d\n",get_last_socket_error());
129774664626SKris Kennaway 				goto shut;
129874664626SKris Kennaway 			case SSL_ERROR_ZERO_RETURN:
129974664626SKris Kennaway 				BIO_printf(bio_c_out,"closed\n");
130074664626SKris Kennaway 				goto shut;
130174664626SKris Kennaway 			case SSL_ERROR_SSL:
130274664626SKris Kennaway 				ERR_print_errors(bio_err);
130374664626SKris Kennaway 				goto shut;
130474664626SKris Kennaway 				/* break; */
130574664626SKris Kennaway 				}
130674664626SKris Kennaway 			}
130774664626SKris Kennaway 
130850ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
130950ef0093SJacques Vidrine #if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
13105c87c606SMark Murray 		else if (_kbhit())
13115c87c606SMark Murray #else
1312ddd58736SKris Kennaway 		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
13135c87c606SMark Murray #endif
13143b4e3dcbSSimon L. B. Nielsen #elif defined (OPENSSL_SYS_NETWARE)
13153b4e3dcbSSimon L. B. Nielsen         else if (_kbhit())
1316f579bf8eSKris Kennaway #else
131774664626SKris Kennaway 		else if (FD_ISSET(fileno(stdin),&readfds))
1318f579bf8eSKris Kennaway #endif
131974664626SKris Kennaway 			{
132074664626SKris Kennaway 			if (crlf)
132174664626SKris Kennaway 				{
132274664626SKris Kennaway 				int j, lf_num;
132374664626SKris Kennaway 
132474664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ/2);
132574664626SKris Kennaway 				lf_num = 0;
132674664626SKris Kennaway 				/* both loops are skipped when i <= 0 */
132774664626SKris Kennaway 				for (j = 0; j < i; j++)
132874664626SKris Kennaway 					if (cbuf[j] == '\n')
132974664626SKris Kennaway 						lf_num++;
133074664626SKris Kennaway 				for (j = i-1; j >= 0; j--)
133174664626SKris Kennaway 					{
133274664626SKris Kennaway 					cbuf[j+lf_num] = cbuf[j];
133374664626SKris Kennaway 					if (cbuf[j] == '\n')
133474664626SKris Kennaway 						{
133574664626SKris Kennaway 						lf_num--;
133674664626SKris Kennaway 						i++;
133774664626SKris Kennaway 						cbuf[j+lf_num] = '\r';
133874664626SKris Kennaway 						}
133974664626SKris Kennaway 					}
134074664626SKris Kennaway 				assert(lf_num == 0);
134174664626SKris Kennaway 				}
134274664626SKris Kennaway 			else
134374664626SKris Kennaway 				i=read(fileno(stdin),cbuf,BUFSIZZ);
134474664626SKris Kennaway 
1345f579bf8eSKris Kennaway 			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
134674664626SKris Kennaway 				{
134774664626SKris Kennaway 				BIO_printf(bio_err,"DONE\n");
134874664626SKris Kennaway 				goto shut;
134974664626SKris Kennaway 				}
135074664626SKris Kennaway 
1351f579bf8eSKris Kennaway 			if ((!c_ign_eof) && (cbuf[0] == 'R'))
135274664626SKris Kennaway 				{
135374664626SKris Kennaway 				BIO_printf(bio_err,"RENEGOTIATING\n");
135474664626SKris Kennaway 				SSL_renegotiate(con);
135574664626SKris Kennaway 				cbuf_len=0;
135674664626SKris Kennaway 				}
135774664626SKris Kennaway 			else
135874664626SKris Kennaway 				{
135974664626SKris Kennaway 				cbuf_len=i;
136074664626SKris Kennaway 				cbuf_off=0;
136174664626SKris Kennaway #ifdef CHARSET_EBCDIC
136274664626SKris Kennaway 				ebcdic2ascii(cbuf, cbuf, i);
136374664626SKris Kennaway #endif
136474664626SKris Kennaway 				}
136574664626SKris Kennaway 
136674664626SKris Kennaway 			write_ssl=1;
136774664626SKris Kennaway 			read_tty=0;
136874664626SKris Kennaway 			}
136974664626SKris Kennaway 		}
137074664626SKris Kennaway shut:
137174664626SKris Kennaway 	SSL_shutdown(con);
137274664626SKris Kennaway 	SHUTDOWN(SSL_get_fd(con));
137374664626SKris Kennaway 	ret=0;
137474664626SKris Kennaway end:
1375f579bf8eSKris Kennaway 	if(prexit) print_stuff(bio_c_out,con,1);
137674664626SKris Kennaway 	if (con != NULL) SSL_free(con);
137774664626SKris Kennaway 	if (con2 != NULL) SSL_free(con2);
137874664626SKris Kennaway 	if (ctx != NULL) SSL_CTX_free(ctx);
13793b4e3dcbSSimon L. B. Nielsen 	if (cert)
13803b4e3dcbSSimon L. B. Nielsen 		X509_free(cert);
13813b4e3dcbSSimon L. B. Nielsen 	if (key)
13823b4e3dcbSSimon L. B. Nielsen 		EVP_PKEY_free(key);
13833b4e3dcbSSimon L. B. Nielsen 	if (pass)
13843b4e3dcbSSimon L. B. Nielsen 		OPENSSL_free(pass);
13855c87c606SMark Murray 	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
13865c87c606SMark Murray 	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
13875c87c606SMark Murray 	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
138874664626SKris Kennaway 	if (bio_c_out != NULL)
138974664626SKris Kennaway 		{
139074664626SKris Kennaway 		BIO_free(bio_c_out);
139174664626SKris Kennaway 		bio_c_out=NULL;
139274664626SKris Kennaway 		}
13935c87c606SMark Murray 	apps_shutdown();
13945c87c606SMark Murray 	OPENSSL_EXIT(ret);
139574664626SKris Kennaway 	}
139674664626SKris Kennaway 
139774664626SKris Kennaway 
139874664626SKris Kennaway static void print_stuff(BIO *bio, SSL *s, int full)
139974664626SKris Kennaway 	{
140074664626SKris Kennaway 	X509 *peer=NULL;
140174664626SKris Kennaway 	char *p;
14023b4e3dcbSSimon L. B. Nielsen 	static const char *space="                ";
140374664626SKris Kennaway 	char buf[BUFSIZ];
140474664626SKris Kennaway 	STACK_OF(X509) *sk;
140574664626SKris Kennaway 	STACK_OF(X509_NAME) *sk2;
140674664626SKris Kennaway 	SSL_CIPHER *c;
140774664626SKris Kennaway 	X509_NAME *xn;
140874664626SKris Kennaway 	int j,i;
14093b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
14103b4e3dcbSSimon L. B. Nielsen 	const COMP_METHOD *comp, *expansion;
14113b4e3dcbSSimon L. B. Nielsen #endif
141274664626SKris Kennaway 
141374664626SKris Kennaway 	if (full)
141474664626SKris Kennaway 		{
141574664626SKris Kennaway 		int got_a_chain = 0;
141674664626SKris Kennaway 
141774664626SKris Kennaway 		sk=SSL_get_peer_cert_chain(s);
141874664626SKris Kennaway 		if (sk != NULL)
141974664626SKris Kennaway 			{
142074664626SKris Kennaway 			got_a_chain = 1; /* we don't have it for SSL2 (yet) */
142174664626SKris Kennaway 
142274664626SKris Kennaway 			BIO_printf(bio,"---\nCertificate chain\n");
142374664626SKris Kennaway 			for (i=0; i<sk_X509_num(sk); i++)
142474664626SKris Kennaway 				{
142574664626SKris Kennaway 				X509_NAME_oneline(X509_get_subject_name(
14265c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
142774664626SKris Kennaway 				BIO_printf(bio,"%2d s:%s\n",i,buf);
142874664626SKris Kennaway 				X509_NAME_oneline(X509_get_issuer_name(
14295c87c606SMark Murray 					sk_X509_value(sk,i)),buf,sizeof buf);
143074664626SKris Kennaway 				BIO_printf(bio,"   i:%s\n",buf);
143174664626SKris Kennaway 				if (c_showcerts)
143274664626SKris Kennaway 					PEM_write_bio_X509(bio,sk_X509_value(sk,i));
143374664626SKris Kennaway 				}
143474664626SKris Kennaway 			}
143574664626SKris Kennaway 
143674664626SKris Kennaway 		BIO_printf(bio,"---\n");
143774664626SKris Kennaway 		peer=SSL_get_peer_certificate(s);
143874664626SKris Kennaway 		if (peer != NULL)
143974664626SKris Kennaway 			{
144074664626SKris Kennaway 			BIO_printf(bio,"Server certificate\n");
144174664626SKris Kennaway 			if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */
144274664626SKris Kennaway 				PEM_write_bio_X509(bio,peer);
144374664626SKris Kennaway 			X509_NAME_oneline(X509_get_subject_name(peer),
14445c87c606SMark Murray 				buf,sizeof buf);
144574664626SKris Kennaway 			BIO_printf(bio,"subject=%s\n",buf);
144674664626SKris Kennaway 			X509_NAME_oneline(X509_get_issuer_name(peer),
14475c87c606SMark Murray 				buf,sizeof buf);
144874664626SKris Kennaway 			BIO_printf(bio,"issuer=%s\n",buf);
144974664626SKris Kennaway 			}
145074664626SKris Kennaway 		else
145174664626SKris Kennaway 			BIO_printf(bio,"no peer certificate available\n");
145274664626SKris Kennaway 
145374664626SKris Kennaway 		sk2=SSL_get_client_CA_list(s);
145474664626SKris Kennaway 		if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0))
145574664626SKris Kennaway 			{
145674664626SKris Kennaway 			BIO_printf(bio,"---\nAcceptable client certificate CA names\n");
145774664626SKris Kennaway 			for (i=0; i<sk_X509_NAME_num(sk2); i++)
145874664626SKris Kennaway 				{
145974664626SKris Kennaway 				xn=sk_X509_NAME_value(sk2,i);
146074664626SKris Kennaway 				X509_NAME_oneline(xn,buf,sizeof(buf));
146174664626SKris Kennaway 				BIO_write(bio,buf,strlen(buf));
146274664626SKris Kennaway 				BIO_write(bio,"\n",1);
146374664626SKris Kennaway 				}
146474664626SKris Kennaway 			}
146574664626SKris Kennaway 		else
146674664626SKris Kennaway 			{
146774664626SKris Kennaway 			BIO_printf(bio,"---\nNo client certificate CA names sent\n");
146874664626SKris Kennaway 			}
14695c87c606SMark Murray 		p=SSL_get_shared_ciphers(s,buf,sizeof buf);
147074664626SKris Kennaway 		if (p != NULL)
147174664626SKris Kennaway 			{
147274664626SKris Kennaway 			/* This works only for SSL 2.  In later protocol
147374664626SKris Kennaway 			 * versions, the client does not know what other
147474664626SKris Kennaway 			 * ciphers (in addition to the one to be used
147574664626SKris Kennaway 			 * in the current connection) the server supports. */
147674664626SKris Kennaway 
147774664626SKris Kennaway 			BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n");
147874664626SKris Kennaway 			j=i=0;
147974664626SKris Kennaway 			while (*p)
148074664626SKris Kennaway 				{
148174664626SKris Kennaway 				if (*p == ':')
148274664626SKris Kennaway 					{
148374664626SKris Kennaway 					BIO_write(bio,space,15-j%25);
148474664626SKris Kennaway 					i++;
148574664626SKris Kennaway 					j=0;
148674664626SKris Kennaway 					BIO_write(bio,((i%3)?" ":"\n"),1);
148774664626SKris Kennaway 					}
148874664626SKris Kennaway 				else
148974664626SKris Kennaway 					{
149074664626SKris Kennaway 					BIO_write(bio,p,1);
149174664626SKris Kennaway 					j++;
149274664626SKris Kennaway 					}
149374664626SKris Kennaway 				p++;
149474664626SKris Kennaway 				}
149574664626SKris Kennaway 			BIO_write(bio,"\n",1);
149674664626SKris Kennaway 			}
149774664626SKris Kennaway 
149874664626SKris Kennaway 		BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n",
149974664626SKris Kennaway 			BIO_number_read(SSL_get_rbio(s)),
150074664626SKris Kennaway 			BIO_number_written(SSL_get_wbio(s)));
150174664626SKris Kennaway 		}
150274664626SKris Kennaway 	BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, "));
150374664626SKris Kennaway 	c=SSL_get_current_cipher(s);
150474664626SKris Kennaway 	BIO_printf(bio,"%s, Cipher is %s\n",
150574664626SKris Kennaway 		SSL_CIPHER_get_version(c),
150674664626SKris Kennaway 		SSL_CIPHER_get_name(c));
150774664626SKris Kennaway 	if (peer != NULL) {
150874664626SKris Kennaway 		EVP_PKEY *pktmp;
150974664626SKris Kennaway 		pktmp = X509_get_pubkey(peer);
151074664626SKris Kennaway 		BIO_printf(bio,"Server public key is %d bit\n",
151174664626SKris Kennaway 							 EVP_PKEY_bits(pktmp));
151274664626SKris Kennaway 		EVP_PKEY_free(pktmp);
151374664626SKris Kennaway 	}
15143b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
15153b4e3dcbSSimon L. B. Nielsen 	comp=SSL_get_current_compression(s);
15163b4e3dcbSSimon L. B. Nielsen 	expansion=SSL_get_current_expansion(s);
15173b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio,"Compression: %s\n",
15183b4e3dcbSSimon L. B. Nielsen 		comp ? SSL_COMP_get_name(comp) : "NONE");
15193b4e3dcbSSimon L. B. Nielsen 	BIO_printf(bio,"Expansion: %s\n",
15203b4e3dcbSSimon L. B. Nielsen 		expansion ? SSL_COMP_get_name(expansion) : "NONE");
15213b4e3dcbSSimon L. B. Nielsen #endif
152274664626SKris Kennaway 	SSL_SESSION_print(bio,SSL_get_session(s));
152374664626SKris Kennaway 	BIO_printf(bio,"---\n");
152474664626SKris Kennaway 	if (peer != NULL)
152574664626SKris Kennaway 		X509_free(peer);
1526a21b1b38SKris Kennaway 	/* flush, or debugging output gets mixed with http response */
1527db522d3aSSimon L. B. Nielsen 	(void)BIO_flush(bio);
152874664626SKris Kennaway 	}
152974664626SKris Kennaway 
1530db522d3aSSimon L. B. Nielsen #ifndef OPENSSL_NO_TLSEXT
1531db522d3aSSimon L. B. Nielsen 
1532db522d3aSSimon L. B. Nielsen static int ocsp_resp_cb(SSL *s, void *arg)
1533db522d3aSSimon L. B. Nielsen 	{
1534db522d3aSSimon L. B. Nielsen 	const unsigned char *p;
1535db522d3aSSimon L. B. Nielsen 	int len;
1536db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE *rsp;
1537db522d3aSSimon L. B. Nielsen 	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
1538db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "OCSP response: ");
1539db522d3aSSimon L. B. Nielsen 	if (!p)
1540db522d3aSSimon L. B. Nielsen 		{
1541db522d3aSSimon L. B. Nielsen 		BIO_puts(arg, "no response sent\n");
1542db522d3aSSimon L. B. Nielsen 		return 1;
1543db522d3aSSimon L. B. Nielsen 		}
1544db522d3aSSimon L. B. Nielsen 	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
1545db522d3aSSimon L. B. Nielsen 	if (!rsp)
1546db522d3aSSimon L. B. Nielsen 		{
1547db522d3aSSimon L. B. Nielsen 		BIO_puts(arg, "response parse error\n");
1548db522d3aSSimon L. B. Nielsen 		BIO_dump_indent(arg, (char *)p, len, 4);
1549db522d3aSSimon L. B. Nielsen 		return 0;
1550db522d3aSSimon L. B. Nielsen 		}
1551db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "\n======================================\n");
1552db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE_print(arg, rsp, 0);
1553db522d3aSSimon L. B. Nielsen 	BIO_puts(arg, "======================================\n");
1554db522d3aSSimon L. B. Nielsen 	OCSP_RESPONSE_free(rsp);
1555db522d3aSSimon L. B. Nielsen 	return 1;
1556db522d3aSSimon L. B. Nielsen 	}
1557db522d3aSSimon L. B. Nielsen #endif  /* ndef OPENSSL_NO_TLSEXT */
1558