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