Import of old SSLeay release: SSLeay 0.9.0b
[openssl.git] / apps / s_server.c
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 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <sys/types.h>
63 #include <sys/stat.h>
64 #ifdef NO_STDIO
65 #define APPS_WIN16
66 #endif
67 #include "lhash.h"
68 #include "bn.h"
69 #define USE_SOCKETS
70 #include "apps.h"
71 #include "err.h"
72 #include "pem.h"
73 #include "x509.h"
74 #include "ssl.h"
75 #include "s_apps.h"
76
77 #ifndef NOPROTO
78 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int export);
79 static int sv_body(char *hostname, int s);
80 static int www_body(char *hostname, int s);
81 static void close_accept_socket(void );
82 static void sv_usage(void);
83 static int init_ssl_connection(SSL *s);
84 static void print_stats(BIO *bp,SSL_CTX *ctx);
85 #ifndef NO_DH
86 static DH *load_dh_param(void );
87 static DH *get_dh512(void);
88 #endif
89 /* static void s_server_init(void);*/
90 #else
91 static RSA MS_CALLBACK *tmp_rsa_cb();
92 static int sv_body();
93 static int www_body();
94 static void close_accept_socket();
95 static void sv_usage();
96 static int init_ssl_connection();
97 static void print_stats();
98 #ifndef NO_DH
99 static DH *load_dh_param();
100 static DH *get_dh512();
101 #endif
102 /* static void s_server_init(); */
103 #endif
104
105
106 #ifndef S_ISDIR
107 #define S_ISDIR(a)      (((a) & _S_IFMT) == _S_IFDIR)
108 #endif
109
110 #ifndef NO_DH
111 static unsigned char dh512_p[]={
112         0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
113         0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
114         0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
115         0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
116         0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
117         0x47,0x74,0xE8,0x33,
118         };
119 static unsigned char dh512_g[]={
120         0x02,
121         };
122
123 static DH *get_dh512()
124         {
125         DH *dh=NULL;
126
127         if ((dh=DH_new()) == NULL) return(NULL);
128         dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
129         dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
130         if ((dh->p == NULL) || (dh->g == NULL))
131                 return(NULL);
132         return(dh);
133         }
134 #endif
135
136 /* static int load_CA(SSL_CTX *ctx, char *file);*/
137
138 #undef BUFSIZZ
139 #define BUFSIZZ 8*1024
140 static int accept_socket= -1;
141
142 #define TEST_CERT       "server.pem"
143 #undef PROG
144 #define PROG            s_server_main
145
146 #define DH_PARAM        "server.pem"
147
148 extern int verify_depth;
149
150 static char *cipher=NULL;
151 static int s_server_verify=SSL_VERIFY_NONE;
152 static char *s_cert_file=TEST_CERT,*s_key_file=NULL;
153 static char *s_dcert_file=NULL,*s_dkey_file=NULL;
154 #ifdef FIONBIO
155 static int s_nbio=0;
156 #endif
157 static int s_nbio_test=0;
158 static SSL_CTX *ctx=NULL;
159 static int www=0;
160
161 static BIO *bio_s_out=NULL;
162 static int s_debug=0;
163 static int s_quiet=0;
164
165 #if 0
166 static void s_server_init()
167         {
168         cipher=NULL;
169         s_server_verify=SSL_VERIFY_NONE;
170         s_dcert_file=NULL;
171         s_dkey_file=NULL;
172         s_cert_file=TEST_CERT;
173         s_key_file=NULL;
174 #ifdef FIONBIO
175         s_nbio=0;
176 #endif
177         s_nbio_test=0;
178         ctx=NULL;
179         www=0;
180
181         bio_s_out=NULL;
182         s_debug=0;
183         s_quiet=0;
184         }
185 #endif
186
187 static void sv_usage()
188         {
189         BIO_printf(bio_err,"usage: s_server [args ...]\n");
190         BIO_printf(bio_err,"\n");
191         BIO_printf(bio_err," -accept arg   - port to accept on (default is %d\n",PORT);
192         BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
193         BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
194         BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
195         BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
196         BIO_printf(bio_err," -key arg      - RSA file to use, PEM format assumed, in cert file if\n");
197         BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
198 #ifdef FIONBIO
199         BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
200 #endif
201         BIO_printf(bio_err," -nbio_test    - test with the non-blocking test bio\n");
202         BIO_printf(bio_err," -debug        - Print more output\n");
203         BIO_printf(bio_err," -state        - Print the SSL states\n");
204         BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
205         BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
206         BIO_printf(bio_err," -nocert       - Don't use any certificates (Anon-DH)\n");
207         BIO_printf(bio_err," -cipher arg   - play with 'ssleay ciphers' to see what goes here\n");
208         BIO_printf(bio_err," -quiet        - No server output\n");
209         BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
210         BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
211         BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
212         BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
213         BIO_printf(bio_err," -no_ssl2      - Just disable SSLv2\n");
214         BIO_printf(bio_err," -no_ssl3      - Just disable SSLv3\n");
215         BIO_printf(bio_err," -no_tls1      - Just disable TLSv1\n");
216         BIO_printf(bio_err," -bugs         - Turn on SSL bug compatability\n");
217         BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
218         BIO_printf(bio_err," -WWW          - Returns requested page from to a 'GET <path> HTTP/1.0'\n");
219         }
220
221 static int local_argc=0;
222 static char **local_argv;
223 static int hack=0;
224
225 int MAIN(argc, argv)
226 int argc;
227 char *argv[];
228         {
229         short port=PORT;
230         char *CApath=NULL,*CAfile=NULL;
231         int badop=0,bugs=0;
232         int ret=1;
233         int off=0;
234         int no_tmp_rsa=0,nocert=0;
235         int state=0;
236         SSL_METHOD *meth=NULL;
237 #ifndef NO_DH
238         DH *dh=NULL;
239 #endif
240
241 #if !defined(NO_SSL2) && !defined(NO_SSL3)
242         meth=SSLv23_server_method();
243 #elif !defined(NO_SSL3)
244         meth=SSLv3_server_method();
245 #elif !defined(NO_SSL2)
246         meth=SSLv2_server_method();
247 #endif
248
249         local_argc=argc;
250         local_argv=argv;
251
252         apps_startup();
253         s_quiet=0;
254         s_debug=0;
255
256         if (bio_err == NULL)
257                 bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
258
259         verify_depth=0;
260 #ifdef FIONBIO
261         s_nbio=0;
262 #endif
263         s_nbio_test=0;
264
265         argc--;
266         argv++;
267
268         while (argc >= 1)
269                 {
270                 if      ((strcmp(*argv,"-port") == 0) ||
271                          (strcmp(*argv,"-accept") == 0))
272                         {
273                         if (--argc < 1) goto bad;
274                         if (!extract_port(*(++argv),&port))
275                                 goto bad;
276                         }
277                 else if (strcmp(*argv,"-verify") == 0)
278                         {
279                         s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
280                         if (--argc < 1) goto bad;
281                         verify_depth=atoi(*(++argv));
282                         BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
283                         }
284                 else if (strcmp(*argv,"-Verify") == 0)
285                         {
286                         s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
287                                 SSL_VERIFY_CLIENT_ONCE;
288                         if (--argc < 1) goto bad;
289                         verify_depth=atoi(*(++argv));
290                         BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
291                         }
292                 else if (strcmp(*argv,"-cert") == 0)
293                         {
294                         if (--argc < 1) goto bad;
295                         s_cert_file= *(++argv);
296                         }
297                 else if (strcmp(*argv,"-key") == 0)
298                         {
299                         if (--argc < 1) goto bad;
300                         s_key_file= *(++argv);
301                         }
302                 else if (strcmp(*argv,"-dcert") == 0)
303                         {
304                         if (--argc < 1) goto bad;
305                         s_dcert_file= *(++argv);
306                         }
307                 else if (strcmp(*argv,"-dkey") == 0)
308                         {
309                         if (--argc < 1) goto bad;
310                         s_dkey_file= *(++argv);
311                         }
312                 else if (strcmp(*argv,"-nocert") == 0)
313                         {
314                         nocert=1;
315                         }
316                 else if (strcmp(*argv,"-CApath") == 0)
317                         {
318                         if (--argc < 1) goto bad;
319                         CApath= *(++argv);
320                         }
321                 else if (strcmp(*argv,"-cipher") == 0)
322                         {
323                         if (--argc < 1) goto bad;
324                         cipher= *(++argv);
325                         }
326                 else if (strcmp(*argv,"-CAfile") == 0)
327                         {
328                         if (--argc < 1) goto bad;
329                         CAfile= *(++argv);
330                         }
331 #ifdef FIONBIO  
332                 else if (strcmp(*argv,"-nbio") == 0)
333                         { s_nbio=1; }
334 #endif
335                 else if (strcmp(*argv,"-nbio_test") == 0)
336                         {
337 #ifdef FIONBIO  
338                         s_nbio=1;
339 #endif
340                         s_nbio_test=1;
341                         }
342                 else if (strcmp(*argv,"-debug") == 0)
343                         { s_debug=1; }
344                 else if (strcmp(*argv,"-hack") == 0)
345                         { hack=1; }
346                 else if (strcmp(*argv,"-state") == 0)
347                         { state=1; }
348                 else if (strcmp(*argv,"-quiet") == 0)
349                         { s_quiet=1; }
350                 else if (strcmp(*argv,"-bugs") == 0)
351                         { bugs=1; }
352                 else if (strcmp(*argv,"-no_tmp_rsa") == 0)
353                         { no_tmp_rsa=1; }
354                 else if (strcmp(*argv,"-www") == 0)
355                         { www=1; }
356                 else if (strcmp(*argv,"-WWW") == 0)
357                         { www=2; }
358                 else if (strcmp(*argv,"-no_ssl2") == 0)
359                         { off|=SSL_OP_NO_SSLv2; }
360                 else if (strcmp(*argv,"-no_ssl3") == 0)
361                         { off|=SSL_OP_NO_SSLv3; }
362                 else if (strcmp(*argv,"-no_tls1") == 0)
363                         { off|=SSL_OP_NO_TLSv1; }
364 #ifndef NO_SSL2
365                 else if (strcmp(*argv,"-ssl2") == 0)
366                         { meth=SSLv2_server_method(); }
367 #endif
368 #ifndef NO_SSL3
369                 else if (strcmp(*argv,"-ssl3") == 0)
370                         { meth=SSLv3_server_method(); }
371 #endif
372 #ifndef NO_TLS1
373                 else if (strcmp(*argv,"-tls1") == 0)
374                         { meth=TLSv1_server_method(); }
375 #endif
376                 else
377                         {
378                         BIO_printf(bio_err,"unknown option %s\n",*argv);
379                         badop=1;
380                         break;
381                         }
382                 argc--;
383                 argv++;
384                 }
385         if (badop)
386                 {
387 bad:
388                 sv_usage();
389                 goto end;
390                 }
391
392         if (bio_s_out == NULL)
393                 {
394                 if (s_quiet && !s_debug)
395                         {
396                         bio_s_out=BIO_new(BIO_s_null());
397                         }
398                 else
399                         {
400                         if (bio_s_out == NULL)
401                                 bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
402                         }
403                 }
404
405 #if !defined(NO_RSA) || !defined(NO_DSA)
406         if (nocert)
407 #endif
408                 {
409                 s_cert_file=NULL;
410                 s_key_file=NULL;
411                 s_dcert_file=NULL;
412                 s_dkey_file=NULL;
413                 }
414
415         SSL_load_error_strings();
416         SSLeay_add_ssl_algorithms();
417
418         ctx=SSL_CTX_new(meth);
419         if (ctx == NULL)
420                 {
421                 ERR_print_errors(bio_err);
422                 goto end;
423                 }
424
425         SSL_CTX_set_quiet_shutdown(ctx,1);
426         if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
427         if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
428         SSL_CTX_set_options(ctx,off);
429         if (hack) SSL_CTX_set_options(ctx,SSL_OP_NON_EXPORT_FIRST);
430
431         if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
432
433         SSL_CTX_sess_set_cache_size(ctx,128);
434
435 #if 0
436         if (cipher == NULL) cipher=getenv("SSL_CIPHER");
437 #endif
438
439 #if 0
440         if (s_cert_file == NULL)
441                 {
442                 BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
443                 goto end;
444                 }
445 #endif
446
447         if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
448                 (!SSL_CTX_set_default_verify_paths(ctx)))
449                 {
450                 /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
451                 ERR_print_errors(bio_err);
452                 /* goto end; */
453                 }
454
455 #ifndef NO_DH
456         /* EAY EAY EAY evil hack */
457         dh=load_dh_param();
458         if (dh != NULL)
459                 {
460                 BIO_printf(bio_s_out,"Setting temp DH parameters\n");
461                 }
462         else
463                 {
464                 BIO_printf(bio_s_out,"Using default temp DH parameters\n");
465                 dh=get_dh512();
466                 }
467         BIO_flush(bio_s_out);
468
469         SSL_CTX_set_tmp_dh(ctx,dh);
470         DH_free(dh);
471 #endif
472         
473         if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
474                 goto end;
475         if (s_dcert_file != NULL)
476                 {
477                 if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file))
478                         goto end;
479                 }
480
481 #if 1
482         SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
483 #else
484         if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
485                 {
486                 RSA *rsa;
487
488                 BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
489                 BIO_flush(bio_s_out);
490
491                 rsa=RSA_generate_key(512,RSA_F4,NULL);
492
493                 if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
494                         {
495                         ERR_print_errors(bio_err);
496                         goto end;
497                         }
498                 RSA_free(rsa);
499                 BIO_printf(bio_s_out,"\n");
500                 }
501 #endif
502
503         if (cipher != NULL)
504                 SSL_CTX_set_cipher_list(ctx,cipher);
505         SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
506
507         SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(s_cert_file));
508
509         BIO_printf(bio_s_out,"ACCEPT\n");
510         if (www)
511                 do_server(port,&accept_socket,www_body);
512         else
513                 do_server(port,&accept_socket,sv_body);
514         print_stats(bio_s_out,ctx);
515         ret=0;
516 end:
517         if (ctx != NULL) SSL_CTX_free(ctx);
518         if (bio_s_out != NULL)
519                 {
520                 BIO_free(bio_s_out);
521                 bio_s_out=NULL;
522                 }
523         EXIT(ret);
524         }
525
526 static void print_stats(bio,ssl_ctx)
527 BIO *bio;
528 SSL_CTX *ssl_ctx;
529         {
530         BIO_printf(bio,"%4ld items in the session cache\n",
531                 SSL_CTX_sess_number(ssl_ctx));
532         BIO_printf(bio,"%4d client connects (SSL_connect())\n",
533                 SSL_CTX_sess_connect(ssl_ctx));
534         BIO_printf(bio,"%4d client renegotiates (SSL_connect())\n",
535                 SSL_CTX_sess_connect_renegotiate(ssl_ctx));
536         BIO_printf(bio,"%4d client connects that finished\n",
537                 SSL_CTX_sess_connect_good(ssl_ctx));
538         BIO_printf(bio,"%4d server accepts (SSL_accept())\n",
539                 SSL_CTX_sess_accept(ssl_ctx));
540         BIO_printf(bio,"%4d server renegotiates (SSL_accept())\n",
541                 SSL_CTX_sess_accept_renegotiate(ssl_ctx));
542         BIO_printf(bio,"%4d server accepts that finished\n",
543                 SSL_CTX_sess_accept_good(ssl_ctx));
544         BIO_printf(bio,"%4d session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
545         BIO_printf(bio,"%4d session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
546         BIO_printf(bio,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
547         BIO_printf(bio,"%4d callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
548         BIO_printf(bio,"%4d cache full overflows (%d allowed)\n",
549                 SSL_CTX_sess_cache_full(ssl_ctx),
550                 SSL_CTX_sess_get_cache_size(ssl_ctx));
551         }
552
553 static int sv_body(hostname, s)
554 char *hostname;
555 int s;
556         {
557         char *buf=NULL;
558         fd_set readfds;
559         int ret=1,width;
560         int k,i;
561         unsigned long l;
562         SSL *con=NULL;
563         BIO *sbio;
564
565         if ((buf=Malloc(BUFSIZZ)) == NULL)
566                 {
567                 BIO_printf(bio_err,"out of memory\n");
568                 goto err;
569                 }
570 #ifdef FIONBIO  
571         if (s_nbio)
572                 {
573                 unsigned long sl=1;
574
575                 if (!s_quiet)
576                         BIO_printf(bio_err,"turning on non blocking io\n");
577                 if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
578                         ERR_print_errors(bio_err);
579                 }
580 #endif
581
582         if (con == NULL)
583                 con=(SSL *)SSL_new(ctx);
584         SSL_clear(con);
585
586         sbio=BIO_new_socket(s,BIO_NOCLOSE);
587         if (s_nbio_test)
588                 {
589                 BIO *test;
590
591                 test=BIO_new(BIO_f_nbio_test());
592                 sbio=BIO_push(test,sbio);
593                 }
594         SSL_set_bio(con,sbio,sbio);
595         SSL_set_accept_state(con);
596         /* SSL_set_fd(con,s); */
597
598         if (s_debug)
599                 {
600                 con->debug=1;
601                 BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
602                 BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
603                 }
604
605         width=s+1;
606         for (;;)
607                 {
608                 FD_ZERO(&readfds);
609 #ifndef WINDOWS
610                 FD_SET(fileno(stdin),&readfds);
611 #endif
612                 FD_SET(s,&readfds);
613                 i=select(width,&readfds,NULL,NULL,NULL);
614                 if (i <= 0) continue;
615                 if (FD_ISSET(fileno(stdin),&readfds))
616                         {
617                         i=read(fileno(stdin),buf,128/*BUFSIZZ*/);
618                         if (!s_quiet)
619                                 {
620                                 if ((i <= 0) || (buf[0] == 'Q'))
621                                         {
622                                         BIO_printf(bio_s_out,"DONE\n");
623                                         SHUTDOWN(s);
624                                         close_accept_socket();
625                                         ret= -11;
626                                         goto err;
627                                         }
628                                 if ((i <= 0) || (buf[0] == 'q'))
629                                         {
630                                         BIO_printf(bio_s_out,"DONE\n");
631                                         SHUTDOWN(s);
632         /*                              close_accept_socket();
633                                         ret= -11;*/
634                                         goto err;
635                                         }
636                                 if ((buf[0] == 'r') && 
637                                         ((buf[1] == '\n') || (buf[1] == '\r')))
638                                         {
639                                         SSL_renegotiate(con);
640                                         i=SSL_do_handshake(con);
641                                         printf("SSL_do_handshake -> %d\n",i);
642                                         i=0; /*13; */
643                                         continue;
644                                         strcpy(buf,"server side RE-NEGOTIATE\n");
645                                         }
646                                 if ((buf[0] == 'R') &&
647                                         ((buf[1] == '\0') || (buf[1] == '\r')))
648                                         {
649                                         SSL_set_verify(con,
650                                                 SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
651                                         SSL_renegotiate(con);
652                                         i=SSL_do_handshake(con);
653                                         printf("SSL_do_handshake -> %d\n",i);
654                                         i=0; /* 13; */
655                                         continue;
656                                         strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n");
657                                         }
658                                 if (buf[0] == 'P')
659                                         {
660                                         static char *str="Lets print some clear text\n";
661                                         BIO_write(SSL_get_wbio(con),str,strlen(str));
662                                         }
663                                 if (buf[0] == 'S')
664                                         {
665                                         print_stats(bio_s_out,SSL_get_SSL_CTX(con));
666                                         }
667                                 }
668                         l=k=0;
669                         for (;;)
670                                 {
671                                 /* should do a select for the write */
672 #ifdef RENEG
673 { static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
674 #endif
675                                 k=SSL_write(con,&(buf[l]),(unsigned int)i);
676                                 switch (SSL_get_error(con,k))
677                                         {
678                                 case SSL_ERROR_NONE:
679                                         break;
680                                 case SSL_ERROR_WANT_WRITE:
681                                 case SSL_ERROR_WANT_READ:
682                                 case SSL_ERROR_WANT_X509_LOOKUP:
683                                         BIO_printf(bio_s_out,"Write BLOCK\n");
684                                         break;
685                                 case SSL_ERROR_SYSCALL:
686                                 case SSL_ERROR_SSL:
687                                         BIO_printf(bio_s_out,"ERROR\n");
688                                         ERR_print_errors(bio_err);
689                                         ret=1;
690                                         goto err;
691                                         break;
692                                 case SSL_ERROR_ZERO_RETURN:
693                                         BIO_printf(bio_s_out,"DONE\n");
694                                         ret=1;
695                                         goto err;
696                                         }
697                                 l+=k;
698                                 i-=k;
699                                 if (i <= 0) break;
700                                 }
701                         }
702                 if (FD_ISSET(s,&readfds))
703                         {
704                         if (!SSL_is_init_finished(con))
705                                 {
706                                 i=init_ssl_connection(con);
707                                 
708                                 if (i < 0)
709                                         {
710                                         ret=0;
711                                         goto err;
712                                         }
713                                 else if (i == 0)
714                                         {
715                                         ret=1;
716                                         goto err;
717                                         }
718                                 }
719                         else
720                                 {
721                                 i=SSL_read(con,(char *)buf,128 /*BUFSIZZ */);
722                                 switch (SSL_get_error(con,i))
723                                         {
724                                 case SSL_ERROR_NONE:
725                                         write(fileno(stdout),buf,
726                                                 (unsigned int)i);
727                                         break;
728                                 case SSL_ERROR_WANT_WRITE:
729                                 case SSL_ERROR_WANT_READ:
730                                 case SSL_ERROR_WANT_X509_LOOKUP:
731                                         BIO_printf(bio_s_out,"Read BLOCK\n");
732                                         break;
733                                 case SSL_ERROR_SYSCALL:
734                                 case SSL_ERROR_SSL:
735                                         BIO_printf(bio_s_out,"ERROR\n");
736                                         ERR_print_errors(bio_err);
737                                         ret=1;
738                                         goto err;
739                                 case SSL_ERROR_ZERO_RETURN:
740                                         BIO_printf(bio_s_out,"DONE\n");
741                                         ret=1;
742                                         goto err;
743                                         }
744                                 }
745                         }
746                 }
747 err:
748         BIO_printf(bio_s_out,"shutting down SSL\n");
749 #if 1
750         SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
751 #else
752         SSL_shutdown(con);
753 #endif
754         if (con != NULL) SSL_free(con);
755         BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
756         if (buf != NULL)
757                 {
758                 memset(buf,0,BUFSIZZ);
759                 Free(buf);
760                 }
761         if (ret >= 0)
762                 BIO_printf(bio_s_out,"ACCEPT\n");
763         return(ret);
764         }
765
766 static void close_accept_socket()
767         {
768         BIO_printf(bio_err,"shutdown accept socket\n");
769         if (accept_socket >= 0)
770                 {
771                 SHUTDOWN2(accept_socket);
772                 }
773         }
774
775 static int init_ssl_connection(con)
776 SSL *con;
777         {
778         int i;
779         char *str;
780         X509 *peer;
781         long verify_error;
782         MS_STATIC char buf[BUFSIZ];
783
784         if ((i=SSL_accept(con)) <= 0)
785                 {
786                 if (BIO_sock_should_retry(i))
787                         {
788                         BIO_printf(bio_s_out,"DELAY\n");
789                         return(1);
790                         }
791
792                 BIO_printf(bio_err,"ERROR\n");
793                 verify_error=SSL_get_verify_result(con);
794                 if (verify_error != X509_V_OK)
795                         {
796                         BIO_printf(bio_err,"verify error:%s\n",
797                                 X509_verify_cert_error_string(verify_error));
798                         }
799                 else
800                         ERR_print_errors(bio_err);
801                 return(0);
802                 }
803
804         PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
805
806         peer=SSL_get_peer_certificate(con);
807         if (peer != NULL)
808                 {
809                 BIO_printf(bio_s_out,"Client certificate\n");
810                 PEM_write_bio_X509(bio_s_out,peer);
811                 X509_NAME_oneline(X509_get_subject_name(peer),buf,BUFSIZ);
812                 BIO_printf(bio_s_out,"subject=%s\n",buf);
813                 X509_NAME_oneline(X509_get_issuer_name(peer),buf,BUFSIZ);
814                 BIO_printf(bio_s_out,"issuer=%s\n",buf);
815                 X509_free(peer);
816                 }
817
818         if (SSL_get_shared_ciphers(con,buf,BUFSIZ) != NULL)
819                 BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
820         str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
821         BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
822         if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
823         return(1);
824         }
825
826 #ifndef NO_DH
827 static DH *load_dh_param()
828         {
829         DH *ret=NULL;
830         BIO *bio;
831
832         if ((bio=BIO_new_file(DH_PARAM,"r")) == NULL)
833                 goto err;
834         ret=PEM_read_bio_DHparams(bio,NULL,NULL);
835 err:
836         if (bio != NULL) BIO_free(bio);
837         return(ret);
838         }
839 #endif
840
841 #if 0
842 static int load_CA(ctx,file)
843 SSL_CTX *ctx;
844 char *file;
845         {
846         FILE *in;
847         X509 *x=NULL;
848
849         if ((in=fopen(file,"r")) == NULL)
850                 return(0);
851
852         for (;;)
853                 {
854                 if (PEM_read_X509(in,&x,NULL) == NULL)
855                         break;
856                 SSL_CTX_add_client_CA(ctx,x);
857                 }
858         if (x != NULL) X509_free(x);
859         fclose(in);
860         return(1);
861         }
862 #endif
863
864 static int www_body(hostname, s)
865 char *hostname;
866 int s;
867         {
868         char buf[1024];
869         int ret=1;
870         int i,j,k,blank,dot;
871         struct stat st_buf;
872         SSL *con;
873         SSL_CIPHER *c;
874         BIO *io,*ssl_bio,*sbio;
875         long total_bytes;
876
877         io=BIO_new(BIO_f_buffer());
878         ssl_bio=BIO_new(BIO_f_ssl());
879         if ((io == NULL) || (ssl_bio == NULL)) goto err;
880
881 #ifdef FIONBIO  
882         if (s_nbio)
883                 {
884                 unsigned long sl=1;
885
886                 if (!s_quiet)
887                         BIO_printf(bio_err,"turning on non blocking io\n");
888                 if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
889                         ERR_print_errors(bio_err);
890                 }
891 #endif
892
893         /* lets make the output buffer a reasonable size */
894         if (!BIO_set_write_buffer_size(io,253 /*16*1024*/)) goto err;
895
896         if ((con=(SSL *)SSL_new(ctx)) == NULL) goto err;
897
898         sbio=BIO_new_socket(s,BIO_NOCLOSE);
899         if (s_nbio_test)
900                 {
901                 BIO *test;
902
903                 test=BIO_new(BIO_f_nbio_test());
904                 sbio=BIO_push(test,sbio);
905                 }
906         SSL_set_bio(con,sbio,sbio);
907         SSL_set_accept_state(con);
908
909         /* SSL_set_fd(con,s); */
910         BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
911         BIO_push(io,ssl_bio);
912
913         if (s_debug)
914                 {
915                 con->debug=1;
916                 BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
917                 BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
918                 }
919
920         blank=0;
921         for (;;)
922                 {
923                 if (hack)
924                         {
925                         i=SSL_accept(con);
926
927                         switch (SSL_get_error(con,i))
928                                 {
929                         case SSL_ERROR_NONE:
930                                 break;
931                         case SSL_ERROR_WANT_WRITE:
932                         case SSL_ERROR_WANT_READ:
933                         case SSL_ERROR_WANT_X509_LOOKUP:
934                                 continue;
935                         case SSL_ERROR_SYSCALL:
936                         case SSL_ERROR_SSL:
937                         case SSL_ERROR_ZERO_RETURN:
938                                 ret=1;
939                                 goto err;
940                                 break;
941                                 }
942
943                         SSL_renegotiate(con);
944                         SSL_write(con,NULL,0);
945                         }
946
947                 i=BIO_gets(io,buf,sizeof(buf)-1);
948                 if (i < 0) /* error */
949                         {
950                         if (!BIO_should_retry(io))
951                                 {
952                                 if (!s_quiet)
953                                         ERR_print_errors(bio_err);
954                                 goto err;
955                                 }
956                         else
957                                 {
958                                 BIO_printf(bio_s_out,"read R BLOCK\n");
959 #ifndef MSDOS
960                                 sleep(1);
961 #endif
962                                 continue;
963                                 }
964                         }
965                 else if (i == 0) /* end of input */
966                         {
967                         ret=1;
968                         goto end;
969                         }
970
971                 /* else we have data */
972                 if (    ((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
973                         ((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
974                         {
975                         char *p;
976                         X509 *peer;
977                         STACK *sk;
978                         static char *space="                          ";
979
980                         BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
981                         BIO_puts(io,"<HTML><BODY BGCOLOR=ffffff>\n");
982                         BIO_puts(io,"<pre>\n");
983 /*                      BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
984                         BIO_puts(io,"\n");
985                         for (i=0; i<local_argc; i++)
986                                 {
987                                 BIO_puts(io,local_argv[i]);
988                                 BIO_write(io," ",1);
989                                 }
990                         BIO_puts(io,"\n");
991
992                         /* The following is evil and should not really
993                          * be done */
994                         BIO_printf(io,"Ciphers supported in s_server binary\n");
995                         sk=SSL_get_ciphers(con);
996                         j=sk_num(sk);
997                         for (i=0; i<j; i++)
998                                 {
999                                 c=(SSL_CIPHER *)sk_value(sk,i);
1000                                 BIO_printf(io,"%-11s:%-25s",
1001                                         SSL_CIPHER_get_version(c),
1002                                         SSL_CIPHER_get_name(c));
1003                                 if ((((i+1)%2) == 0) && (i+1 != j))
1004                                         BIO_puts(io,"\n");
1005                                 }
1006                         BIO_puts(io,"\n");
1007                         p=SSL_get_shared_ciphers(con,buf,sizeof(buf));
1008                         if (p != NULL)
1009                                 {
1010                                 BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
1011                                 j=i=0;
1012                                 while (*p)
1013                                         {
1014                                         if (*p == ':')
1015                                                 {
1016                                                 BIO_write(io,space,26-j);
1017                                                 i++;
1018                                                 j=0;
1019                                                 BIO_write(io,((i%3)?" ":"\n"),1);
1020                                                 }
1021                                         else
1022                                                 {
1023                                                 BIO_write(io,p,1);
1024                                                 j++;
1025                                                 }
1026                                         p++;
1027                                         }
1028                                 BIO_puts(io,"\n");
1029                                 }
1030                         BIO_printf(io,((con->hit)
1031                                 ?"---\nReused, "
1032                                 :"---\nNew, "));
1033                         c=SSL_get_current_cipher(con);
1034                         BIO_printf(io,"%s, Cipher is %s\n",
1035                                 SSL_CIPHER_get_version(c),
1036                                 SSL_CIPHER_get_name(c));
1037                         SSL_SESSION_print(io,SSL_get_session(con));
1038                         BIO_printf(io,"---\n");
1039                         print_stats(io,SSL_get_SSL_CTX(con));
1040                         BIO_printf(io,"---\n");
1041                         peer=SSL_get_peer_certificate(con);
1042                         if (peer != NULL)
1043                                 {
1044                                 BIO_printf(io,"Client certificate\n");
1045                                 X509_print(io,peer);
1046                                 PEM_write_bio_X509(io,peer);
1047                                 }
1048                         else
1049                                 BIO_puts(io,"no client certificate available\n");
1050                         BIO_puts(io,"</BODY></HTML>\r\n\r\n");
1051                         break;
1052                         }
1053                 else if ((www == 2) && (strncmp("GET ",buf,4) == 0))
1054                         {
1055                         BIO *file;
1056                         char *p,*e;
1057                         static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
1058
1059                         /* skip the '/' */
1060                         p= &(buf[5]);
1061                         dot=0;
1062                         for (e=p; *e != '\0'; e++)
1063                                 {
1064                                 if (e[0] == ' ') break;
1065                                 if (    (e[0] == '.') &&
1066                                         (strncmp(&(e[-1]),"/../",4) == 0))
1067                                         dot=1;
1068                                 }
1069                         
1070
1071                         if (*e == '\0')
1072                                 {
1073                                 BIO_puts(io,text);
1074                                 BIO_printf(io,"'%s' is an invalid file name\r\n",p);
1075                                 break;
1076                                 }
1077                         *e='\0';
1078
1079                         if (dot)
1080                                 {
1081                                 BIO_puts(io,text);
1082                                 BIO_printf(io,"'%s' contains '..' reference\r\n",p);
1083                                 break;
1084                                 }
1085
1086                         if (*p == '/')
1087                                 {
1088                                 BIO_puts(io,text);
1089                                 BIO_printf(io,"'%s' is an invalid path\r\n",p);
1090                                 break;
1091                                 }
1092
1093                         /* append if a directory lookup */
1094                         if (e[-1] == '/')
1095                                 strcat(p,"index.html");
1096
1097                         /* if a directory, do the index thang */
1098                         if (stat(p,&st_buf) < 0)
1099                                 {
1100                                 BIO_puts(io,text);
1101                                 BIO_printf(io,"Error accessing '%s'\r\n",p);
1102                                 ERR_print_errors(io);
1103                                 break;
1104                                 }
1105                         if (S_ISDIR(st_buf.st_mode))
1106                                 {
1107                                 strcat(p,"/index.html");
1108                                 }
1109
1110                         if ((file=BIO_new_file(p,"r")) == NULL)
1111                                 {
1112                                 BIO_puts(io,text);
1113                                 BIO_printf(io,"Error opening '%s'\r\n",p);
1114                                 ERR_print_errors(io);
1115                                 break;
1116                                 }
1117
1118                         if (!s_quiet)
1119                                 BIO_printf(bio_err,"FILE:%s\n",p);
1120
1121                         i=strlen(p);
1122                         if (    ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
1123                                 ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
1124                                 ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
1125                                 BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1126                         else
1127                                 BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
1128                         /* send the file */
1129                         total_bytes=0;
1130                         for (;;)
1131                                 {
1132                                 i=BIO_read(file,buf,1024);
1133                                 if (i <= 0) break;
1134
1135                                 total_bytes+=i;
1136                                 fprintf(stderr,"%d\n",i);
1137                                 if (total_bytes > 3*1024)
1138                                         {
1139                                         total_bytes=0;
1140                                         fprintf(stderr,"RENEGOTIATE\n");
1141                                         SSL_renegotiate(con);
1142                                         }
1143
1144                                 for (j=0; j<i; )
1145                                         {
1146 #ifdef RENEG
1147 { static count=0; if (++count == 13) { SSL_renegotiate(con); } }
1148 #endif
1149                                         k=BIO_write(io,&(buf[j]),i-j);
1150                                         if (k <= 0)
1151                                                 {
1152                                                 if (!BIO_should_retry(io))
1153                                                         goto write_error;
1154                                                 else
1155                                                         {
1156                                                         BIO_printf(bio_s_out,"rwrite W BLOCK\n");
1157                                                         }
1158                                                 }
1159                                         else
1160                                                 {
1161                                                 j+=k;
1162                                                 }
1163                                         }
1164                                 }
1165 write_error:
1166                         BIO_free(file);
1167                         break;
1168                         }
1169                 }
1170
1171         for (;;)
1172                 {
1173                 i=(int)BIO_flush(io);
1174                 if (i <= 0)
1175                         {
1176                         if (!BIO_should_retry(io))
1177                                 break;
1178                         }
1179                 else
1180                         break;
1181                 }
1182 end:
1183 #if 1
1184         /* make sure we re-use sessions */
1185         SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1186 #else
1187         /* This kills performace */
1188 /*      SSL_shutdown(con); A shutdown gets sent in the
1189  *      BIO_free_all(io) procession */
1190 #endif
1191
1192 err:
1193
1194         if (ret >= 0)
1195                 BIO_printf(bio_s_out,"ACCEPT\n");
1196
1197         if (io != NULL) BIO_free_all(io);
1198 /*      if (ssl_bio != NULL) BIO_free(ssl_bio);*/
1199         return(ret);
1200         }
1201
1202 static RSA MS_CALLBACK *tmp_rsa_cb(s,export)
1203 SSL *s;
1204 int export;
1205         {
1206         static RSA *rsa_tmp=NULL;
1207
1208         if (rsa_tmp == NULL)
1209                 {
1210                 if (!s_quiet)
1211                         {
1212                         BIO_printf(bio_err,"Generating temp (512 bit) RSA key...");
1213                         BIO_flush(bio_err);
1214                         }
1215 #ifndef NO_RSA
1216                 rsa_tmp=RSA_generate_key(512,RSA_F4,NULL,NULL);
1217 #endif
1218                 if (!s_quiet)
1219                         {
1220                         BIO_printf(bio_err,"\n");
1221                         BIO_flush(bio_err);
1222                         }
1223                 }
1224         return(rsa_tmp);
1225         }