s_server.c revision 109998
1/* apps/s_server.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to.  The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 *    notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 *    notice, this list of conditions and the following disclaimer in the
30 *    documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 *    must display the following acknowledgement:
33 *    "This product includes cryptographic software written by
34 *     Eric Young (eay@cryptsoft.com)"
35 *    The word 'cryptographic' can be left out if the rouines from the library
36 *    being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 *    the apps directory (application code) you must include an acknowledgement:
39 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 *    notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in
70 *    the documentation and/or other materials provided with the
71 *    distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 *    software must display the following acknowledgment:
75 *    "This product includes software developed by the OpenSSL Project
76 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 *    endorse or promote products derived from this software without
80 *    prior written permission. For written permission, please contact
81 *    openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 *    nor may "OpenSSL" appear in their names without prior written
85 *    permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 *    acknowledgment:
89 *    "This product includes software developed by the OpenSSL Project
90 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com).  This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <assert.h>
113#include <stdio.h>
114#include <stdlib.h>
115#include <string.h>
116#include <sys/types.h>
117#include <sys/stat.h>
118#include <openssl/e_os2.h>
119#ifdef OPENSSL_NO_STDIO
120#define APPS_WIN16
121#endif
122
123/* With IPv6, it looks like Digital has mixed up the proper order of
124   recursive header file inclusion, resulting in the compiler complaining
125   that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
126   is needed to have fileno() declared correctly...  So let's define u_int */
127#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
128#define __U_INT
129typedef unsigned int u_int;
130#endif
131
132#include <openssl/lhash.h>
133#include <openssl/bn.h>
134#define USE_SOCKETS
135#include "apps.h"
136#include <openssl/err.h>
137#include <openssl/pem.h>
138#include <openssl/x509.h>
139#include <openssl/ssl.h>
140#include <openssl/rand.h>
141#include "s_apps.h"
142
143#ifdef OPENSSL_SYS_WINDOWS
144#include <conio.h>
145#endif
146
147#ifdef OPENSSL_SYS_WINCE
148/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
149#ifdef fileno
150#undef fileno
151#endif
152#define fileno(a) (int)_fileno(a)
153#endif
154
155#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
156/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
157#undef FIONBIO
158#endif
159
160#ifndef OPENSSL_NO_RSA
161static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
162#endif
163static int sv_body(char *hostname, int s, unsigned char *context);
164static int www_body(char *hostname, int s, unsigned char *context);
165static void close_accept_socket(void );
166static void sv_usage(void);
167static int init_ssl_connection(SSL *s);
168static void print_stats(BIO *bp,SSL_CTX *ctx);
169static int generate_session_id(const SSL *ssl, unsigned char *id,
170				unsigned int *id_len);
171#ifndef OPENSSL_NO_DH
172static DH *load_dh_param(char *dhfile);
173static DH *get_dh512(void);
174#endif
175#ifdef MONOLITH
176static void s_server_init(void);
177#endif
178
179#ifndef S_ISDIR
180# if defined(_S_IFMT) && defined(_S_IFDIR)
181#  define S_ISDIR(a)	(((a) & _S_IFMT) == _S_IFDIR)
182# else
183#  define S_ISDIR(a)	(((a) & S_IFMT) == S_IFDIR)
184# endif
185#endif
186
187#ifndef OPENSSL_NO_DH
188static unsigned char dh512_p[]={
189	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
190	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
191	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
192	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
193	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
194	0x47,0x74,0xE8,0x33,
195	};
196static unsigned char dh512_g[]={
197	0x02,
198	};
199
200static DH *get_dh512(void)
201	{
202	DH *dh=NULL;
203
204	if ((dh=DH_new()) == NULL) return(NULL);
205	dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
206	dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
207	if ((dh->p == NULL) || (dh->g == NULL))
208		return(NULL);
209	return(dh);
210	}
211#endif
212
213/* static int load_CA(SSL_CTX *ctx, char *file);*/
214
215#undef BUFSIZZ
216#define BUFSIZZ	16*1024
217static int bufsize=BUFSIZZ;
218static int accept_socket= -1;
219
220#define TEST_CERT	"server.pem"
221#undef PROG
222#define PROG		s_server_main
223
224extern int verify_depth;
225
226static char *cipher=NULL;
227static int s_server_verify=SSL_VERIFY_NONE;
228static int s_server_session_id_context = 1; /* anything will do */
229static char *s_cert_file=TEST_CERT,*s_key_file=NULL;
230static char *s_dcert_file=NULL,*s_dkey_file=NULL;
231#ifdef FIONBIO
232static int s_nbio=0;
233#endif
234static int s_nbio_test=0;
235int s_crlf=0;
236static SSL_CTX *ctx=NULL;
237static int www=0;
238
239static BIO *bio_s_out=NULL;
240static int s_debug=0;
241static int s_msg=0;
242static int s_quiet=0;
243
244static int hack=0;
245static char *engine_id=NULL;
246static const char *session_id_prefix=NULL;
247
248#ifdef MONOLITH
249static void s_server_init(void)
250	{
251	accept_socket=-1;
252	cipher=NULL;
253	s_server_verify=SSL_VERIFY_NONE;
254	s_dcert_file=NULL;
255	s_dkey_file=NULL;
256	s_cert_file=TEST_CERT;
257	s_key_file=NULL;
258#ifdef FIONBIO
259	s_nbio=0;
260#endif
261	s_nbio_test=0;
262	ctx=NULL;
263	www=0;
264
265	bio_s_out=NULL;
266	s_debug=0;
267	s_msg=0;
268	s_quiet=0;
269	hack=0;
270	engine_id=NULL;
271	}
272#endif
273
274static void sv_usage(void)
275	{
276	BIO_printf(bio_err,"usage: s_server [args ...]\n");
277	BIO_printf(bio_err,"\n");
278	BIO_printf(bio_err," -accept arg   - port to accept on (default is %d)\n",PORT);
279	BIO_printf(bio_err," -context arg  - set session ID context\n");
280	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
281	BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
282	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
283	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
284	BIO_printf(bio_err," -key arg      - Private Key file to use, PEM format assumed, in cert file if\n");
285	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
286	BIO_printf(bio_err," -dcert arg    - second certificate file to use (usually for DSA)\n");
287	BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
288	BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
289	BIO_printf(bio_err,"                 or a default set of parameters is used\n");
290#ifdef FIONBIO
291	BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
292#endif
293	BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
294	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
295	BIO_printf(bio_err," -debug        - Print more output\n");
296	BIO_printf(bio_err," -msg          - Show protocol messages\n");
297	BIO_printf(bio_err," -state        - Print the SSL states\n");
298	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
299	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
300	BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
301	BIO_printf(bio_err," -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
302	BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
303	BIO_printf(bio_err," -quiet        - No server output\n");
304	BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
305	BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
306	BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
307	BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
308	BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
309	BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
310	BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
311#ifndef OPENSSL_NO_DH
312	BIO_printf(bio_err," -no_dhe       - Disable ephemeral DH\n");
313#endif
314	BIO_printf(bio_err," -bugs         - Turn on SSL bug compatibility\n");
315	BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
316	BIO_printf(bio_err," -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
317	BIO_printf(bio_err," -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
318        BIO_printf(bio_err,"                 with the assumption it contains a complete HTTP response.\n");
319	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
320	BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
321	BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
322	}
323
324static int local_argc=0;
325static char **local_argv;
326
327#ifdef CHARSET_EBCDIC
328static int ebcdic_new(BIO *bi);
329static int ebcdic_free(BIO *a);
330static int ebcdic_read(BIO *b, char *out, int outl);
331static int ebcdic_write(BIO *b, const char *in, int inl);
332static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
333static int ebcdic_gets(BIO *bp, char *buf, int size);
334static int ebcdic_puts(BIO *bp, const char *str);
335
336#define BIO_TYPE_EBCDIC_FILTER	(18|0x0200)
337static BIO_METHOD methods_ebcdic=
338	{
339	BIO_TYPE_EBCDIC_FILTER,
340	"EBCDIC/ASCII filter",
341	ebcdic_write,
342	ebcdic_read,
343	ebcdic_puts,
344	ebcdic_gets,
345	ebcdic_ctrl,
346	ebcdic_new,
347	ebcdic_free,
348	};
349
350typedef struct
351{
352	size_t	alloced;
353	char	buff[1];
354} EBCDIC_OUTBUFF;
355
356BIO_METHOD *BIO_f_ebcdic_filter()
357{
358	return(&methods_ebcdic);
359}
360
361static int ebcdic_new(BIO *bi)
362{
363	EBCDIC_OUTBUFF *wbuf;
364
365	wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
366	wbuf->alloced = 1024;
367	wbuf->buff[0] = '\0';
368
369	bi->ptr=(char *)wbuf;
370	bi->init=1;
371	bi->flags=0;
372	return(1);
373}
374
375static int ebcdic_free(BIO *a)
376{
377	if (a == NULL) return(0);
378	if (a->ptr != NULL)
379		OPENSSL_free(a->ptr);
380	a->ptr=NULL;
381	a->init=0;
382	a->flags=0;
383	return(1);
384}
385
386static int ebcdic_read(BIO *b, char *out, int outl)
387{
388	int ret=0;
389
390	if (out == NULL || outl == 0) return(0);
391	if (b->next_bio == NULL) return(0);
392
393	ret=BIO_read(b->next_bio,out,outl);
394	if (ret > 0)
395		ascii2ebcdic(out,out,ret);
396	return(ret);
397}
398
399static int ebcdic_write(BIO *b, const char *in, int inl)
400{
401	EBCDIC_OUTBUFF *wbuf;
402	int ret=0;
403	int num;
404	unsigned char n;
405
406	if ((in == NULL) || (inl <= 0)) return(0);
407	if (b->next_bio == NULL) return(0);
408
409	wbuf=(EBCDIC_OUTBUFF *)b->ptr;
410
411	if (inl > (num = wbuf->alloced))
412	{
413		num = num + num;  /* double the size */
414		if (num < inl)
415			num = inl;
416		OPENSSL_free(wbuf);
417		wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
418
419		wbuf->alloced = num;
420		wbuf->buff[0] = '\0';
421
422		b->ptr=(char *)wbuf;
423	}
424
425	ebcdic2ascii(wbuf->buff, in, inl);
426
427	ret=BIO_write(b->next_bio, wbuf->buff, inl);
428
429	return(ret);
430}
431
432static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
433{
434	long ret;
435
436	if (b->next_bio == NULL) return(0);
437	switch (cmd)
438	{
439	case BIO_CTRL_DUP:
440		ret=0L;
441		break;
442	default:
443		ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
444		break;
445	}
446	return(ret);
447}
448
449static int ebcdic_gets(BIO *bp, char *buf, int size)
450{
451	int i, ret=0;
452	if (bp->next_bio == NULL) return(0);
453/*	return(BIO_gets(bp->next_bio,buf,size));*/
454	for (i=0; i<size-1; ++i)
455	{
456		ret = ebcdic_read(bp,&buf[i],1);
457		if (ret <= 0)
458			break;
459		else if (buf[i] == '\n')
460		{
461			++i;
462			break;
463		}
464	}
465	if (i < size)
466		buf[i] = '\0';
467	return (ret < 0 && i == 0) ? ret : i;
468}
469
470static int ebcdic_puts(BIO *bp, const char *str)
471{
472	if (bp->next_bio == NULL) return(0);
473	return ebcdic_write(bp, str, strlen(str));
474}
475#endif
476
477int MAIN(int, char **);
478
479int MAIN(int argc, char *argv[])
480	{
481	X509_STORE *store = NULL;
482	int vflags = 0;
483	short port=PORT;
484	char *CApath=NULL,*CAfile=NULL;
485	char *context = NULL;
486	char *dhfile = NULL;
487	int badop=0,bugs=0;
488	int ret=1;
489	int off=0;
490	int no_tmp_rsa=0,no_dhe=0,nocert=0;
491	int state=0;
492	SSL_METHOD *meth=NULL;
493	ENGINE *e=NULL;
494	char *inrand=NULL;
495
496#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
497	meth=SSLv23_server_method();
498#elif !defined(OPENSSL_NO_SSL3)
499	meth=SSLv3_server_method();
500#elif !defined(OPENSSL_NO_SSL2)
501	meth=SSLv2_server_method();
502#endif
503
504	local_argc=argc;
505	local_argv=argv;
506
507	apps_startup();
508#ifdef MONOLITH
509	s_server_init();
510#endif
511
512	if (bio_err == NULL)
513		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
514
515	if (!load_config(bio_err, NULL))
516		goto end;
517
518	verify_depth=0;
519#ifdef FIONBIO
520	s_nbio=0;
521#endif
522	s_nbio_test=0;
523
524	argc--;
525	argv++;
526
527	while (argc >= 1)
528		{
529		if	((strcmp(*argv,"-port") == 0) ||
530			 (strcmp(*argv,"-accept") == 0))
531			{
532			if (--argc < 1) goto bad;
533			if (!extract_port(*(++argv),&port))
534				goto bad;
535			}
536		else if	(strcmp(*argv,"-verify") == 0)
537			{
538			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
539			if (--argc < 1) goto bad;
540			verify_depth=atoi(*(++argv));
541			BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
542			}
543		else if	(strcmp(*argv,"-Verify") == 0)
544			{
545			s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
546				SSL_VERIFY_CLIENT_ONCE;
547			if (--argc < 1) goto bad;
548			verify_depth=atoi(*(++argv));
549			BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
550			}
551		else if	(strcmp(*argv,"-context") == 0)
552			{
553			if (--argc < 1) goto bad;
554			context= *(++argv);
555			}
556		else if	(strcmp(*argv,"-cert") == 0)
557			{
558			if (--argc < 1) goto bad;
559			s_cert_file= *(++argv);
560			}
561		else if	(strcmp(*argv,"-key") == 0)
562			{
563			if (--argc < 1) goto bad;
564			s_key_file= *(++argv);
565			}
566		else if	(strcmp(*argv,"-dhparam") == 0)
567			{
568			if (--argc < 1) goto bad;
569			dhfile = *(++argv);
570			}
571		else if	(strcmp(*argv,"-dcert") == 0)
572			{
573			if (--argc < 1) goto bad;
574			s_dcert_file= *(++argv);
575			}
576		else if	(strcmp(*argv,"-dkey") == 0)
577			{
578			if (--argc < 1) goto bad;
579			s_dkey_file= *(++argv);
580			}
581		else if (strcmp(*argv,"-nocert") == 0)
582			{
583			nocert=1;
584			}
585		else if	(strcmp(*argv,"-CApath") == 0)
586			{
587			if (--argc < 1) goto bad;
588			CApath= *(++argv);
589			}
590		else if (strcmp(*argv,"-crl_check") == 0)
591			{
592			vflags |= X509_V_FLAG_CRL_CHECK;
593			}
594		else if (strcmp(*argv,"-crl_check") == 0)
595			{
596			vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
597			}
598		else if	(strcmp(*argv,"-serverpref") == 0)
599			{ off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
600		else if	(strcmp(*argv,"-cipher") == 0)
601			{
602			if (--argc < 1) goto bad;
603			cipher= *(++argv);
604			}
605		else if	(strcmp(*argv,"-CAfile") == 0)
606			{
607			if (--argc < 1) goto bad;
608			CAfile= *(++argv);
609			}
610#ifdef FIONBIO
611		else if	(strcmp(*argv,"-nbio") == 0)
612			{ s_nbio=1; }
613#endif
614		else if	(strcmp(*argv,"-nbio_test") == 0)
615			{
616#ifdef FIONBIO
617			s_nbio=1;
618#endif
619			s_nbio_test=1;
620			}
621		else if	(strcmp(*argv,"-debug") == 0)
622			{ s_debug=1; }
623		else if	(strcmp(*argv,"-msg") == 0)
624			{ s_msg=1; }
625		else if	(strcmp(*argv,"-hack") == 0)
626			{ hack=1; }
627		else if	(strcmp(*argv,"-state") == 0)
628			{ state=1; }
629		else if	(strcmp(*argv,"-crlf") == 0)
630			{ s_crlf=1; }
631		else if	(strcmp(*argv,"-quiet") == 0)
632			{ s_quiet=1; }
633		else if	(strcmp(*argv,"-bugs") == 0)
634			{ bugs=1; }
635		else if	(strcmp(*argv,"-no_tmp_rsa") == 0)
636			{ no_tmp_rsa=1; }
637		else if	(strcmp(*argv,"-no_dhe") == 0)
638			{ no_dhe=1; }
639		else if	(strcmp(*argv,"-www") == 0)
640			{ www=1; }
641		else if	(strcmp(*argv,"-WWW") == 0)
642			{ www=2; }
643		else if	(strcmp(*argv,"-HTTP") == 0)
644			{ www=3; }
645		else if	(strcmp(*argv,"-no_ssl2") == 0)
646			{ off|=SSL_OP_NO_SSLv2; }
647		else if	(strcmp(*argv,"-no_ssl3") == 0)
648			{ off|=SSL_OP_NO_SSLv3; }
649		else if	(strcmp(*argv,"-no_tls1") == 0)
650			{ off|=SSL_OP_NO_TLSv1; }
651#ifndef OPENSSL_NO_SSL2
652		else if	(strcmp(*argv,"-ssl2") == 0)
653			{ meth=SSLv2_server_method(); }
654#endif
655#ifndef OPENSSL_NO_SSL3
656		else if	(strcmp(*argv,"-ssl3") == 0)
657			{ meth=SSLv3_server_method(); }
658#endif
659#ifndef OPENSSL_NO_TLS1
660		else if	(strcmp(*argv,"-tls1") == 0)
661			{ meth=TLSv1_server_method(); }
662#endif
663		else if (strcmp(*argv, "-id_prefix") == 0)
664			{
665			if (--argc < 1) goto bad;
666			session_id_prefix = *(++argv);
667			}
668		else if (strcmp(*argv,"-engine") == 0)
669			{
670			if (--argc < 1) goto bad;
671			engine_id= *(++argv);
672			}
673		else if (strcmp(*argv,"-rand") == 0)
674			{
675			if (--argc < 1) goto bad;
676			inrand= *(++argv);
677			}
678		else
679			{
680			BIO_printf(bio_err,"unknown option %s\n",*argv);
681			badop=1;
682			break;
683			}
684		argc--;
685		argv++;
686		}
687	if (badop)
688		{
689bad:
690		sv_usage();
691		goto end;
692		}
693
694	SSL_load_error_strings();
695	OpenSSL_add_ssl_algorithms();
696
697        e = setup_engine(bio_err, engine_id, 1);
698
699	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
700		&& !RAND_status())
701		{
702		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
703		}
704	if (inrand != NULL)
705		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
706			app_RAND_load_files(inrand));
707
708	if (bio_s_out == NULL)
709		{
710		if (s_quiet && !s_debug && !s_msg)
711			{
712			bio_s_out=BIO_new(BIO_s_null());
713			}
714		else
715			{
716			if (bio_s_out == NULL)
717				bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
718			}
719		}
720
721#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
722	if (nocert)
723#endif
724		{
725		s_cert_file=NULL;
726		s_key_file=NULL;
727		s_dcert_file=NULL;
728		s_dkey_file=NULL;
729		}
730
731	ctx=SSL_CTX_new(meth);
732	if (ctx == NULL)
733		{
734		ERR_print_errors(bio_err);
735		goto end;
736		}
737	if (session_id_prefix)
738		{
739		if(strlen(session_id_prefix) >= 32)
740			BIO_printf(bio_err,
741"warning: id_prefix is too long, only one new session will be possible\n");
742		else if(strlen(session_id_prefix) >= 16)
743			BIO_printf(bio_err,
744"warning: id_prefix is too long if you use SSLv2\n");
745		if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
746			{
747			BIO_printf(bio_err,"error setting 'id_prefix'\n");
748			ERR_print_errors(bio_err);
749			goto end;
750			}
751		BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
752		}
753	SSL_CTX_set_quiet_shutdown(ctx,1);
754	if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
755	if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
756	SSL_CTX_set_options(ctx,off);
757
758	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
759
760	SSL_CTX_sess_set_cache_size(ctx,128);
761
762#if 0
763	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
764#endif
765
766#if 0
767	if (s_cert_file == NULL)
768		{
769		BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
770		goto end;
771		}
772#endif
773
774	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
775		(!SSL_CTX_set_default_verify_paths(ctx)))
776		{
777		/* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
778		ERR_print_errors(bio_err);
779		/* goto end; */
780		}
781	store = SSL_CTX_get_cert_store(ctx);
782	X509_STORE_set_flags(store, vflags);
783
784#ifndef OPENSSL_NO_DH
785	if (!no_dhe)
786		{
787		DH *dh=NULL;
788
789		if (dhfile)
790			dh = load_dh_param(dhfile);
791		else if (s_cert_file)
792			dh = load_dh_param(s_cert_file);
793
794		if (dh != NULL)
795			{
796			BIO_printf(bio_s_out,"Setting temp DH parameters\n");
797			}
798		else
799			{
800			BIO_printf(bio_s_out,"Using default temp DH parameters\n");
801			dh=get_dh512();
802			}
803		(void)BIO_flush(bio_s_out);
804
805		SSL_CTX_set_tmp_dh(ctx,dh);
806		DH_free(dh);
807		}
808#endif
809
810	if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
811		goto end;
812	if (s_dcert_file != NULL)
813		{
814		if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file))
815			goto end;
816		}
817
818#ifndef OPENSSL_NO_RSA
819#if 1
820	if (!no_tmp_rsa)
821		SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
822#else
823	if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
824		{
825		RSA *rsa;
826
827		BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
828		BIO_flush(bio_s_out);
829
830		rsa=RSA_generate_key(512,RSA_F4,NULL);
831
832		if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
833			{
834			ERR_print_errors(bio_err);
835			goto end;
836			}
837		RSA_free(rsa);
838		BIO_printf(bio_s_out,"\n");
839		}
840#endif
841#endif
842
843	if (cipher != NULL)
844		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
845		BIO_printf(bio_err,"error setting cipher list\n");
846		ERR_print_errors(bio_err);
847		goto end;
848	}
849	SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
850	SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
851		sizeof s_server_session_id_context);
852
853	if (CAfile != NULL)
854	    SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
855
856	BIO_printf(bio_s_out,"ACCEPT\n");
857	if (www)
858		do_server(port,&accept_socket,www_body, context);
859	else
860		do_server(port,&accept_socket,sv_body, context);
861	print_stats(bio_s_out,ctx);
862	ret=0;
863end:
864	if (ctx != NULL) SSL_CTX_free(ctx);
865	if (bio_s_out != NULL)
866		{
867		BIO_free(bio_s_out);
868		bio_s_out=NULL;
869		}
870	apps_shutdown();
871	OPENSSL_EXIT(ret);
872	}
873
874static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
875	{
876	BIO_printf(bio,"%4ld items in the session cache\n",
877		SSL_CTX_sess_number(ssl_ctx));
878	BIO_printf(bio,"%4d client connects (SSL_connect())\n",
879		SSL_CTX_sess_connect(ssl_ctx));
880	BIO_printf(bio,"%4d client renegotiates (SSL_connect())\n",
881		SSL_CTX_sess_connect_renegotiate(ssl_ctx));
882	BIO_printf(bio,"%4d client connects that finished\n",
883		SSL_CTX_sess_connect_good(ssl_ctx));
884	BIO_printf(bio,"%4d server accepts (SSL_accept())\n",
885		SSL_CTX_sess_accept(ssl_ctx));
886	BIO_printf(bio,"%4d server renegotiates (SSL_accept())\n",
887		SSL_CTX_sess_accept_renegotiate(ssl_ctx));
888	BIO_printf(bio,"%4d server accepts that finished\n",
889		SSL_CTX_sess_accept_good(ssl_ctx));
890	BIO_printf(bio,"%4d session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
891	BIO_printf(bio,"%4d session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
892	BIO_printf(bio,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
893	BIO_printf(bio,"%4d callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
894	BIO_printf(bio,"%4d cache full overflows (%d allowed)\n",
895		SSL_CTX_sess_cache_full(ssl_ctx),
896		SSL_CTX_sess_get_cache_size(ssl_ctx));
897	}
898
899static int sv_body(char *hostname, int s, unsigned char *context)
900	{
901	char *buf=NULL;
902	fd_set readfds;
903	int ret=1,width;
904	int k,i;
905	unsigned long l;
906	SSL *con=NULL;
907	BIO *sbio;
908#ifdef OPENSSL_SYS_WINDOWS
909	struct timeval tv;
910#endif
911
912	if ((buf=OPENSSL_malloc(bufsize)) == NULL)
913		{
914		BIO_printf(bio_err,"out of memory\n");
915		goto err;
916		}
917#ifdef FIONBIO
918	if (s_nbio)
919		{
920		unsigned long sl=1;
921
922		if (!s_quiet)
923			BIO_printf(bio_err,"turning on non blocking io\n");
924		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
925			ERR_print_errors(bio_err);
926		}
927#endif
928
929	if (con == NULL) {
930		con=SSL_new(ctx);
931#ifndef OPENSSL_NO_KRB5
932		if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
933                        {
934                        kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
935								KRB5SVC);
936                        kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
937								KRB5KEYTAB);
938                        }
939#endif	/* OPENSSL_NO_KRB5 */
940		if(context)
941		      SSL_set_session_id_context(con, context,
942						 strlen((char *)context));
943	}
944	SSL_clear(con);
945
946	sbio=BIO_new_socket(s,BIO_NOCLOSE);
947	if (s_nbio_test)
948		{
949		BIO *test;
950
951		test=BIO_new(BIO_f_nbio_test());
952		sbio=BIO_push(test,sbio);
953		}
954	SSL_set_bio(con,sbio,sbio);
955	SSL_set_accept_state(con);
956	/* SSL_set_fd(con,s); */
957
958	if (s_debug)
959		{
960		con->debug=1;
961		BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
962		BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
963		}
964	if (s_msg)
965		{
966		SSL_set_msg_callback(con, msg_cb);
967		SSL_set_msg_callback_arg(con, bio_s_out);
968		}
969
970	width=s+1;
971	for (;;)
972		{
973		int read_from_terminal;
974		int read_from_sslcon;
975
976		read_from_terminal = 0;
977		read_from_sslcon = SSL_pending(con);
978
979		if (!read_from_sslcon)
980			{
981			FD_ZERO(&readfds);
982#ifndef OPENSSL_SYS_WINDOWS
983			FD_SET(fileno(stdin),&readfds);
984#endif
985			FD_SET(s,&readfds);
986			/* Note: under VMS with SOCKETSHR the second parameter is
987			 * currently of type (int *) whereas under other systems
988			 * it is (void *) if you don't have a cast it will choke
989			 * the compiler: if you do have a cast then you can either
990			 * go for (int *) or (void *).
991			 */
992#ifdef OPENSSL_SYS_WINDOWS
993			/* Under Windows we can't select on stdin: only
994			 * on sockets. As a workaround we timeout the select every
995			 * second and check for any keypress. In a proper Windows
996			 * application we wouldn't do this because it is inefficient.
997			 */
998			tv.tv_sec = 1;
999			tv.tv_usec = 0;
1000			i=select(width,(void *)&readfds,NULL,NULL,&tv);
1001			if((i < 0) || (!i && !_kbhit() ) )continue;
1002			if(_kbhit())
1003				read_from_terminal = 1;
1004#else
1005			i=select(width,(void *)&readfds,NULL,NULL,NULL);
1006			if (i <= 0) continue;
1007			if (FD_ISSET(fileno(stdin),&readfds))
1008				read_from_terminal = 1;
1009#endif
1010			if (FD_ISSET(s,&readfds))
1011				read_from_sslcon = 1;
1012			}
1013		if (read_from_terminal)
1014			{
1015			if (s_crlf)
1016				{
1017				int j, lf_num;
1018
1019				i=read(fileno(stdin), buf, bufsize/2);
1020				lf_num = 0;
1021				/* both loops are skipped when i <= 0 */
1022				for (j = 0; j < i; j++)
1023					if (buf[j] == '\n')
1024						lf_num++;
1025				for (j = i-1; j >= 0; j--)
1026					{
1027					buf[j+lf_num] = buf[j];
1028					if (buf[j] == '\n')
1029						{
1030						lf_num--;
1031						i++;
1032						buf[j+lf_num] = '\r';
1033						}
1034					}
1035				assert(lf_num == 0);
1036				}
1037			else
1038				i=read(fileno(stdin),buf,bufsize);
1039			if (!s_quiet)
1040				{
1041				if ((i <= 0) || (buf[0] == 'Q'))
1042					{
1043					BIO_printf(bio_s_out,"DONE\n");
1044					SHUTDOWN(s);
1045					close_accept_socket();
1046					ret= -11;
1047					goto err;
1048					}
1049				if ((i <= 0) || (buf[0] == 'q'))
1050					{
1051					BIO_printf(bio_s_out,"DONE\n");
1052					SHUTDOWN(s);
1053	/*				close_accept_socket();
1054					ret= -11;*/
1055					goto err;
1056					}
1057				if ((buf[0] == 'r') &&
1058					((buf[1] == '\n') || (buf[1] == '\r')))
1059					{
1060					SSL_renegotiate(con);
1061					i=SSL_do_handshake(con);
1062					printf("SSL_do_handshake -> %d\n",i);
1063					i=0; /*13; */
1064					continue;
1065					/* strcpy(buf,"server side RE-NEGOTIATE\n"); */
1066					}
1067				if ((buf[0] == 'R') &&
1068					((buf[1] == '\n') || (buf[1] == '\r')))
1069					{
1070					SSL_set_verify(con,
1071						SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
1072					SSL_renegotiate(con);
1073					i=SSL_do_handshake(con);
1074					printf("SSL_do_handshake -> %d\n",i);
1075					i=0; /* 13; */
1076					continue;
1077					/* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
1078					}
1079				if (buf[0] == 'P')
1080					{
1081					static char *str="Lets print some clear text\n";
1082					BIO_write(SSL_get_wbio(con),str,strlen(str));
1083					}
1084				if (buf[0] == 'S')
1085					{
1086					print_stats(bio_s_out,SSL_get_SSL_CTX(con));
1087					}
1088				}
1089#ifdef CHARSET_EBCDIC
1090			ebcdic2ascii(buf,buf,i);
1091#endif
1092			l=k=0;
1093			for (;;)
1094				{
1095				/* should do a select for the write */
1096#ifdef RENEG
1097{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
1098#endif
1099				k=SSL_write(con,&(buf[l]),(unsigned int)i);
1100				switch (SSL_get_error(con,k))
1101					{
1102				case SSL_ERROR_NONE:
1103					break;
1104				case SSL_ERROR_WANT_WRITE:
1105				case SSL_ERROR_WANT_READ:
1106				case SSL_ERROR_WANT_X509_LOOKUP:
1107					BIO_printf(bio_s_out,"Write BLOCK\n");
1108					break;
1109				case SSL_ERROR_SYSCALL:
1110				case SSL_ERROR_SSL:
1111					BIO_printf(bio_s_out,"ERROR\n");
1112					ERR_print_errors(bio_err);
1113					ret=1;
1114					goto err;
1115					/* break; */
1116				case SSL_ERROR_ZERO_RETURN:
1117					BIO_printf(bio_s_out,"DONE\n");
1118					ret=1;
1119					goto err;
1120					}
1121				l+=k;
1122				i-=k;
1123				if (i <= 0) break;
1124				}
1125			}
1126		if (read_from_sslcon)
1127			{
1128			if (!SSL_is_init_finished(con))
1129				{
1130				i=init_ssl_connection(con);
1131
1132				if (i < 0)
1133					{
1134					ret=0;
1135					goto err;
1136					}
1137				else if (i == 0)
1138					{
1139					ret=1;
1140					goto err;
1141					}
1142				}
1143			else
1144				{
1145again:
1146				i=SSL_read(con,(char *)buf,bufsize);
1147				switch (SSL_get_error(con,i))
1148					{
1149				case SSL_ERROR_NONE:
1150#ifdef CHARSET_EBCDIC
1151					ascii2ebcdic(buf,buf,i);
1152#endif
1153					write(fileno(stdout),buf,
1154						(unsigned int)i);
1155					if (SSL_pending(con)) goto again;
1156					break;
1157				case SSL_ERROR_WANT_WRITE:
1158				case SSL_ERROR_WANT_READ:
1159				case SSL_ERROR_WANT_X509_LOOKUP:
1160					BIO_printf(bio_s_out,"Read BLOCK\n");
1161					break;
1162				case SSL_ERROR_SYSCALL:
1163				case SSL_ERROR_SSL:
1164					BIO_printf(bio_s_out,"ERROR\n");
1165					ERR_print_errors(bio_err);
1166					ret=1;
1167					goto err;
1168				case SSL_ERROR_ZERO_RETURN:
1169					BIO_printf(bio_s_out,"DONE\n");
1170					ret=1;
1171					goto err;
1172					}
1173				}
1174			}
1175		}
1176err:
1177	BIO_printf(bio_s_out,"shutting down SSL\n");
1178#if 1
1179	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1180#else
1181	SSL_shutdown(con);
1182#endif
1183	if (con != NULL) SSL_free(con);
1184	BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
1185	if (buf != NULL)
1186		{
1187		OPENSSL_cleanse(buf,bufsize);
1188		OPENSSL_free(buf);
1189		}
1190	if (ret >= 0)
1191		BIO_printf(bio_s_out,"ACCEPT\n");
1192	return(ret);
1193	}
1194
1195static void close_accept_socket(void)
1196	{
1197	BIO_printf(bio_err,"shutdown accept socket\n");
1198	if (accept_socket >= 0)
1199		{
1200		SHUTDOWN2(accept_socket);
1201		}
1202	}
1203
1204static int init_ssl_connection(SSL *con)
1205	{
1206	int i;
1207	const char *str;
1208	X509 *peer;
1209	long verify_error;
1210	MS_STATIC char buf[BUFSIZ];
1211
1212	if ((i=SSL_accept(con)) <= 0)
1213		{
1214		if (BIO_sock_should_retry(i))
1215			{
1216			BIO_printf(bio_s_out,"DELAY\n");
1217			return(1);
1218			}
1219
1220		BIO_printf(bio_err,"ERROR\n");
1221		verify_error=SSL_get_verify_result(con);
1222		if (verify_error != X509_V_OK)
1223			{
1224			BIO_printf(bio_err,"verify error:%s\n",
1225				X509_verify_cert_error_string(verify_error));
1226			}
1227		else
1228			ERR_print_errors(bio_err);
1229		return(0);
1230		}
1231
1232	PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
1233
1234	peer=SSL_get_peer_certificate(con);
1235	if (peer != NULL)
1236		{
1237		BIO_printf(bio_s_out,"Client certificate\n");
1238		PEM_write_bio_X509(bio_s_out,peer);
1239		X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
1240		BIO_printf(bio_s_out,"subject=%s\n",buf);
1241		X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
1242		BIO_printf(bio_s_out,"issuer=%s\n",buf);
1243		X509_free(peer);
1244		}
1245
1246	if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
1247		BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
1248	str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1249	BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
1250	if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
1251	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
1252		TLS1_FLAGS_TLS_PADDING_BUG)
1253		BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
1254
1255	return(1);
1256	}
1257
1258#ifndef OPENSSL_NO_DH
1259static DH *load_dh_param(char *dhfile)
1260	{
1261	DH *ret=NULL;
1262	BIO *bio;
1263
1264	if ((bio=BIO_new_file(dhfile,"r")) == NULL)
1265		goto err;
1266	ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
1267err:
1268	if (bio != NULL) BIO_free(bio);
1269	return(ret);
1270	}
1271#endif
1272
1273#if 0
1274static int load_CA(SSL_CTX *ctx, char *file)
1275	{
1276	FILE *in;
1277	X509 *x=NULL;
1278
1279	if ((in=fopen(file,"r")) == NULL)
1280		return(0);
1281
1282	for (;;)
1283		{
1284		if (PEM_read_X509(in,&x,NULL) == NULL)
1285			break;
1286		SSL_CTX_add_client_CA(ctx,x);
1287		}
1288	if (x != NULL) X509_free(x);
1289	fclose(in);
1290	return(1);
1291	}
1292#endif
1293
1294static int www_body(char *hostname, int s, unsigned char *context)
1295	{
1296	char *buf=NULL;
1297	int ret=1;
1298	int i,j,k,blank,dot;
1299	struct stat st_buf;
1300	SSL *con;
1301	SSL_CIPHER *c;
1302	BIO *io,*ssl_bio,*sbio;
1303	long total_bytes;
1304
1305	buf=OPENSSL_malloc(bufsize);
1306	if (buf == NULL) return(0);
1307	io=BIO_new(BIO_f_buffer());
1308	ssl_bio=BIO_new(BIO_f_ssl());
1309	if ((io == NULL) || (ssl_bio == NULL)) goto err;
1310
1311#ifdef FIONBIO
1312	if (s_nbio)
1313		{
1314		unsigned long sl=1;
1315
1316		if (!s_quiet)
1317			BIO_printf(bio_err,"turning on non blocking io\n");
1318		if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
1319			ERR_print_errors(bio_err);
1320		}
1321#endif
1322
1323	/* lets make the output buffer a reasonable size */
1324	if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
1325
1326	if ((con=SSL_new(ctx)) == NULL) goto err;
1327#ifndef OPENSSL_NO_KRB5
1328	if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
1329		{
1330		kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
1331		kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
1332		}
1333#endif	/* OPENSSL_NO_KRB5 */
1334	if(context) SSL_set_session_id_context(con, context,
1335					       strlen((char *)context));
1336
1337	sbio=BIO_new_socket(s,BIO_NOCLOSE);
1338	if (s_nbio_test)
1339		{
1340		BIO *test;
1341
1342		test=BIO_new(BIO_f_nbio_test());
1343		sbio=BIO_push(test,sbio);
1344		}
1345	SSL_set_bio(con,sbio,sbio);
1346	SSL_set_accept_state(con);
1347
1348	/* SSL_set_fd(con,s); */
1349	BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
1350	BIO_push(io,ssl_bio);
1351#ifdef CHARSET_EBCDIC
1352	io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
1353#endif
1354
1355	if (s_debug)
1356		{
1357		con->debug=1;
1358		BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
1359		BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
1360		}
1361	if (s_msg)
1362		{
1363		SSL_set_msg_callback(con, msg_cb);
1364		SSL_set_msg_callback_arg(con, bio_s_out);
1365		}
1366
1367	blank=0;
1368	for (;;)
1369		{
1370		if (hack)
1371			{
1372			i=SSL_accept(con);
1373
1374			switch (SSL_get_error(con,i))
1375				{
1376			case SSL_ERROR_NONE:
1377				break;
1378			case SSL_ERROR_WANT_WRITE:
1379			case SSL_ERROR_WANT_READ:
1380			case SSL_ERROR_WANT_X509_LOOKUP:
1381				continue;
1382			case SSL_ERROR_SYSCALL:
1383			case SSL_ERROR_SSL:
1384			case SSL_ERROR_ZERO_RETURN:
1385				ret=1;
1386				goto err;
1387				/* break; */
1388				}
1389
1390			SSL_renegotiate(con);
1391			SSL_write(con,NULL,0);
1392			}
1393
1394		i=BIO_gets(io,buf,bufsize-1);
1395		if (i < 0) /* error */
1396			{
1397			if (!BIO_should_retry(io))
1398				{
1399				if (!s_quiet)
1400					ERR_print_errors(bio_err);
1401				goto err;
1402				}
1403			else
1404				{
1405				BIO_printf(bio_s_out,"read R BLOCK\n");
1406#if !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
1407				sleep(1);
1408#endif
1409				continue;
1410				}
1411			}
1412		else if (i == 0) /* end of input */
1413			{
1414			ret=1;
1415			goto end;
1416			}
1417
1418		/* else we have data */
1419		if (	((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
1420			((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
1421			{
1422			char *p;
1423			X509 *peer;
1424			STACK_OF(SSL_CIPHER) *sk;
1425			static char *space="                          ";
1426
1427			BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1428			BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
1429			BIO_puts(io,"<pre>\n");
1430/*			BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
1431			BIO_puts(io,"\n");
1432			for (i=0; i<local_argc; i++)
1433				{
1434				BIO_puts(io,local_argv[i]);
1435				BIO_write(io," ",1);
1436				}
1437			BIO_puts(io,"\n");
1438
1439			/* The following is evil and should not really
1440			 * be done */
1441			BIO_printf(io,"Ciphers supported in s_server binary\n");
1442			sk=SSL_get_ciphers(con);
1443			j=sk_SSL_CIPHER_num(sk);
1444			for (i=0; i<j; i++)
1445				{
1446				c=sk_SSL_CIPHER_value(sk,i);
1447				BIO_printf(io,"%-11s:%-25s",
1448					SSL_CIPHER_get_version(c),
1449					SSL_CIPHER_get_name(c));
1450				if ((((i+1)%2) == 0) && (i+1 != j))
1451					BIO_puts(io,"\n");
1452				}
1453			BIO_puts(io,"\n");
1454			p=SSL_get_shared_ciphers(con,buf,bufsize);
1455			if (p != NULL)
1456				{
1457				BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
1458				j=i=0;
1459				while (*p)
1460					{
1461					if (*p == ':')
1462						{
1463						BIO_write(io,space,26-j);
1464						i++;
1465						j=0;
1466						BIO_write(io,((i%3)?" ":"\n"),1);
1467						}
1468					else
1469						{
1470						BIO_write(io,p,1);
1471						j++;
1472						}
1473					p++;
1474					}
1475				BIO_puts(io,"\n");
1476				}
1477			BIO_printf(io,((con->hit)
1478				?"---\nReused, "
1479				:"---\nNew, "));
1480			c=SSL_get_current_cipher(con);
1481			BIO_printf(io,"%s, Cipher is %s\n",
1482				SSL_CIPHER_get_version(c),
1483				SSL_CIPHER_get_name(c));
1484			SSL_SESSION_print(io,SSL_get_session(con));
1485			BIO_printf(io,"---\n");
1486			print_stats(io,SSL_get_SSL_CTX(con));
1487			BIO_printf(io,"---\n");
1488			peer=SSL_get_peer_certificate(con);
1489			if (peer != NULL)
1490				{
1491				BIO_printf(io,"Client certificate\n");
1492				X509_print(io,peer);
1493				PEM_write_bio_X509(io,peer);
1494				}
1495			else
1496				BIO_puts(io,"no client certificate available\n");
1497			BIO_puts(io,"</BODY></HTML>\r\n\r\n");
1498			break;
1499			}
1500		else if ((www == 2 || www == 3)
1501                         && (strncmp("GET /",buf,5) == 0))
1502			{
1503			BIO *file;
1504			char *p,*e;
1505			static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
1506
1507			/* skip the '/' */
1508			p= &(buf[5]);
1509
1510			dot = 1;
1511			for (e=p; *e != '\0'; e++)
1512				{
1513				if (e[0] == ' ')
1514					break;
1515
1516				switch (dot)
1517					{
1518				case 1:
1519					dot = (e[0] == '.') ? 2 : 0;
1520					break;
1521				case 2:
1522					dot = (e[0] == '.') ? 3 : 0;
1523					break;
1524				case 3:
1525					dot = (e[0] == '/') ? -1 : 0;
1526					break;
1527					}
1528				if (dot == 0)
1529					dot = (e[0] == '/') ? 1 : 0;
1530				}
1531			dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
1532
1533			if (*e == '\0')
1534				{
1535				BIO_puts(io,text);
1536				BIO_printf(io,"'%s' is an invalid file name\r\n",p);
1537				break;
1538				}
1539			*e='\0';
1540
1541			if (dot)
1542				{
1543				BIO_puts(io,text);
1544				BIO_printf(io,"'%s' contains '..' reference\r\n",p);
1545				break;
1546				}
1547
1548			if (*p == '/')
1549				{
1550				BIO_puts(io,text);
1551				BIO_printf(io,"'%s' is an invalid path\r\n",p);
1552				break;
1553				}
1554
1555#if 0
1556			/* append if a directory lookup */
1557			if (e[-1] == '/')
1558				strcat(p,"index.html");
1559#endif
1560
1561			/* if a directory, do the index thang */
1562			if (stat(p,&st_buf) < 0)
1563				{
1564				BIO_puts(io,text);
1565				BIO_printf(io,"Error accessing '%s'\r\n",p);
1566				ERR_print_errors(io);
1567				break;
1568				}
1569			if (S_ISDIR(st_buf.st_mode))
1570				{
1571#if 0 /* must check buffer size */
1572				strcat(p,"/index.html");
1573#else
1574				BIO_puts(io,text);
1575				BIO_printf(io,"'%s' is a directory\r\n",p);
1576				break;
1577#endif
1578				}
1579
1580			if ((file=BIO_new_file(p,"r")) == NULL)
1581				{
1582				BIO_puts(io,text);
1583				BIO_printf(io,"Error opening '%s'\r\n",p);
1584				ERR_print_errors(io);
1585				break;
1586				}
1587
1588			if (!s_quiet)
1589				BIO_printf(bio_err,"FILE:%s\n",p);
1590
1591                        if (www == 2)
1592                                {
1593                                i=strlen(p);
1594                                if (	((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
1595                                        ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
1596                                        ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
1597                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1598                                else
1599                                        BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
1600                                }
1601			/* send the file */
1602			total_bytes=0;
1603			for (;;)
1604				{
1605				i=BIO_read(file,buf,bufsize);
1606				if (i <= 0) break;
1607
1608#ifdef RENEG
1609				total_bytes+=i;
1610				fprintf(stderr,"%d\n",i);
1611				if (total_bytes > 3*1024)
1612					{
1613					total_bytes=0;
1614					fprintf(stderr,"RENEGOTIATE\n");
1615					SSL_renegotiate(con);
1616					}
1617#endif
1618
1619				for (j=0; j<i; )
1620					{
1621#ifdef RENEG
1622{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
1623#endif
1624					k=BIO_write(io,&(buf[j]),i-j);
1625					if (k <= 0)
1626						{
1627						if (!BIO_should_retry(io))
1628							goto write_error;
1629						else
1630							{
1631							BIO_printf(bio_s_out,"rwrite W BLOCK\n");
1632							}
1633						}
1634					else
1635						{
1636						j+=k;
1637						}
1638					}
1639				}
1640write_error:
1641			BIO_free(file);
1642			break;
1643			}
1644		}
1645
1646	for (;;)
1647		{
1648		i=(int)BIO_flush(io);
1649		if (i <= 0)
1650			{
1651			if (!BIO_should_retry(io))
1652				break;
1653			}
1654		else
1655			break;
1656		}
1657end:
1658#if 1
1659	/* make sure we re-use sessions */
1660	SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1661#else
1662	/* This kills performance */
1663/*	SSL_shutdown(con); A shutdown gets sent in the
1664 *	BIO_free_all(io) procession */
1665#endif
1666
1667err:
1668
1669	if (ret >= 0)
1670		BIO_printf(bio_s_out,"ACCEPT\n");
1671
1672	if (buf != NULL) OPENSSL_free(buf);
1673	if (io != NULL) BIO_free_all(io);
1674/*	if (ssl_bio != NULL) BIO_free(ssl_bio);*/
1675	return(ret);
1676	}
1677
1678#ifndef OPENSSL_NO_RSA
1679static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
1680	{
1681	static RSA *rsa_tmp=NULL;
1682
1683	if (rsa_tmp == NULL)
1684		{
1685		if (!s_quiet)
1686			{
1687			BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
1688			(void)BIO_flush(bio_err);
1689			}
1690		rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL);
1691		if (!s_quiet)
1692			{
1693			BIO_printf(bio_err,"\n");
1694			(void)BIO_flush(bio_err);
1695			}
1696		}
1697	return(rsa_tmp);
1698	}
1699#endif
1700
1701#define MAX_SESSION_ID_ATTEMPTS 10
1702static int generate_session_id(const SSL *ssl, unsigned char *id,
1703				unsigned int *id_len)
1704	{
1705	unsigned int count = 0;
1706	do	{
1707		RAND_pseudo_bytes(id, *id_len);
1708		/* Prefix the session_id with the required prefix. NB: If our
1709		 * prefix is too long, clip it - but there will be worse effects
1710		 * anyway, eg. the server could only possibly create 1 session
1711		 * ID (ie. the prefix!) so all future session negotiations will
1712		 * fail due to conflicts. */
1713		memcpy(id, session_id_prefix,
1714			(strlen(session_id_prefix) < *id_len) ?
1715			strlen(session_id_prefix) : *id_len);
1716		}
1717	while(SSL_has_matching_session_id(ssl, id, *id_len) &&
1718		(++count < MAX_SESSION_ID_ATTEMPTS));
1719	if(count >= MAX_SESSION_ID_ATTEMPTS)
1720		return 0;
1721	return 1;
1722	}
1723