174664626SKris Kennaway /* apps/s_server.c */ 274664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 374664626SKris Kennaway * All rights reserved. 474664626SKris Kennaway * 574664626SKris Kennaway * This package is an SSL implementation written 674664626SKris Kennaway * by Eric Young (eay@cryptsoft.com). 774664626SKris Kennaway * The implementation was written so as to conform with Netscapes SSL. 874664626SKris Kennaway * 974664626SKris Kennaway * This library is free for commercial and non-commercial use as long as 1074664626SKris Kennaway * the following conditions are aheared to. The following conditions 1174664626SKris Kennaway * apply to all code found in this distribution, be it the RC4, RSA, 1274664626SKris Kennaway * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1374664626SKris Kennaway * included with this distribution is covered by the same copyright terms 1474664626SKris Kennaway * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1574664626SKris Kennaway * 1674664626SKris Kennaway * Copyright remains Eric Young's, and as such any Copyright notices in 1774664626SKris Kennaway * the code are not to be removed. 1874664626SKris Kennaway * If this package is used in a product, Eric Young should be given attribution 1974664626SKris Kennaway * as the author of the parts of the library used. 2074664626SKris Kennaway * This can be in the form of a textual message at program startup or 2174664626SKris Kennaway * in documentation (online or textual) provided with the package. 2274664626SKris Kennaway * 2374664626SKris Kennaway * Redistribution and use in source and binary forms, with or without 2474664626SKris Kennaway * modification, are permitted provided that the following conditions 2574664626SKris Kennaway * are met: 2674664626SKris Kennaway * 1. Redistributions of source code must retain the copyright 2774664626SKris Kennaway * notice, this list of conditions and the following disclaimer. 2874664626SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 2974664626SKris Kennaway * notice, this list of conditions and the following disclaimer in the 3074664626SKris Kennaway * documentation and/or other materials provided with the distribution. 3174664626SKris Kennaway * 3. All advertising materials mentioning features or use of this software 3274664626SKris Kennaway * must display the following acknowledgement: 3374664626SKris Kennaway * "This product includes cryptographic software written by 3474664626SKris Kennaway * Eric Young (eay@cryptsoft.com)" 3574664626SKris Kennaway * The word 'cryptographic' can be left out if the rouines from the library 3674664626SKris Kennaway * being used are not cryptographic related :-). 3774664626SKris Kennaway * 4. If you include any Windows specific code (or a derivative thereof) from 3874664626SKris Kennaway * the apps directory (application code) you must include an acknowledgement: 3974664626SKris Kennaway * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4074664626SKris Kennaway * 4174664626SKris Kennaway * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4274664626SKris Kennaway * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4374664626SKris Kennaway * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4474664626SKris Kennaway * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4574664626SKris Kennaway * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4674664626SKris Kennaway * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4774664626SKris Kennaway * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4874664626SKris Kennaway * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4974664626SKris Kennaway * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5074664626SKris Kennaway * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5174664626SKris Kennaway * SUCH DAMAGE. 5274664626SKris Kennaway * 5374664626SKris Kennaway * The licence and distribution terms for any publically available version or 5474664626SKris Kennaway * derivative of this code cannot be changed. i.e. this code cannot simply be 5574664626SKris Kennaway * copied and put under another distribution licence 5674664626SKris Kennaway * [including the GNU Public Licence.] 5774664626SKris Kennaway */ 585c87c606SMark Murray /* ==================================================================== 595c87c606SMark Murray * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 605c87c606SMark Murray * 615c87c606SMark Murray * Redistribution and use in source and binary forms, with or without 625c87c606SMark Murray * modification, are permitted provided that the following conditions 635c87c606SMark Murray * are met: 645c87c606SMark Murray * 655c87c606SMark Murray * 1. Redistributions of source code must retain the above copyright 665c87c606SMark Murray * notice, this list of conditions and the following disclaimer. 675c87c606SMark Murray * 685c87c606SMark Murray * 2. Redistributions in binary form must reproduce the above copyright 695c87c606SMark Murray * notice, this list of conditions and the following disclaimer in 705c87c606SMark Murray * the documentation and/or other materials provided with the 715c87c606SMark Murray * distribution. 725c87c606SMark Murray * 735c87c606SMark Murray * 3. All advertising materials mentioning features or use of this 745c87c606SMark Murray * software must display the following acknowledgment: 755c87c606SMark Murray * "This product includes software developed by the OpenSSL Project 765c87c606SMark Murray * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 775c87c606SMark Murray * 785c87c606SMark Murray * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 795c87c606SMark Murray * endorse or promote products derived from this software without 805c87c606SMark Murray * prior written permission. For written permission, please contact 815c87c606SMark Murray * openssl-core@openssl.org. 825c87c606SMark Murray * 835c87c606SMark Murray * 5. Products derived from this software may not be called "OpenSSL" 845c87c606SMark Murray * nor may "OpenSSL" appear in their names without prior written 855c87c606SMark Murray * permission of the OpenSSL Project. 865c87c606SMark Murray * 875c87c606SMark Murray * 6. Redistributions of any form whatsoever must retain the following 885c87c606SMark Murray * acknowledgment: 895c87c606SMark Murray * "This product includes software developed by the OpenSSL Project 905c87c606SMark Murray * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 915c87c606SMark Murray * 925c87c606SMark Murray * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 935c87c606SMark Murray * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 945c87c606SMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 955c87c606SMark Murray * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 965c87c606SMark Murray * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 975c87c606SMark Murray * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 985c87c606SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 995c87c606SMark Murray * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1005c87c606SMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1015c87c606SMark Murray * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1025c87c606SMark Murray * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1035c87c606SMark Murray * OF THE POSSIBILITY OF SUCH DAMAGE. 1045c87c606SMark Murray * ==================================================================== 1055c87c606SMark Murray * 1065c87c606SMark Murray * This product includes cryptographic software written by Eric Young 1075c87c606SMark Murray * (eay@cryptsoft.com). This product includes software written by Tim 1085c87c606SMark Murray * Hudson (tjh@cryptsoft.com). 1095c87c606SMark Murray * 1105c87c606SMark Murray */ 11174664626SKris Kennaway 11274664626SKris Kennaway #include <assert.h> 11374664626SKris Kennaway #include <stdio.h> 11474664626SKris Kennaway #include <stdlib.h> 11574664626SKris Kennaway #include <string.h> 11674664626SKris Kennaway #include <sys/types.h> 11774664626SKris Kennaway #include <sys/stat.h> 1185c87c606SMark Murray #include <openssl/e_os2.h> 1195c87c606SMark Murray #ifdef OPENSSL_NO_STDIO 12074664626SKris Kennaway #define APPS_WIN16 12174664626SKris Kennaway #endif 12274664626SKris Kennaway 12374664626SKris Kennaway /* With IPv6, it looks like Digital has mixed up the proper order of 12474664626SKris Kennaway recursive header file inclusion, resulting in the compiler complaining 12574664626SKris Kennaway that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which 12674664626SKris Kennaway is needed to have fileno() declared correctly... So let's define u_int */ 1275c87c606SMark Murray #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) 12874664626SKris Kennaway #define __U_INT 12974664626SKris Kennaway typedef unsigned int u_int; 13074664626SKris Kennaway #endif 13174664626SKris Kennaway 13274664626SKris Kennaway #include <openssl/lhash.h> 13374664626SKris Kennaway #include <openssl/bn.h> 13474664626SKris Kennaway #define USE_SOCKETS 13574664626SKris Kennaway #include "apps.h" 13674664626SKris Kennaway #include <openssl/err.h> 13774664626SKris Kennaway #include <openssl/pem.h> 13874664626SKris Kennaway #include <openssl/x509.h> 13974664626SKris Kennaway #include <openssl/ssl.h> 1405740a5e3SKris Kennaway #include <openssl/rand.h> 14174664626SKris Kennaway #include "s_apps.h" 14274664626SKris Kennaway 1435c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS 144f579bf8eSKris Kennaway #include <conio.h> 145f579bf8eSKris Kennaway #endif 146f579bf8eSKris Kennaway 1475c87c606SMark Murray #ifdef OPENSSL_SYS_WINCE 1485c87c606SMark Murray /* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */ 1495c87c606SMark Murray #ifdef fileno 1505c87c606SMark Murray #undef fileno 1515c87c606SMark Murray #endif 1525c87c606SMark Murray #define fileno(a) (int)_fileno(a) 1535c87c606SMark Murray #endif 1545c87c606SMark Murray 1555c87c606SMark Murray #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) 15674664626SKris Kennaway /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ 15774664626SKris Kennaway #undef FIONBIO 15874664626SKris Kennaway #endif 15974664626SKris Kennaway 1605c87c606SMark Murray #ifndef OPENSSL_NO_RSA 16174664626SKris Kennaway static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); 16274664626SKris Kennaway #endif 16374664626SKris Kennaway static int sv_body(char *hostname, int s, unsigned char *context); 16474664626SKris Kennaway static int www_body(char *hostname, int s, unsigned char *context); 16574664626SKris Kennaway static void close_accept_socket(void ); 16674664626SKris Kennaway static void sv_usage(void); 16774664626SKris Kennaway static int init_ssl_connection(SSL *s); 16874664626SKris Kennaway static void print_stats(BIO *bp,SSL_CTX *ctx); 1695c87c606SMark Murray static int generate_session_id(const SSL *ssl, unsigned char *id, 1705c87c606SMark Murray unsigned int *id_len); 1715c87c606SMark Murray #ifndef OPENSSL_NO_DH 172f579bf8eSKris Kennaway static DH *load_dh_param(char *dhfile); 17374664626SKris Kennaway static DH *get_dh512(void); 17474664626SKris Kennaway #endif 175f579bf8eSKris Kennaway #ifdef MONOLITH 176f579bf8eSKris Kennaway static void s_server_init(void); 177f579bf8eSKris Kennaway #endif 17874664626SKris Kennaway 17974664626SKris Kennaway #ifndef S_ISDIR 18074664626SKris Kennaway # if defined(_S_IFMT) && defined(_S_IFDIR) 18174664626SKris Kennaway # define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR) 18274664626SKris Kennaway # else 18374664626SKris Kennaway # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) 18474664626SKris Kennaway # endif 18574664626SKris Kennaway #endif 18674664626SKris Kennaway 1875c87c606SMark Murray #ifndef OPENSSL_NO_DH 18874664626SKris Kennaway static unsigned char dh512_p[]={ 18974664626SKris Kennaway 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, 19074664626SKris Kennaway 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, 19174664626SKris Kennaway 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, 19274664626SKris Kennaway 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, 19374664626SKris Kennaway 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, 19474664626SKris Kennaway 0x47,0x74,0xE8,0x33, 19574664626SKris Kennaway }; 19674664626SKris Kennaway static unsigned char dh512_g[]={ 19774664626SKris Kennaway 0x02, 19874664626SKris Kennaway }; 19974664626SKris Kennaway 20074664626SKris Kennaway static DH *get_dh512(void) 20174664626SKris Kennaway { 20274664626SKris Kennaway DH *dh=NULL; 20374664626SKris Kennaway 20474664626SKris Kennaway if ((dh=DH_new()) == NULL) return(NULL); 20574664626SKris Kennaway dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); 20674664626SKris Kennaway dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); 20774664626SKris Kennaway if ((dh->p == NULL) || (dh->g == NULL)) 20874664626SKris Kennaway return(NULL); 20974664626SKris Kennaway return(dh); 21074664626SKris Kennaway } 21174664626SKris Kennaway #endif 21274664626SKris Kennaway 21374664626SKris Kennaway /* static int load_CA(SSL_CTX *ctx, char *file);*/ 21474664626SKris Kennaway 21574664626SKris Kennaway #undef BUFSIZZ 21674664626SKris Kennaway #define BUFSIZZ 16*1024 217f579bf8eSKris Kennaway static int bufsize=BUFSIZZ; 21874664626SKris Kennaway static int accept_socket= -1; 21974664626SKris Kennaway 22074664626SKris Kennaway #define TEST_CERT "server.pem" 22174664626SKris Kennaway #undef PROG 22274664626SKris Kennaway #define PROG s_server_main 22374664626SKris Kennaway 22474664626SKris Kennaway extern int verify_depth; 22574664626SKris Kennaway 22674664626SKris Kennaway static char *cipher=NULL; 22774664626SKris Kennaway static int s_server_verify=SSL_VERIFY_NONE; 22874664626SKris Kennaway static int s_server_session_id_context = 1; /* anything will do */ 22974664626SKris Kennaway static char *s_cert_file=TEST_CERT,*s_key_file=NULL; 23074664626SKris Kennaway static char *s_dcert_file=NULL,*s_dkey_file=NULL; 23174664626SKris Kennaway #ifdef FIONBIO 23274664626SKris Kennaway static int s_nbio=0; 23374664626SKris Kennaway #endif 23474664626SKris Kennaway static int s_nbio_test=0; 23574664626SKris Kennaway int s_crlf=0; 23674664626SKris Kennaway static SSL_CTX *ctx=NULL; 23774664626SKris Kennaway static int www=0; 23874664626SKris Kennaway 23974664626SKris Kennaway static BIO *bio_s_out=NULL; 24074664626SKris Kennaway static int s_debug=0; 2415c87c606SMark Murray static int s_msg=0; 24274664626SKris Kennaway static int s_quiet=0; 24374664626SKris Kennaway 244f579bf8eSKris Kennaway static int hack=0; 2455c87c606SMark Murray static char *engine_id=NULL; 2465c87c606SMark Murray static const char *session_id_prefix=NULL; 247f579bf8eSKris Kennaway 248f579bf8eSKris Kennaway #ifdef MONOLITH 24974664626SKris Kennaway static void s_server_init(void) 25074664626SKris Kennaway { 251f579bf8eSKris Kennaway accept_socket=-1; 25274664626SKris Kennaway cipher=NULL; 25374664626SKris Kennaway s_server_verify=SSL_VERIFY_NONE; 25474664626SKris Kennaway s_dcert_file=NULL; 25574664626SKris Kennaway s_dkey_file=NULL; 25674664626SKris Kennaway s_cert_file=TEST_CERT; 25774664626SKris Kennaway s_key_file=NULL; 25874664626SKris Kennaway #ifdef FIONBIO 25974664626SKris Kennaway s_nbio=0; 26074664626SKris Kennaway #endif 26174664626SKris Kennaway s_nbio_test=0; 26274664626SKris Kennaway ctx=NULL; 26374664626SKris Kennaway www=0; 26474664626SKris Kennaway 26574664626SKris Kennaway bio_s_out=NULL; 26674664626SKris Kennaway s_debug=0; 2675c87c606SMark Murray s_msg=0; 26874664626SKris Kennaway s_quiet=0; 269f579bf8eSKris Kennaway hack=0; 2705c87c606SMark Murray engine_id=NULL; 27174664626SKris Kennaway } 27274664626SKris Kennaway #endif 27374664626SKris Kennaway 27474664626SKris Kennaway static void sv_usage(void) 27574664626SKris Kennaway { 27674664626SKris Kennaway BIO_printf(bio_err,"usage: s_server [args ...]\n"); 27774664626SKris Kennaway BIO_printf(bio_err,"\n"); 27874664626SKris Kennaway BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT); 27974664626SKris Kennaway BIO_printf(bio_err," -context arg - set session ID context\n"); 28074664626SKris Kennaway BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); 28174664626SKris Kennaway BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); 28274664626SKris Kennaway BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); 28374664626SKris Kennaway BIO_printf(bio_err," (default is %s)\n",TEST_CERT); 284f579bf8eSKris Kennaway BIO_printf(bio_err," -key arg - Private Key file to use, PEM format assumed, in cert file if\n"); 28574664626SKris Kennaway BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT); 28674664626SKris Kennaway BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n"); 28774664626SKris Kennaway BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n"); 288f579bf8eSKris Kennaway BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n"); 289f579bf8eSKris Kennaway BIO_printf(bio_err," or a default set of parameters is used\n"); 29074664626SKris Kennaway #ifdef FIONBIO 29174664626SKris Kennaway BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); 29274664626SKris Kennaway #endif 29374664626SKris Kennaway BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n"); 29474664626SKris Kennaway BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n"); 29574664626SKris Kennaway BIO_printf(bio_err," -debug - Print more output\n"); 2965c87c606SMark Murray BIO_printf(bio_err," -msg - Show protocol messages\n"); 29774664626SKris Kennaway BIO_printf(bio_err," -state - Print the SSL states\n"); 29874664626SKris Kennaway BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n"); 29974664626SKris Kennaway BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n"); 30074664626SKris Kennaway BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n"); 30174664626SKris Kennaway BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n"); 3025c87c606SMark Murray BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n"); 30374664626SKris Kennaway BIO_printf(bio_err," -quiet - No server output\n"); 30474664626SKris Kennaway BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n"); 30574664626SKris Kennaway BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n"); 30674664626SKris Kennaway BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n"); 30774664626SKris Kennaway BIO_printf(bio_err," -tls1 - Just talk TLSv1\n"); 30874664626SKris Kennaway BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n"); 30974664626SKris Kennaway BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n"); 31074664626SKris Kennaway BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n"); 3115c87c606SMark Murray #ifndef OPENSSL_NO_DH 31274664626SKris Kennaway BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n"); 31374664626SKris Kennaway #endif 314f579bf8eSKris Kennaway BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n"); 31574664626SKris Kennaway BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n"); 31674664626SKris Kennaway BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); 3175c87c606SMark Murray BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n"); 3185c87c606SMark Murray BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n"); 3195c87c606SMark Murray BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n"); 3205c87c606SMark Murray BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); 3215740a5e3SKris Kennaway BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 32274664626SKris Kennaway } 32374664626SKris Kennaway 32474664626SKris Kennaway static int local_argc=0; 32574664626SKris Kennaway static char **local_argv; 32674664626SKris Kennaway 32774664626SKris Kennaway #ifdef CHARSET_EBCDIC 32874664626SKris Kennaway static int ebcdic_new(BIO *bi); 32974664626SKris Kennaway static int ebcdic_free(BIO *a); 33074664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl); 3315c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl); 3325c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr); 33374664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size); 3345c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str); 33574664626SKris Kennaway 33674664626SKris Kennaway #define BIO_TYPE_EBCDIC_FILTER (18|0x0200) 33774664626SKris Kennaway static BIO_METHOD methods_ebcdic= 33874664626SKris Kennaway { 33974664626SKris Kennaway BIO_TYPE_EBCDIC_FILTER, 34074664626SKris Kennaway "EBCDIC/ASCII filter", 34174664626SKris Kennaway ebcdic_write, 34274664626SKris Kennaway ebcdic_read, 34374664626SKris Kennaway ebcdic_puts, 34474664626SKris Kennaway ebcdic_gets, 34574664626SKris Kennaway ebcdic_ctrl, 34674664626SKris Kennaway ebcdic_new, 34774664626SKris Kennaway ebcdic_free, 34874664626SKris Kennaway }; 34974664626SKris Kennaway 35074664626SKris Kennaway typedef struct 35174664626SKris Kennaway { 35274664626SKris Kennaway size_t alloced; 35374664626SKris Kennaway char buff[1]; 35474664626SKris Kennaway } EBCDIC_OUTBUFF; 35574664626SKris Kennaway 35674664626SKris Kennaway BIO_METHOD *BIO_f_ebcdic_filter() 35774664626SKris Kennaway { 35874664626SKris Kennaway return(&methods_ebcdic); 35974664626SKris Kennaway } 36074664626SKris Kennaway 36174664626SKris Kennaway static int ebcdic_new(BIO *bi) 36274664626SKris Kennaway { 36374664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 36474664626SKris Kennaway 365ddd58736SKris Kennaway wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024); 36674664626SKris Kennaway wbuf->alloced = 1024; 36774664626SKris Kennaway wbuf->buff[0] = '\0'; 36874664626SKris Kennaway 36974664626SKris Kennaway bi->ptr=(char *)wbuf; 37074664626SKris Kennaway bi->init=1; 37174664626SKris Kennaway bi->flags=0; 37274664626SKris Kennaway return(1); 37374664626SKris Kennaway } 37474664626SKris Kennaway 37574664626SKris Kennaway static int ebcdic_free(BIO *a) 37674664626SKris Kennaway { 37774664626SKris Kennaway if (a == NULL) return(0); 37874664626SKris Kennaway if (a->ptr != NULL) 379ddd58736SKris Kennaway OPENSSL_free(a->ptr); 38074664626SKris Kennaway a->ptr=NULL; 38174664626SKris Kennaway a->init=0; 38274664626SKris Kennaway a->flags=0; 38374664626SKris Kennaway return(1); 38474664626SKris Kennaway } 38574664626SKris Kennaway 38674664626SKris Kennaway static int ebcdic_read(BIO *b, char *out, int outl) 38774664626SKris Kennaway { 38874664626SKris Kennaway int ret=0; 38974664626SKris Kennaway 39074664626SKris Kennaway if (out == NULL || outl == 0) return(0); 39174664626SKris Kennaway if (b->next_bio == NULL) return(0); 39274664626SKris Kennaway 39374664626SKris Kennaway ret=BIO_read(b->next_bio,out,outl); 39474664626SKris Kennaway if (ret > 0) 39574664626SKris Kennaway ascii2ebcdic(out,out,ret); 39674664626SKris Kennaway return(ret); 39774664626SKris Kennaway } 39874664626SKris Kennaway 3995c87c606SMark Murray static int ebcdic_write(BIO *b, const char *in, int inl) 40074664626SKris Kennaway { 40174664626SKris Kennaway EBCDIC_OUTBUFF *wbuf; 40274664626SKris Kennaway int ret=0; 40374664626SKris Kennaway int num; 40474664626SKris Kennaway unsigned char n; 40574664626SKris Kennaway 40674664626SKris Kennaway if ((in == NULL) || (inl <= 0)) return(0); 40774664626SKris Kennaway if (b->next_bio == NULL) return(0); 40874664626SKris Kennaway 40974664626SKris Kennaway wbuf=(EBCDIC_OUTBUFF *)b->ptr; 41074664626SKris Kennaway 41174664626SKris Kennaway if (inl > (num = wbuf->alloced)) 41274664626SKris Kennaway { 41374664626SKris Kennaway num = num + num; /* double the size */ 41474664626SKris Kennaway if (num < inl) 41574664626SKris Kennaway num = inl; 416ddd58736SKris Kennaway OPENSSL_free(wbuf); 417ddd58736SKris Kennaway wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); 41874664626SKris Kennaway 41974664626SKris Kennaway wbuf->alloced = num; 42074664626SKris Kennaway wbuf->buff[0] = '\0'; 42174664626SKris Kennaway 42274664626SKris Kennaway b->ptr=(char *)wbuf; 42374664626SKris Kennaway } 42474664626SKris Kennaway 42574664626SKris Kennaway ebcdic2ascii(wbuf->buff, in, inl); 42674664626SKris Kennaway 42774664626SKris Kennaway ret=BIO_write(b->next_bio, wbuf->buff, inl); 42874664626SKris Kennaway 42974664626SKris Kennaway return(ret); 43074664626SKris Kennaway } 43174664626SKris Kennaway 4325c87c606SMark Murray static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr) 43374664626SKris Kennaway { 43474664626SKris Kennaway long ret; 43574664626SKris Kennaway 43674664626SKris Kennaway if (b->next_bio == NULL) return(0); 43774664626SKris Kennaway switch (cmd) 43874664626SKris Kennaway { 43974664626SKris Kennaway case BIO_CTRL_DUP: 44074664626SKris Kennaway ret=0L; 44174664626SKris Kennaway break; 44274664626SKris Kennaway default: 44374664626SKris Kennaway ret=BIO_ctrl(b->next_bio,cmd,num,ptr); 44474664626SKris Kennaway break; 44574664626SKris Kennaway } 44674664626SKris Kennaway return(ret); 44774664626SKris Kennaway } 44874664626SKris Kennaway 44974664626SKris Kennaway static int ebcdic_gets(BIO *bp, char *buf, int size) 45074664626SKris Kennaway { 4515c87c606SMark Murray int i, ret=0; 45274664626SKris Kennaway if (bp->next_bio == NULL) return(0); 45374664626SKris Kennaway /* return(BIO_gets(bp->next_bio,buf,size));*/ 45474664626SKris Kennaway for (i=0; i<size-1; ++i) 45574664626SKris Kennaway { 45674664626SKris Kennaway ret = ebcdic_read(bp,&buf[i],1); 45774664626SKris Kennaway if (ret <= 0) 45874664626SKris Kennaway break; 45974664626SKris Kennaway else if (buf[i] == '\n') 46074664626SKris Kennaway { 46174664626SKris Kennaway ++i; 46274664626SKris Kennaway break; 46374664626SKris Kennaway } 46474664626SKris Kennaway } 46574664626SKris Kennaway if (i < size) 46674664626SKris Kennaway buf[i] = '\0'; 46774664626SKris Kennaway return (ret < 0 && i == 0) ? ret : i; 46874664626SKris Kennaway } 46974664626SKris Kennaway 4705c87c606SMark Murray static int ebcdic_puts(BIO *bp, const char *str) 47174664626SKris Kennaway { 47274664626SKris Kennaway if (bp->next_bio == NULL) return(0); 47374664626SKris Kennaway return ebcdic_write(bp, str, strlen(str)); 47474664626SKris Kennaway } 47574664626SKris Kennaway #endif 47674664626SKris Kennaway 477f579bf8eSKris Kennaway int MAIN(int, char **); 478f579bf8eSKris Kennaway 47974664626SKris Kennaway int MAIN(int argc, char *argv[]) 48074664626SKris Kennaway { 4815c87c606SMark Murray X509_STORE *store = NULL; 4825c87c606SMark Murray int vflags = 0; 48374664626SKris Kennaway short port=PORT; 48474664626SKris Kennaway char *CApath=NULL,*CAfile=NULL; 48574664626SKris Kennaway char *context = NULL; 486f579bf8eSKris Kennaway char *dhfile = NULL; 48774664626SKris Kennaway int badop=0,bugs=0; 48874664626SKris Kennaway int ret=1; 48974664626SKris Kennaway int off=0; 49074664626SKris Kennaway int no_tmp_rsa=0,no_dhe=0,nocert=0; 49174664626SKris Kennaway int state=0; 49274664626SKris Kennaway SSL_METHOD *meth=NULL; 4935c87c606SMark Murray ENGINE *e=NULL; 4945740a5e3SKris Kennaway char *inrand=NULL; 49574664626SKris Kennaway 4965c87c606SMark Murray #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) 49774664626SKris Kennaway meth=SSLv23_server_method(); 4985c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL3) 49974664626SKris Kennaway meth=SSLv3_server_method(); 5005c87c606SMark Murray #elif !defined(OPENSSL_NO_SSL2) 50174664626SKris Kennaway meth=SSLv2_server_method(); 50274664626SKris Kennaway #endif 50374664626SKris Kennaway 50474664626SKris Kennaway local_argc=argc; 50574664626SKris Kennaway local_argv=argv; 50674664626SKris Kennaway 50774664626SKris Kennaway apps_startup(); 508f579bf8eSKris Kennaway #ifdef MONOLITH 509f579bf8eSKris Kennaway s_server_init(); 510f579bf8eSKris Kennaway #endif 51174664626SKris Kennaway 51274664626SKris Kennaway if (bio_err == NULL) 51374664626SKris Kennaway bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); 51474664626SKris Kennaway 5155c87c606SMark Murray if (!load_config(bio_err, NULL)) 5165c87c606SMark Murray goto end; 5175c87c606SMark Murray 51874664626SKris Kennaway verify_depth=0; 51974664626SKris Kennaway #ifdef FIONBIO 52074664626SKris Kennaway s_nbio=0; 52174664626SKris Kennaway #endif 52274664626SKris Kennaway s_nbio_test=0; 52374664626SKris Kennaway 52474664626SKris Kennaway argc--; 52574664626SKris Kennaway argv++; 52674664626SKris Kennaway 52774664626SKris Kennaway while (argc >= 1) 52874664626SKris Kennaway { 52974664626SKris Kennaway if ((strcmp(*argv,"-port") == 0) || 53074664626SKris Kennaway (strcmp(*argv,"-accept") == 0)) 53174664626SKris Kennaway { 53274664626SKris Kennaway if (--argc < 1) goto bad; 53374664626SKris Kennaway if (!extract_port(*(++argv),&port)) 53474664626SKris Kennaway goto bad; 53574664626SKris Kennaway } 53674664626SKris Kennaway else if (strcmp(*argv,"-verify") == 0) 53774664626SKris Kennaway { 53874664626SKris Kennaway s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE; 53974664626SKris Kennaway if (--argc < 1) goto bad; 54074664626SKris Kennaway verify_depth=atoi(*(++argv)); 54174664626SKris Kennaway BIO_printf(bio_err,"verify depth is %d\n",verify_depth); 54274664626SKris Kennaway } 54374664626SKris Kennaway else if (strcmp(*argv,"-Verify") == 0) 54474664626SKris Kennaway { 54574664626SKris Kennaway s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| 54674664626SKris Kennaway SSL_VERIFY_CLIENT_ONCE; 54774664626SKris Kennaway if (--argc < 1) goto bad; 54874664626SKris Kennaway verify_depth=atoi(*(++argv)); 54974664626SKris Kennaway BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth); 55074664626SKris Kennaway } 55174664626SKris Kennaway else if (strcmp(*argv,"-context") == 0) 55274664626SKris Kennaway { 55374664626SKris Kennaway if (--argc < 1) goto bad; 55474664626SKris Kennaway context= *(++argv); 55574664626SKris Kennaway } 55674664626SKris Kennaway else if (strcmp(*argv,"-cert") == 0) 55774664626SKris Kennaway { 55874664626SKris Kennaway if (--argc < 1) goto bad; 55974664626SKris Kennaway s_cert_file= *(++argv); 56074664626SKris Kennaway } 56174664626SKris Kennaway else if (strcmp(*argv,"-key") == 0) 56274664626SKris Kennaway { 56374664626SKris Kennaway if (--argc < 1) goto bad; 56474664626SKris Kennaway s_key_file= *(++argv); 56574664626SKris Kennaway } 566f579bf8eSKris Kennaway else if (strcmp(*argv,"-dhparam") == 0) 567f579bf8eSKris Kennaway { 568f579bf8eSKris Kennaway if (--argc < 1) goto bad; 569f579bf8eSKris Kennaway dhfile = *(++argv); 570f579bf8eSKris Kennaway } 57174664626SKris Kennaway else if (strcmp(*argv,"-dcert") == 0) 57274664626SKris Kennaway { 57374664626SKris Kennaway if (--argc < 1) goto bad; 57474664626SKris Kennaway s_dcert_file= *(++argv); 57574664626SKris Kennaway } 57674664626SKris Kennaway else if (strcmp(*argv,"-dkey") == 0) 57774664626SKris Kennaway { 57874664626SKris Kennaway if (--argc < 1) goto bad; 57974664626SKris Kennaway s_dkey_file= *(++argv); 58074664626SKris Kennaway } 58174664626SKris Kennaway else if (strcmp(*argv,"-nocert") == 0) 58274664626SKris Kennaway { 58374664626SKris Kennaway nocert=1; 58474664626SKris Kennaway } 58574664626SKris Kennaway else if (strcmp(*argv,"-CApath") == 0) 58674664626SKris Kennaway { 58774664626SKris Kennaway if (--argc < 1) goto bad; 58874664626SKris Kennaway CApath= *(++argv); 58974664626SKris Kennaway } 5905c87c606SMark Murray else if (strcmp(*argv,"-crl_check") == 0) 5915c87c606SMark Murray { 5925c87c606SMark Murray vflags |= X509_V_FLAG_CRL_CHECK; 5935c87c606SMark Murray } 5945c87c606SMark Murray else if (strcmp(*argv,"-crl_check") == 0) 5955c87c606SMark Murray { 5965c87c606SMark Murray vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; 5975c87c606SMark Murray } 5985c87c606SMark Murray else if (strcmp(*argv,"-serverpref") == 0) 5995c87c606SMark Murray { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } 60074664626SKris Kennaway else if (strcmp(*argv,"-cipher") == 0) 60174664626SKris Kennaway { 60274664626SKris Kennaway if (--argc < 1) goto bad; 60374664626SKris Kennaway cipher= *(++argv); 60474664626SKris Kennaway } 60574664626SKris Kennaway else if (strcmp(*argv,"-CAfile") == 0) 60674664626SKris Kennaway { 60774664626SKris Kennaway if (--argc < 1) goto bad; 60874664626SKris Kennaway CAfile= *(++argv); 60974664626SKris Kennaway } 61074664626SKris Kennaway #ifdef FIONBIO 61174664626SKris Kennaway else if (strcmp(*argv,"-nbio") == 0) 61274664626SKris Kennaway { s_nbio=1; } 61374664626SKris Kennaway #endif 61474664626SKris Kennaway else if (strcmp(*argv,"-nbio_test") == 0) 61574664626SKris Kennaway { 61674664626SKris Kennaway #ifdef FIONBIO 61774664626SKris Kennaway s_nbio=1; 61874664626SKris Kennaway #endif 61974664626SKris Kennaway s_nbio_test=1; 62074664626SKris Kennaway } 62174664626SKris Kennaway else if (strcmp(*argv,"-debug") == 0) 62274664626SKris Kennaway { s_debug=1; } 6235c87c606SMark Murray else if (strcmp(*argv,"-msg") == 0) 6245c87c606SMark Murray { s_msg=1; } 62574664626SKris Kennaway else if (strcmp(*argv,"-hack") == 0) 62674664626SKris Kennaway { hack=1; } 62774664626SKris Kennaway else if (strcmp(*argv,"-state") == 0) 62874664626SKris Kennaway { state=1; } 62974664626SKris Kennaway else if (strcmp(*argv,"-crlf") == 0) 63074664626SKris Kennaway { s_crlf=1; } 63174664626SKris Kennaway else if (strcmp(*argv,"-quiet") == 0) 63274664626SKris Kennaway { s_quiet=1; } 63374664626SKris Kennaway else if (strcmp(*argv,"-bugs") == 0) 63474664626SKris Kennaway { bugs=1; } 63574664626SKris Kennaway else if (strcmp(*argv,"-no_tmp_rsa") == 0) 63674664626SKris Kennaway { no_tmp_rsa=1; } 63774664626SKris Kennaway else if (strcmp(*argv,"-no_dhe") == 0) 63874664626SKris Kennaway { no_dhe=1; } 63974664626SKris Kennaway else if (strcmp(*argv,"-www") == 0) 64074664626SKris Kennaway { www=1; } 64174664626SKris Kennaway else if (strcmp(*argv,"-WWW") == 0) 64274664626SKris Kennaway { www=2; } 6435c87c606SMark Murray else if (strcmp(*argv,"-HTTP") == 0) 6445c87c606SMark Murray { www=3; } 64574664626SKris Kennaway else if (strcmp(*argv,"-no_ssl2") == 0) 64674664626SKris Kennaway { off|=SSL_OP_NO_SSLv2; } 64774664626SKris Kennaway else if (strcmp(*argv,"-no_ssl3") == 0) 64874664626SKris Kennaway { off|=SSL_OP_NO_SSLv3; } 64974664626SKris Kennaway else if (strcmp(*argv,"-no_tls1") == 0) 65074664626SKris Kennaway { off|=SSL_OP_NO_TLSv1; } 6515c87c606SMark Murray #ifndef OPENSSL_NO_SSL2 65274664626SKris Kennaway else if (strcmp(*argv,"-ssl2") == 0) 65374664626SKris Kennaway { meth=SSLv2_server_method(); } 65474664626SKris Kennaway #endif 6555c87c606SMark Murray #ifndef OPENSSL_NO_SSL3 65674664626SKris Kennaway else if (strcmp(*argv,"-ssl3") == 0) 65774664626SKris Kennaway { meth=SSLv3_server_method(); } 65874664626SKris Kennaway #endif 6595c87c606SMark Murray #ifndef OPENSSL_NO_TLS1 66074664626SKris Kennaway else if (strcmp(*argv,"-tls1") == 0) 66174664626SKris Kennaway { meth=TLSv1_server_method(); } 66274664626SKris Kennaway #endif 6635c87c606SMark Murray else if (strcmp(*argv, "-id_prefix") == 0) 6645c87c606SMark Murray { 6655c87c606SMark Murray if (--argc < 1) goto bad; 6665c87c606SMark Murray session_id_prefix = *(++argv); 6675c87c606SMark Murray } 6685c87c606SMark Murray else if (strcmp(*argv,"-engine") == 0) 6695c87c606SMark Murray { 6705c87c606SMark Murray if (--argc < 1) goto bad; 6715c87c606SMark Murray engine_id= *(++argv); 6725c87c606SMark Murray } 6735740a5e3SKris Kennaway else if (strcmp(*argv,"-rand") == 0) 6745740a5e3SKris Kennaway { 6755740a5e3SKris Kennaway if (--argc < 1) goto bad; 6765740a5e3SKris Kennaway inrand= *(++argv); 6775740a5e3SKris Kennaway } 67874664626SKris Kennaway else 67974664626SKris Kennaway { 68074664626SKris Kennaway BIO_printf(bio_err,"unknown option %s\n",*argv); 68174664626SKris Kennaway badop=1; 68274664626SKris Kennaway break; 68374664626SKris Kennaway } 68474664626SKris Kennaway argc--; 68574664626SKris Kennaway argv++; 68674664626SKris Kennaway } 68774664626SKris Kennaway if (badop) 68874664626SKris Kennaway { 68974664626SKris Kennaway bad: 69074664626SKris Kennaway sv_usage(); 69174664626SKris Kennaway goto end; 69274664626SKris Kennaway } 69374664626SKris Kennaway 6945c87c606SMark Murray SSL_load_error_strings(); 6955c87c606SMark Murray OpenSSL_add_ssl_algorithms(); 6965c87c606SMark Murray 6975c87c606SMark Murray e = setup_engine(bio_err, engine_id, 1); 6985c87c606SMark Murray 6995740a5e3SKris Kennaway if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL 7005740a5e3SKris Kennaway && !RAND_status()) 7015740a5e3SKris Kennaway { 7025740a5e3SKris Kennaway BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); 7035740a5e3SKris Kennaway } 7045740a5e3SKris Kennaway if (inrand != NULL) 7055740a5e3SKris Kennaway BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 7065740a5e3SKris Kennaway app_RAND_load_files(inrand)); 707f579bf8eSKris Kennaway 70874664626SKris Kennaway if (bio_s_out == NULL) 70974664626SKris Kennaway { 7105c87c606SMark Murray if (s_quiet && !s_debug && !s_msg) 71174664626SKris Kennaway { 71274664626SKris Kennaway bio_s_out=BIO_new(BIO_s_null()); 71374664626SKris Kennaway } 71474664626SKris Kennaway else 71574664626SKris Kennaway { 71674664626SKris Kennaway if (bio_s_out == NULL) 71774664626SKris Kennaway bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE); 71874664626SKris Kennaway } 71974664626SKris Kennaway } 72074664626SKris Kennaway 7215c87c606SMark Murray #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) 72274664626SKris Kennaway if (nocert) 72374664626SKris Kennaway #endif 72474664626SKris Kennaway { 72574664626SKris Kennaway s_cert_file=NULL; 72674664626SKris Kennaway s_key_file=NULL; 72774664626SKris Kennaway s_dcert_file=NULL; 72874664626SKris Kennaway s_dkey_file=NULL; 72974664626SKris Kennaway } 73074664626SKris Kennaway 73174664626SKris Kennaway ctx=SSL_CTX_new(meth); 73274664626SKris Kennaway if (ctx == NULL) 73374664626SKris Kennaway { 73474664626SKris Kennaway ERR_print_errors(bio_err); 73574664626SKris Kennaway goto end; 73674664626SKris Kennaway } 7375c87c606SMark Murray if (session_id_prefix) 7385c87c606SMark Murray { 7395c87c606SMark Murray if(strlen(session_id_prefix) >= 32) 7405c87c606SMark Murray BIO_printf(bio_err, 7415c87c606SMark Murray "warning: id_prefix is too long, only one new session will be possible\n"); 7425c87c606SMark Murray else if(strlen(session_id_prefix) >= 16) 7435c87c606SMark Murray BIO_printf(bio_err, 7445c87c606SMark Murray "warning: id_prefix is too long if you use SSLv2\n"); 7455c87c606SMark Murray if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) 7465c87c606SMark Murray { 7475c87c606SMark Murray BIO_printf(bio_err,"error setting 'id_prefix'\n"); 7485c87c606SMark Murray ERR_print_errors(bio_err); 7495c87c606SMark Murray goto end; 7505c87c606SMark Murray } 7515c87c606SMark Murray BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); 7525c87c606SMark Murray } 75374664626SKris Kennaway SSL_CTX_set_quiet_shutdown(ctx,1); 75474664626SKris Kennaway if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL); 75574664626SKris Kennaway if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); 75674664626SKris Kennaway SSL_CTX_set_options(ctx,off); 75774664626SKris Kennaway 75874664626SKris Kennaway if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback); 75974664626SKris Kennaway 76074664626SKris Kennaway SSL_CTX_sess_set_cache_size(ctx,128); 76174664626SKris Kennaway 76274664626SKris Kennaway #if 0 76374664626SKris Kennaway if (cipher == NULL) cipher=getenv("SSL_CIPHER"); 76474664626SKris Kennaway #endif 76574664626SKris Kennaway 76674664626SKris Kennaway #if 0 76774664626SKris Kennaway if (s_cert_file == NULL) 76874664626SKris Kennaway { 76974664626SKris Kennaway BIO_printf(bio_err,"You must specify a certificate file for the server to use\n"); 77074664626SKris Kennaway goto end; 77174664626SKris Kennaway } 77274664626SKris Kennaway #endif 77374664626SKris Kennaway 77474664626SKris Kennaway if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || 77574664626SKris Kennaway (!SSL_CTX_set_default_verify_paths(ctx))) 77674664626SKris Kennaway { 77774664626SKris Kennaway /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ 77874664626SKris Kennaway ERR_print_errors(bio_err); 77974664626SKris Kennaway /* goto end; */ 78074664626SKris Kennaway } 7815c87c606SMark Murray store = SSL_CTX_get_cert_store(ctx); 7825c87c606SMark Murray X509_STORE_set_flags(store, vflags); 78374664626SKris Kennaway 7845c87c606SMark Murray #ifndef OPENSSL_NO_DH 78574664626SKris Kennaway if (!no_dhe) 78674664626SKris Kennaway { 7875c87c606SMark Murray DH *dh=NULL; 7885c87c606SMark Murray 7895c87c606SMark Murray if (dhfile) 7905c87c606SMark Murray dh = load_dh_param(dhfile); 7915c87c606SMark Murray else if (s_cert_file) 7925c87c606SMark Murray dh = load_dh_param(s_cert_file); 7935c87c606SMark Murray 79474664626SKris Kennaway if (dh != NULL) 79574664626SKris Kennaway { 79674664626SKris Kennaway BIO_printf(bio_s_out,"Setting temp DH parameters\n"); 79774664626SKris Kennaway } 79874664626SKris Kennaway else 79974664626SKris Kennaway { 80074664626SKris Kennaway BIO_printf(bio_s_out,"Using default temp DH parameters\n"); 80174664626SKris Kennaway dh=get_dh512(); 80274664626SKris Kennaway } 80374664626SKris Kennaway (void)BIO_flush(bio_s_out); 80474664626SKris Kennaway 80574664626SKris Kennaway SSL_CTX_set_tmp_dh(ctx,dh); 80674664626SKris Kennaway DH_free(dh); 80774664626SKris Kennaway } 80874664626SKris Kennaway #endif 80974664626SKris Kennaway 81074664626SKris Kennaway if (!set_cert_stuff(ctx,s_cert_file,s_key_file)) 81174664626SKris Kennaway goto end; 81274664626SKris Kennaway if (s_dcert_file != NULL) 81374664626SKris Kennaway { 81474664626SKris Kennaway if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file)) 81574664626SKris Kennaway goto end; 81674664626SKris Kennaway } 81774664626SKris Kennaway 8185c87c606SMark Murray #ifndef OPENSSL_NO_RSA 81974664626SKris Kennaway #if 1 8205740a5e3SKris Kennaway if (!no_tmp_rsa) 82174664626SKris Kennaway SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); 82274664626SKris Kennaway #else 82374664626SKris Kennaway if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) 82474664626SKris Kennaway { 82574664626SKris Kennaway RSA *rsa; 82674664626SKris Kennaway 82774664626SKris Kennaway BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key..."); 82874664626SKris Kennaway BIO_flush(bio_s_out); 82974664626SKris Kennaway 83074664626SKris Kennaway rsa=RSA_generate_key(512,RSA_F4,NULL); 83174664626SKris Kennaway 83274664626SKris Kennaway if (!SSL_CTX_set_tmp_rsa(ctx,rsa)) 83374664626SKris Kennaway { 83474664626SKris Kennaway ERR_print_errors(bio_err); 83574664626SKris Kennaway goto end; 83674664626SKris Kennaway } 83774664626SKris Kennaway RSA_free(rsa); 83874664626SKris Kennaway BIO_printf(bio_s_out,"\n"); 83974664626SKris Kennaway } 84074664626SKris Kennaway #endif 84174664626SKris Kennaway #endif 84274664626SKris Kennaway 84374664626SKris Kennaway if (cipher != NULL) 844f579bf8eSKris Kennaway if(!SSL_CTX_set_cipher_list(ctx,cipher)) { 845f579bf8eSKris Kennaway BIO_printf(bio_err,"error setting cipher list\n"); 846f579bf8eSKris Kennaway ERR_print_errors(bio_err); 847f579bf8eSKris Kennaway goto end; 848f579bf8eSKris Kennaway } 84974664626SKris Kennaway SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); 85074664626SKris Kennaway SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, 85174664626SKris Kennaway sizeof s_server_session_id_context); 85274664626SKris Kennaway 853f579bf8eSKris Kennaway if (CAfile != NULL) 85474664626SKris Kennaway SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); 85574664626SKris Kennaway 85674664626SKris Kennaway BIO_printf(bio_s_out,"ACCEPT\n"); 85774664626SKris Kennaway if (www) 85874664626SKris Kennaway do_server(port,&accept_socket,www_body, context); 85974664626SKris Kennaway else 86074664626SKris Kennaway do_server(port,&accept_socket,sv_body, context); 86174664626SKris Kennaway print_stats(bio_s_out,ctx); 86274664626SKris Kennaway ret=0; 86374664626SKris Kennaway end: 86474664626SKris Kennaway if (ctx != NULL) SSL_CTX_free(ctx); 86574664626SKris Kennaway if (bio_s_out != NULL) 86674664626SKris Kennaway { 86774664626SKris Kennaway BIO_free(bio_s_out); 86874664626SKris Kennaway bio_s_out=NULL; 86974664626SKris Kennaway } 8705c87c606SMark Murray apps_shutdown(); 8715c87c606SMark Murray OPENSSL_EXIT(ret); 87274664626SKris Kennaway } 87374664626SKris Kennaway 87474664626SKris Kennaway static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) 87574664626SKris Kennaway { 87674664626SKris Kennaway BIO_printf(bio,"%4ld items in the session cache\n", 87774664626SKris Kennaway SSL_CTX_sess_number(ssl_ctx)); 87874664626SKris Kennaway BIO_printf(bio,"%4d client connects (SSL_connect())\n", 87974664626SKris Kennaway SSL_CTX_sess_connect(ssl_ctx)); 88074664626SKris Kennaway BIO_printf(bio,"%4d client renegotiates (SSL_connect())\n", 88174664626SKris Kennaway SSL_CTX_sess_connect_renegotiate(ssl_ctx)); 88274664626SKris Kennaway BIO_printf(bio,"%4d client connects that finished\n", 88374664626SKris Kennaway SSL_CTX_sess_connect_good(ssl_ctx)); 88474664626SKris Kennaway BIO_printf(bio,"%4d server accepts (SSL_accept())\n", 88574664626SKris Kennaway SSL_CTX_sess_accept(ssl_ctx)); 88674664626SKris Kennaway BIO_printf(bio,"%4d server renegotiates (SSL_accept())\n", 88774664626SKris Kennaway SSL_CTX_sess_accept_renegotiate(ssl_ctx)); 88874664626SKris Kennaway BIO_printf(bio,"%4d server accepts that finished\n", 88974664626SKris Kennaway SSL_CTX_sess_accept_good(ssl_ctx)); 89074664626SKris Kennaway BIO_printf(bio,"%4d session cache hits\n",SSL_CTX_sess_hits(ssl_ctx)); 89174664626SKris Kennaway BIO_printf(bio,"%4d session cache misses\n",SSL_CTX_sess_misses(ssl_ctx)); 89274664626SKris Kennaway BIO_printf(bio,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx)); 89374664626SKris Kennaway BIO_printf(bio,"%4d callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx)); 89474664626SKris Kennaway BIO_printf(bio,"%4d cache full overflows (%d allowed)\n", 89574664626SKris Kennaway SSL_CTX_sess_cache_full(ssl_ctx), 89674664626SKris Kennaway SSL_CTX_sess_get_cache_size(ssl_ctx)); 89774664626SKris Kennaway } 89874664626SKris Kennaway 89974664626SKris Kennaway static int sv_body(char *hostname, int s, unsigned char *context) 90074664626SKris Kennaway { 90174664626SKris Kennaway char *buf=NULL; 90274664626SKris Kennaway fd_set readfds; 90374664626SKris Kennaway int ret=1,width; 90474664626SKris Kennaway int k,i; 90574664626SKris Kennaway unsigned long l; 90674664626SKris Kennaway SSL *con=NULL; 90774664626SKris Kennaway BIO *sbio; 9085c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS 909f579bf8eSKris Kennaway struct timeval tv; 910f579bf8eSKris Kennaway #endif 91174664626SKris Kennaway 912ddd58736SKris Kennaway if ((buf=OPENSSL_malloc(bufsize)) == NULL) 91374664626SKris Kennaway { 91474664626SKris Kennaway BIO_printf(bio_err,"out of memory\n"); 91574664626SKris Kennaway goto err; 91674664626SKris Kennaway } 91774664626SKris Kennaway #ifdef FIONBIO 91874664626SKris Kennaway if (s_nbio) 91974664626SKris Kennaway { 92074664626SKris Kennaway unsigned long sl=1; 92174664626SKris Kennaway 92274664626SKris Kennaway if (!s_quiet) 92374664626SKris Kennaway BIO_printf(bio_err,"turning on non blocking io\n"); 92474664626SKris Kennaway if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) 92574664626SKris Kennaway ERR_print_errors(bio_err); 92674664626SKris Kennaway } 92774664626SKris Kennaway #endif 92874664626SKris Kennaway 92974664626SKris Kennaway if (con == NULL) { 930f579bf8eSKris Kennaway con=SSL_new(ctx); 9315c87c606SMark Murray #ifndef OPENSSL_NO_KRB5 9325c87c606SMark Murray if ((con->kssl_ctx = kssl_ctx_new()) != NULL) 9335c87c606SMark Murray { 9345c87c606SMark Murray kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, 9355c87c606SMark Murray KRB5SVC); 9365c87c606SMark Murray kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, 9375c87c606SMark Murray KRB5KEYTAB); 9385c87c606SMark Murray } 9395c87c606SMark Murray #endif /* OPENSSL_NO_KRB5 */ 94074664626SKris Kennaway if(context) 94174664626SKris Kennaway SSL_set_session_id_context(con, context, 94274664626SKris Kennaway strlen((char *)context)); 94374664626SKris Kennaway } 94474664626SKris Kennaway SSL_clear(con); 94574664626SKris Kennaway 94674664626SKris Kennaway sbio=BIO_new_socket(s,BIO_NOCLOSE); 94774664626SKris Kennaway if (s_nbio_test) 94874664626SKris Kennaway { 94974664626SKris Kennaway BIO *test; 95074664626SKris Kennaway 95174664626SKris Kennaway test=BIO_new(BIO_f_nbio_test()); 95274664626SKris Kennaway sbio=BIO_push(test,sbio); 95374664626SKris Kennaway } 95474664626SKris Kennaway SSL_set_bio(con,sbio,sbio); 95574664626SKris Kennaway SSL_set_accept_state(con); 95674664626SKris Kennaway /* SSL_set_fd(con,s); */ 95774664626SKris Kennaway 95874664626SKris Kennaway if (s_debug) 95974664626SKris Kennaway { 96074664626SKris Kennaway con->debug=1; 96174664626SKris Kennaway BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); 96274664626SKris Kennaway BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out); 96374664626SKris Kennaway } 9645c87c606SMark Murray if (s_msg) 9655c87c606SMark Murray { 9665c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 9675c87c606SMark Murray SSL_set_msg_callback_arg(con, bio_s_out); 9685c87c606SMark Murray } 96974664626SKris Kennaway 97074664626SKris Kennaway width=s+1; 97174664626SKris Kennaway for (;;) 97274664626SKris Kennaway { 973f579bf8eSKris Kennaway int read_from_terminal; 974f579bf8eSKris Kennaway int read_from_sslcon; 975f579bf8eSKris Kennaway 976f579bf8eSKris Kennaway read_from_terminal = 0; 977f579bf8eSKris Kennaway read_from_sslcon = SSL_pending(con); 978f579bf8eSKris Kennaway 979f579bf8eSKris Kennaway if (!read_from_sslcon) 980f579bf8eSKris Kennaway { 98174664626SKris Kennaway FD_ZERO(&readfds); 9825c87c606SMark Murray #ifndef OPENSSL_SYS_WINDOWS 98374664626SKris Kennaway FD_SET(fileno(stdin),&readfds); 98474664626SKris Kennaway #endif 98574664626SKris Kennaway FD_SET(s,&readfds); 98674664626SKris Kennaway /* Note: under VMS with SOCKETSHR the second parameter is 98774664626SKris Kennaway * currently of type (int *) whereas under other systems 98874664626SKris Kennaway * it is (void *) if you don't have a cast it will choke 98974664626SKris Kennaway * the compiler: if you do have a cast then you can either 99074664626SKris Kennaway * go for (int *) or (void *). 99174664626SKris Kennaway */ 9925c87c606SMark Murray #ifdef OPENSSL_SYS_WINDOWS 993f579bf8eSKris Kennaway /* Under Windows we can't select on stdin: only 994f579bf8eSKris Kennaway * on sockets. As a workaround we timeout the select every 995f579bf8eSKris Kennaway * second and check for any keypress. In a proper Windows 996f579bf8eSKris Kennaway * application we wouldn't do this because it is inefficient. 997f579bf8eSKris Kennaway */ 998f579bf8eSKris Kennaway tv.tv_sec = 1; 999f579bf8eSKris Kennaway tv.tv_usec = 0; 1000f579bf8eSKris Kennaway i=select(width,(void *)&readfds,NULL,NULL,&tv); 1001f579bf8eSKris Kennaway if((i < 0) || (!i && !_kbhit() ) )continue; 1002f579bf8eSKris Kennaway if(_kbhit()) 1003f579bf8eSKris Kennaway read_from_terminal = 1; 1004f579bf8eSKris Kennaway #else 100574664626SKris Kennaway i=select(width,(void *)&readfds,NULL,NULL,NULL); 100674664626SKris Kennaway if (i <= 0) continue; 100774664626SKris Kennaway if (FD_ISSET(fileno(stdin),&readfds)) 1008f579bf8eSKris Kennaway read_from_terminal = 1; 1009f579bf8eSKris Kennaway #endif 1010f579bf8eSKris Kennaway if (FD_ISSET(s,&readfds)) 1011f579bf8eSKris Kennaway read_from_sslcon = 1; 1012f579bf8eSKris Kennaway } 1013f579bf8eSKris Kennaway if (read_from_terminal) 101474664626SKris Kennaway { 101574664626SKris Kennaway if (s_crlf) 101674664626SKris Kennaway { 101774664626SKris Kennaway int j, lf_num; 101874664626SKris Kennaway 101974664626SKris Kennaway i=read(fileno(stdin), buf, bufsize/2); 102074664626SKris Kennaway lf_num = 0; 102174664626SKris Kennaway /* both loops are skipped when i <= 0 */ 102274664626SKris Kennaway for (j = 0; j < i; j++) 102374664626SKris Kennaway if (buf[j] == '\n') 102474664626SKris Kennaway lf_num++; 102574664626SKris Kennaway for (j = i-1; j >= 0; j--) 102674664626SKris Kennaway { 102774664626SKris Kennaway buf[j+lf_num] = buf[j]; 102874664626SKris Kennaway if (buf[j] == '\n') 102974664626SKris Kennaway { 103074664626SKris Kennaway lf_num--; 103174664626SKris Kennaway i++; 103274664626SKris Kennaway buf[j+lf_num] = '\r'; 103374664626SKris Kennaway } 103474664626SKris Kennaway } 103574664626SKris Kennaway assert(lf_num == 0); 103674664626SKris Kennaway } 103774664626SKris Kennaway else 103874664626SKris Kennaway i=read(fileno(stdin),buf,bufsize); 103974664626SKris Kennaway if (!s_quiet) 104074664626SKris Kennaway { 104174664626SKris Kennaway if ((i <= 0) || (buf[0] == 'Q')) 104274664626SKris Kennaway { 104374664626SKris Kennaway BIO_printf(bio_s_out,"DONE\n"); 104474664626SKris Kennaway SHUTDOWN(s); 104574664626SKris Kennaway close_accept_socket(); 104674664626SKris Kennaway ret= -11; 104774664626SKris Kennaway goto err; 104874664626SKris Kennaway } 104974664626SKris Kennaway if ((i <= 0) || (buf[0] == 'q')) 105074664626SKris Kennaway { 105174664626SKris Kennaway BIO_printf(bio_s_out,"DONE\n"); 105274664626SKris Kennaway SHUTDOWN(s); 105374664626SKris Kennaway /* close_accept_socket(); 105474664626SKris Kennaway ret= -11;*/ 105574664626SKris Kennaway goto err; 105674664626SKris Kennaway } 105774664626SKris Kennaway if ((buf[0] == 'r') && 105874664626SKris Kennaway ((buf[1] == '\n') || (buf[1] == '\r'))) 105974664626SKris Kennaway { 106074664626SKris Kennaway SSL_renegotiate(con); 106174664626SKris Kennaway i=SSL_do_handshake(con); 106274664626SKris Kennaway printf("SSL_do_handshake -> %d\n",i); 106374664626SKris Kennaway i=0; /*13; */ 106474664626SKris Kennaway continue; 106574664626SKris Kennaway /* strcpy(buf,"server side RE-NEGOTIATE\n"); */ 106674664626SKris Kennaway } 106774664626SKris Kennaway if ((buf[0] == 'R') && 106874664626SKris Kennaway ((buf[1] == '\n') || (buf[1] == '\r'))) 106974664626SKris Kennaway { 107074664626SKris Kennaway SSL_set_verify(con, 107174664626SKris Kennaway SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL); 107274664626SKris Kennaway SSL_renegotiate(con); 107374664626SKris Kennaway i=SSL_do_handshake(con); 107474664626SKris Kennaway printf("SSL_do_handshake -> %d\n",i); 107574664626SKris Kennaway i=0; /* 13; */ 107674664626SKris Kennaway continue; 107774664626SKris Kennaway /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */ 107874664626SKris Kennaway } 107974664626SKris Kennaway if (buf[0] == 'P') 108074664626SKris Kennaway { 108174664626SKris Kennaway static char *str="Lets print some clear text\n"; 108274664626SKris Kennaway BIO_write(SSL_get_wbio(con),str,strlen(str)); 108374664626SKris Kennaway } 108474664626SKris Kennaway if (buf[0] == 'S') 108574664626SKris Kennaway { 108674664626SKris Kennaway print_stats(bio_s_out,SSL_get_SSL_CTX(con)); 108774664626SKris Kennaway } 108874664626SKris Kennaway } 108974664626SKris Kennaway #ifdef CHARSET_EBCDIC 109074664626SKris Kennaway ebcdic2ascii(buf,buf,i); 109174664626SKris Kennaway #endif 109274664626SKris Kennaway l=k=0; 109374664626SKris Kennaway for (;;) 109474664626SKris Kennaway { 109574664626SKris Kennaway /* should do a select for the write */ 109674664626SKris Kennaway #ifdef RENEG 109774664626SKris Kennaway { static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } } 109874664626SKris Kennaway #endif 109974664626SKris Kennaway k=SSL_write(con,&(buf[l]),(unsigned int)i); 110074664626SKris Kennaway switch (SSL_get_error(con,k)) 110174664626SKris Kennaway { 110274664626SKris Kennaway case SSL_ERROR_NONE: 110374664626SKris Kennaway break; 110474664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 110574664626SKris Kennaway case SSL_ERROR_WANT_READ: 110674664626SKris Kennaway case SSL_ERROR_WANT_X509_LOOKUP: 110774664626SKris Kennaway BIO_printf(bio_s_out,"Write BLOCK\n"); 110874664626SKris Kennaway break; 110974664626SKris Kennaway case SSL_ERROR_SYSCALL: 111074664626SKris Kennaway case SSL_ERROR_SSL: 111174664626SKris Kennaway BIO_printf(bio_s_out,"ERROR\n"); 111274664626SKris Kennaway ERR_print_errors(bio_err); 111374664626SKris Kennaway ret=1; 111474664626SKris Kennaway goto err; 111574664626SKris Kennaway /* break; */ 111674664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 111774664626SKris Kennaway BIO_printf(bio_s_out,"DONE\n"); 111874664626SKris Kennaway ret=1; 111974664626SKris Kennaway goto err; 112074664626SKris Kennaway } 112174664626SKris Kennaway l+=k; 112274664626SKris Kennaway i-=k; 112374664626SKris Kennaway if (i <= 0) break; 112474664626SKris Kennaway } 112574664626SKris Kennaway } 1126f579bf8eSKris Kennaway if (read_from_sslcon) 112774664626SKris Kennaway { 112874664626SKris Kennaway if (!SSL_is_init_finished(con)) 112974664626SKris Kennaway { 113074664626SKris Kennaway i=init_ssl_connection(con); 113174664626SKris Kennaway 113274664626SKris Kennaway if (i < 0) 113374664626SKris Kennaway { 113474664626SKris Kennaway ret=0; 113574664626SKris Kennaway goto err; 113674664626SKris Kennaway } 113774664626SKris Kennaway else if (i == 0) 113874664626SKris Kennaway { 113974664626SKris Kennaway ret=1; 114074664626SKris Kennaway goto err; 114174664626SKris Kennaway } 114274664626SKris Kennaway } 114374664626SKris Kennaway else 114474664626SKris Kennaway { 114574664626SKris Kennaway again: 114674664626SKris Kennaway i=SSL_read(con,(char *)buf,bufsize); 114774664626SKris Kennaway switch (SSL_get_error(con,i)) 114874664626SKris Kennaway { 114974664626SKris Kennaway case SSL_ERROR_NONE: 115074664626SKris Kennaway #ifdef CHARSET_EBCDIC 115174664626SKris Kennaway ascii2ebcdic(buf,buf,i); 115274664626SKris Kennaway #endif 115374664626SKris Kennaway write(fileno(stdout),buf, 115474664626SKris Kennaway (unsigned int)i); 115574664626SKris Kennaway if (SSL_pending(con)) goto again; 115674664626SKris Kennaway break; 115774664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 115874664626SKris Kennaway case SSL_ERROR_WANT_READ: 115974664626SKris Kennaway case SSL_ERROR_WANT_X509_LOOKUP: 116074664626SKris Kennaway BIO_printf(bio_s_out,"Read BLOCK\n"); 116174664626SKris Kennaway break; 116274664626SKris Kennaway case SSL_ERROR_SYSCALL: 116374664626SKris Kennaway case SSL_ERROR_SSL: 116474664626SKris Kennaway BIO_printf(bio_s_out,"ERROR\n"); 116574664626SKris Kennaway ERR_print_errors(bio_err); 116674664626SKris Kennaway ret=1; 116774664626SKris Kennaway goto err; 116874664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 116974664626SKris Kennaway BIO_printf(bio_s_out,"DONE\n"); 117074664626SKris Kennaway ret=1; 117174664626SKris Kennaway goto err; 117274664626SKris Kennaway } 117374664626SKris Kennaway } 117474664626SKris Kennaway } 117574664626SKris Kennaway } 117674664626SKris Kennaway err: 117774664626SKris Kennaway BIO_printf(bio_s_out,"shutting down SSL\n"); 117874664626SKris Kennaway #if 1 117974664626SKris Kennaway SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 118074664626SKris Kennaway #else 118174664626SKris Kennaway SSL_shutdown(con); 118274664626SKris Kennaway #endif 118374664626SKris Kennaway if (con != NULL) SSL_free(con); 118474664626SKris Kennaway BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); 118574664626SKris Kennaway if (buf != NULL) 118674664626SKris Kennaway { 11875c87c606SMark Murray OPENSSL_cleanse(buf,bufsize); 1188ddd58736SKris Kennaway OPENSSL_free(buf); 118974664626SKris Kennaway } 119074664626SKris Kennaway if (ret >= 0) 119174664626SKris Kennaway BIO_printf(bio_s_out,"ACCEPT\n"); 119274664626SKris Kennaway return(ret); 119374664626SKris Kennaway } 119474664626SKris Kennaway 119574664626SKris Kennaway static void close_accept_socket(void) 119674664626SKris Kennaway { 119774664626SKris Kennaway BIO_printf(bio_err,"shutdown accept socket\n"); 119874664626SKris Kennaway if (accept_socket >= 0) 119974664626SKris Kennaway { 120074664626SKris Kennaway SHUTDOWN2(accept_socket); 120174664626SKris Kennaway } 120274664626SKris Kennaway } 120374664626SKris Kennaway 120474664626SKris Kennaway static int init_ssl_connection(SSL *con) 120574664626SKris Kennaway { 120674664626SKris Kennaway int i; 120774664626SKris Kennaway const char *str; 120874664626SKris Kennaway X509 *peer; 120974664626SKris Kennaway long verify_error; 121074664626SKris Kennaway MS_STATIC char buf[BUFSIZ]; 121174664626SKris Kennaway 121274664626SKris Kennaway if ((i=SSL_accept(con)) <= 0) 121374664626SKris Kennaway { 121474664626SKris Kennaway if (BIO_sock_should_retry(i)) 121574664626SKris Kennaway { 121674664626SKris Kennaway BIO_printf(bio_s_out,"DELAY\n"); 121774664626SKris Kennaway return(1); 121874664626SKris Kennaway } 121974664626SKris Kennaway 122074664626SKris Kennaway BIO_printf(bio_err,"ERROR\n"); 122174664626SKris Kennaway verify_error=SSL_get_verify_result(con); 122274664626SKris Kennaway if (verify_error != X509_V_OK) 122374664626SKris Kennaway { 122474664626SKris Kennaway BIO_printf(bio_err,"verify error:%s\n", 122574664626SKris Kennaway X509_verify_cert_error_string(verify_error)); 122674664626SKris Kennaway } 122774664626SKris Kennaway else 122874664626SKris Kennaway ERR_print_errors(bio_err); 122974664626SKris Kennaway return(0); 123074664626SKris Kennaway } 123174664626SKris Kennaway 123274664626SKris Kennaway PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); 123374664626SKris Kennaway 123474664626SKris Kennaway peer=SSL_get_peer_certificate(con); 123574664626SKris Kennaway if (peer != NULL) 123674664626SKris Kennaway { 123774664626SKris Kennaway BIO_printf(bio_s_out,"Client certificate\n"); 123874664626SKris Kennaway PEM_write_bio_X509(bio_s_out,peer); 12395c87c606SMark Murray X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf); 124074664626SKris Kennaway BIO_printf(bio_s_out,"subject=%s\n",buf); 12415c87c606SMark Murray X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf); 124274664626SKris Kennaway BIO_printf(bio_s_out,"issuer=%s\n",buf); 124374664626SKris Kennaway X509_free(peer); 124474664626SKris Kennaway } 124574664626SKris Kennaway 12465c87c606SMark Murray if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL) 124774664626SKris Kennaway BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); 124874664626SKris Kennaway str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); 124974664626SKris Kennaway BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); 125074664626SKris Kennaway if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); 125174664626SKris Kennaway if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & 125274664626SKris Kennaway TLS1_FLAGS_TLS_PADDING_BUG) 125374664626SKris Kennaway BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n"); 125474664626SKris Kennaway 125574664626SKris Kennaway return(1); 125674664626SKris Kennaway } 125774664626SKris Kennaway 12585c87c606SMark Murray #ifndef OPENSSL_NO_DH 1259f579bf8eSKris Kennaway static DH *load_dh_param(char *dhfile) 126074664626SKris Kennaway { 126174664626SKris Kennaway DH *ret=NULL; 126274664626SKris Kennaway BIO *bio; 126374664626SKris Kennaway 1264f579bf8eSKris Kennaway if ((bio=BIO_new_file(dhfile,"r")) == NULL) 126574664626SKris Kennaway goto err; 126674664626SKris Kennaway ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL); 126774664626SKris Kennaway err: 126874664626SKris Kennaway if (bio != NULL) BIO_free(bio); 126974664626SKris Kennaway return(ret); 127074664626SKris Kennaway } 127174664626SKris Kennaway #endif 127274664626SKris Kennaway 127374664626SKris Kennaway #if 0 127474664626SKris Kennaway static int load_CA(SSL_CTX *ctx, char *file) 127574664626SKris Kennaway { 127674664626SKris Kennaway FILE *in; 127774664626SKris Kennaway X509 *x=NULL; 127874664626SKris Kennaway 127974664626SKris Kennaway if ((in=fopen(file,"r")) == NULL) 128074664626SKris Kennaway return(0); 128174664626SKris Kennaway 128274664626SKris Kennaway for (;;) 128374664626SKris Kennaway { 128474664626SKris Kennaway if (PEM_read_X509(in,&x,NULL) == NULL) 128574664626SKris Kennaway break; 128674664626SKris Kennaway SSL_CTX_add_client_CA(ctx,x); 128774664626SKris Kennaway } 128874664626SKris Kennaway if (x != NULL) X509_free(x); 128974664626SKris Kennaway fclose(in); 129074664626SKris Kennaway return(1); 129174664626SKris Kennaway } 129274664626SKris Kennaway #endif 129374664626SKris Kennaway 129474664626SKris Kennaway static int www_body(char *hostname, int s, unsigned char *context) 129574664626SKris Kennaway { 129674664626SKris Kennaway char *buf=NULL; 129774664626SKris Kennaway int ret=1; 129874664626SKris Kennaway int i,j,k,blank,dot; 129974664626SKris Kennaway struct stat st_buf; 130074664626SKris Kennaway SSL *con; 130174664626SKris Kennaway SSL_CIPHER *c; 130274664626SKris Kennaway BIO *io,*ssl_bio,*sbio; 130374664626SKris Kennaway long total_bytes; 130474664626SKris Kennaway 1305ddd58736SKris Kennaway buf=OPENSSL_malloc(bufsize); 130674664626SKris Kennaway if (buf == NULL) return(0); 130774664626SKris Kennaway io=BIO_new(BIO_f_buffer()); 130874664626SKris Kennaway ssl_bio=BIO_new(BIO_f_ssl()); 130974664626SKris Kennaway if ((io == NULL) || (ssl_bio == NULL)) goto err; 131074664626SKris Kennaway 131174664626SKris Kennaway #ifdef FIONBIO 131274664626SKris Kennaway if (s_nbio) 131374664626SKris Kennaway { 131474664626SKris Kennaway unsigned long sl=1; 131574664626SKris Kennaway 131674664626SKris Kennaway if (!s_quiet) 131774664626SKris Kennaway BIO_printf(bio_err,"turning on non blocking io\n"); 131874664626SKris Kennaway if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) 131974664626SKris Kennaway ERR_print_errors(bio_err); 132074664626SKris Kennaway } 132174664626SKris Kennaway #endif 132274664626SKris Kennaway 132374664626SKris Kennaway /* lets make the output buffer a reasonable size */ 132474664626SKris Kennaway if (!BIO_set_write_buffer_size(io,bufsize)) goto err; 132574664626SKris Kennaway 1326f579bf8eSKris Kennaway if ((con=SSL_new(ctx)) == NULL) goto err; 13275c87c606SMark Murray #ifndef OPENSSL_NO_KRB5 13285c87c606SMark Murray if ((con->kssl_ctx = kssl_ctx_new()) != NULL) 13295c87c606SMark Murray { 13305c87c606SMark Murray kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC); 13315c87c606SMark Murray kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB); 13325c87c606SMark Murray } 13335c87c606SMark Murray #endif /* OPENSSL_NO_KRB5 */ 133474664626SKris Kennaway if(context) SSL_set_session_id_context(con, context, 133574664626SKris Kennaway strlen((char *)context)); 133674664626SKris Kennaway 133774664626SKris Kennaway sbio=BIO_new_socket(s,BIO_NOCLOSE); 133874664626SKris Kennaway if (s_nbio_test) 133974664626SKris Kennaway { 134074664626SKris Kennaway BIO *test; 134174664626SKris Kennaway 134274664626SKris Kennaway test=BIO_new(BIO_f_nbio_test()); 134374664626SKris Kennaway sbio=BIO_push(test,sbio); 134474664626SKris Kennaway } 134574664626SKris Kennaway SSL_set_bio(con,sbio,sbio); 134674664626SKris Kennaway SSL_set_accept_state(con); 134774664626SKris Kennaway 134874664626SKris Kennaway /* SSL_set_fd(con,s); */ 134974664626SKris Kennaway BIO_set_ssl(ssl_bio,con,BIO_CLOSE); 135074664626SKris Kennaway BIO_push(io,ssl_bio); 135174664626SKris Kennaway #ifdef CHARSET_EBCDIC 135274664626SKris Kennaway io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io); 135374664626SKris Kennaway #endif 135474664626SKris Kennaway 135574664626SKris Kennaway if (s_debug) 135674664626SKris Kennaway { 135774664626SKris Kennaway con->debug=1; 135874664626SKris Kennaway BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); 135974664626SKris Kennaway BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out); 136074664626SKris Kennaway } 13615c87c606SMark Murray if (s_msg) 13625c87c606SMark Murray { 13635c87c606SMark Murray SSL_set_msg_callback(con, msg_cb); 13645c87c606SMark Murray SSL_set_msg_callback_arg(con, bio_s_out); 13655c87c606SMark Murray } 136674664626SKris Kennaway 136774664626SKris Kennaway blank=0; 136874664626SKris Kennaway for (;;) 136974664626SKris Kennaway { 137074664626SKris Kennaway if (hack) 137174664626SKris Kennaway { 137274664626SKris Kennaway i=SSL_accept(con); 137374664626SKris Kennaway 137474664626SKris Kennaway switch (SSL_get_error(con,i)) 137574664626SKris Kennaway { 137674664626SKris Kennaway case SSL_ERROR_NONE: 137774664626SKris Kennaway break; 137874664626SKris Kennaway case SSL_ERROR_WANT_WRITE: 137974664626SKris Kennaway case SSL_ERROR_WANT_READ: 138074664626SKris Kennaway case SSL_ERROR_WANT_X509_LOOKUP: 138174664626SKris Kennaway continue; 138274664626SKris Kennaway case SSL_ERROR_SYSCALL: 138374664626SKris Kennaway case SSL_ERROR_SSL: 138474664626SKris Kennaway case SSL_ERROR_ZERO_RETURN: 138574664626SKris Kennaway ret=1; 138674664626SKris Kennaway goto err; 138774664626SKris Kennaway /* break; */ 138874664626SKris Kennaway } 138974664626SKris Kennaway 139074664626SKris Kennaway SSL_renegotiate(con); 139174664626SKris Kennaway SSL_write(con,NULL,0); 139274664626SKris Kennaway } 139374664626SKris Kennaway 139474664626SKris Kennaway i=BIO_gets(io,buf,bufsize-1); 139574664626SKris Kennaway if (i < 0) /* error */ 139674664626SKris Kennaway { 139774664626SKris Kennaway if (!BIO_should_retry(io)) 139874664626SKris Kennaway { 139974664626SKris Kennaway if (!s_quiet) 140074664626SKris Kennaway ERR_print_errors(bio_err); 140174664626SKris Kennaway goto err; 140274664626SKris Kennaway } 140374664626SKris Kennaway else 140474664626SKris Kennaway { 140574664626SKris Kennaway BIO_printf(bio_s_out,"read R BLOCK\n"); 14065c87c606SMark Murray #if !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__) 140774664626SKris Kennaway sleep(1); 140874664626SKris Kennaway #endif 140974664626SKris Kennaway continue; 141074664626SKris Kennaway } 141174664626SKris Kennaway } 141274664626SKris Kennaway else if (i == 0) /* end of input */ 141374664626SKris Kennaway { 141474664626SKris Kennaway ret=1; 141574664626SKris Kennaway goto end; 141674664626SKris Kennaway } 141774664626SKris Kennaway 141874664626SKris Kennaway /* else we have data */ 141974664626SKris Kennaway if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) || 142074664626SKris Kennaway ((www == 2) && (strncmp("GET /stats ",buf,10) == 0))) 142174664626SKris Kennaway { 142274664626SKris Kennaway char *p; 142374664626SKris Kennaway X509 *peer; 142474664626SKris Kennaway STACK_OF(SSL_CIPHER) *sk; 142574664626SKris Kennaway static char *space=" "; 142674664626SKris Kennaway 142774664626SKris Kennaway BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 142874664626SKris Kennaway BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n"); 142974664626SKris Kennaway BIO_puts(io,"<pre>\n"); 143074664626SKris Kennaway /* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ 143174664626SKris Kennaway BIO_puts(io,"\n"); 143274664626SKris Kennaway for (i=0; i<local_argc; i++) 143374664626SKris Kennaway { 143474664626SKris Kennaway BIO_puts(io,local_argv[i]); 143574664626SKris Kennaway BIO_write(io," ",1); 143674664626SKris Kennaway } 143774664626SKris Kennaway BIO_puts(io,"\n"); 143874664626SKris Kennaway 143974664626SKris Kennaway /* The following is evil and should not really 144074664626SKris Kennaway * be done */ 144174664626SKris Kennaway BIO_printf(io,"Ciphers supported in s_server binary\n"); 144274664626SKris Kennaway sk=SSL_get_ciphers(con); 144374664626SKris Kennaway j=sk_SSL_CIPHER_num(sk); 144474664626SKris Kennaway for (i=0; i<j; i++) 144574664626SKris Kennaway { 144674664626SKris Kennaway c=sk_SSL_CIPHER_value(sk,i); 144774664626SKris Kennaway BIO_printf(io,"%-11s:%-25s", 144874664626SKris Kennaway SSL_CIPHER_get_version(c), 144974664626SKris Kennaway SSL_CIPHER_get_name(c)); 145074664626SKris Kennaway if ((((i+1)%2) == 0) && (i+1 != j)) 145174664626SKris Kennaway BIO_puts(io,"\n"); 145274664626SKris Kennaway } 145374664626SKris Kennaway BIO_puts(io,"\n"); 145474664626SKris Kennaway p=SSL_get_shared_ciphers(con,buf,bufsize); 145574664626SKris Kennaway if (p != NULL) 145674664626SKris Kennaway { 145774664626SKris Kennaway BIO_printf(io,"---\nCiphers common between both SSL end points:\n"); 145874664626SKris Kennaway j=i=0; 145974664626SKris Kennaway while (*p) 146074664626SKris Kennaway { 146174664626SKris Kennaway if (*p == ':') 146274664626SKris Kennaway { 146374664626SKris Kennaway BIO_write(io,space,26-j); 146474664626SKris Kennaway i++; 146574664626SKris Kennaway j=0; 146674664626SKris Kennaway BIO_write(io,((i%3)?" ":"\n"),1); 146774664626SKris Kennaway } 146874664626SKris Kennaway else 146974664626SKris Kennaway { 147074664626SKris Kennaway BIO_write(io,p,1); 147174664626SKris Kennaway j++; 147274664626SKris Kennaway } 147374664626SKris Kennaway p++; 147474664626SKris Kennaway } 147574664626SKris Kennaway BIO_puts(io,"\n"); 147674664626SKris Kennaway } 147774664626SKris Kennaway BIO_printf(io,((con->hit) 147874664626SKris Kennaway ?"---\nReused, " 147974664626SKris Kennaway :"---\nNew, ")); 148074664626SKris Kennaway c=SSL_get_current_cipher(con); 148174664626SKris Kennaway BIO_printf(io,"%s, Cipher is %s\n", 148274664626SKris Kennaway SSL_CIPHER_get_version(c), 148374664626SKris Kennaway SSL_CIPHER_get_name(c)); 148474664626SKris Kennaway SSL_SESSION_print(io,SSL_get_session(con)); 148574664626SKris Kennaway BIO_printf(io,"---\n"); 148674664626SKris Kennaway print_stats(io,SSL_get_SSL_CTX(con)); 148774664626SKris Kennaway BIO_printf(io,"---\n"); 148874664626SKris Kennaway peer=SSL_get_peer_certificate(con); 148974664626SKris Kennaway if (peer != NULL) 149074664626SKris Kennaway { 149174664626SKris Kennaway BIO_printf(io,"Client certificate\n"); 149274664626SKris Kennaway X509_print(io,peer); 149374664626SKris Kennaway PEM_write_bio_X509(io,peer); 149474664626SKris Kennaway } 149574664626SKris Kennaway else 149674664626SKris Kennaway BIO_puts(io,"no client certificate available\n"); 149774664626SKris Kennaway BIO_puts(io,"</BODY></HTML>\r\n\r\n"); 149874664626SKris Kennaway break; 149974664626SKris Kennaway } 15005c87c606SMark Murray else if ((www == 2 || www == 3) 15015c87c606SMark Murray && (strncmp("GET /",buf,5) == 0)) 150274664626SKris Kennaway { 150374664626SKris Kennaway BIO *file; 150474664626SKris Kennaway char *p,*e; 150574664626SKris Kennaway static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; 150674664626SKris Kennaway 150774664626SKris Kennaway /* skip the '/' */ 150874664626SKris Kennaway p= &(buf[5]); 15095740a5e3SKris Kennaway 15105740a5e3SKris Kennaway dot = 1; 151174664626SKris Kennaway for (e=p; *e != '\0'; e++) 151274664626SKris Kennaway { 15135740a5e3SKris Kennaway if (e[0] == ' ') 15145740a5e3SKris Kennaway break; 151574664626SKris Kennaway 15165740a5e3SKris Kennaway switch (dot) 15175740a5e3SKris Kennaway { 15185740a5e3SKris Kennaway case 1: 15195740a5e3SKris Kennaway dot = (e[0] == '.') ? 2 : 0; 15205740a5e3SKris Kennaway break; 15215740a5e3SKris Kennaway case 2: 15225740a5e3SKris Kennaway dot = (e[0] == '.') ? 3 : 0; 15235740a5e3SKris Kennaway break; 15245740a5e3SKris Kennaway case 3: 15255740a5e3SKris Kennaway dot = (e[0] == '/') ? -1 : 0; 15265740a5e3SKris Kennaway break; 15275740a5e3SKris Kennaway } 15285740a5e3SKris Kennaway if (dot == 0) 15295740a5e3SKris Kennaway dot = (e[0] == '/') ? 1 : 0; 15305740a5e3SKris Kennaway } 15315740a5e3SKris Kennaway dot = (dot == 3) || (dot == -1); /* filename contains ".." component */ 153274664626SKris Kennaway 153374664626SKris Kennaway if (*e == '\0') 153474664626SKris Kennaway { 153574664626SKris Kennaway BIO_puts(io,text); 153674664626SKris Kennaway BIO_printf(io,"'%s' is an invalid file name\r\n",p); 153774664626SKris Kennaway break; 153874664626SKris Kennaway } 153974664626SKris Kennaway *e='\0'; 154074664626SKris Kennaway 154174664626SKris Kennaway if (dot) 154274664626SKris Kennaway { 154374664626SKris Kennaway BIO_puts(io,text); 154474664626SKris Kennaway BIO_printf(io,"'%s' contains '..' reference\r\n",p); 154574664626SKris Kennaway break; 154674664626SKris Kennaway } 154774664626SKris Kennaway 154874664626SKris Kennaway if (*p == '/') 154974664626SKris Kennaway { 155074664626SKris Kennaway BIO_puts(io,text); 155174664626SKris Kennaway BIO_printf(io,"'%s' is an invalid path\r\n",p); 155274664626SKris Kennaway break; 155374664626SKris Kennaway } 155474664626SKris Kennaway 15555740a5e3SKris Kennaway #if 0 155674664626SKris Kennaway /* append if a directory lookup */ 155774664626SKris Kennaway if (e[-1] == '/') 155874664626SKris Kennaway strcat(p,"index.html"); 15595740a5e3SKris Kennaway #endif 156074664626SKris Kennaway 156174664626SKris Kennaway /* if a directory, do the index thang */ 156274664626SKris Kennaway if (stat(p,&st_buf) < 0) 156374664626SKris Kennaway { 156474664626SKris Kennaway BIO_puts(io,text); 156574664626SKris Kennaway BIO_printf(io,"Error accessing '%s'\r\n",p); 156674664626SKris Kennaway ERR_print_errors(io); 156774664626SKris Kennaway break; 156874664626SKris Kennaway } 156974664626SKris Kennaway if (S_ISDIR(st_buf.st_mode)) 157074664626SKris Kennaway { 15715740a5e3SKris Kennaway #if 0 /* must check buffer size */ 157274664626SKris Kennaway strcat(p,"/index.html"); 15735740a5e3SKris Kennaway #else 15745740a5e3SKris Kennaway BIO_puts(io,text); 15755740a5e3SKris Kennaway BIO_printf(io,"'%s' is a directory\r\n",p); 15765740a5e3SKris Kennaway break; 15775740a5e3SKris Kennaway #endif 157874664626SKris Kennaway } 157974664626SKris Kennaway 158074664626SKris Kennaway if ((file=BIO_new_file(p,"r")) == NULL) 158174664626SKris Kennaway { 158274664626SKris Kennaway BIO_puts(io,text); 158374664626SKris Kennaway BIO_printf(io,"Error opening '%s'\r\n",p); 158474664626SKris Kennaway ERR_print_errors(io); 158574664626SKris Kennaway break; 158674664626SKris Kennaway } 158774664626SKris Kennaway 158874664626SKris Kennaway if (!s_quiet) 158974664626SKris Kennaway BIO_printf(bio_err,"FILE:%s\n",p); 159074664626SKris Kennaway 15915c87c606SMark Murray if (www == 2) 15925c87c606SMark Murray { 159374664626SKris Kennaway i=strlen(p); 159474664626SKris Kennaway if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) || 159574664626SKris Kennaway ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) || 159674664626SKris Kennaway ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0))) 159774664626SKris Kennaway BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); 159874664626SKris Kennaway else 159974664626SKris Kennaway BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"); 16005c87c606SMark Murray } 160174664626SKris Kennaway /* send the file */ 160274664626SKris Kennaway total_bytes=0; 160374664626SKris Kennaway for (;;) 160474664626SKris Kennaway { 160574664626SKris Kennaway i=BIO_read(file,buf,bufsize); 160674664626SKris Kennaway if (i <= 0) break; 160774664626SKris Kennaway 160874664626SKris Kennaway #ifdef RENEG 160974664626SKris Kennaway total_bytes+=i; 161074664626SKris Kennaway fprintf(stderr,"%d\n",i); 161174664626SKris Kennaway if (total_bytes > 3*1024) 161274664626SKris Kennaway { 161374664626SKris Kennaway total_bytes=0; 161474664626SKris Kennaway fprintf(stderr,"RENEGOTIATE\n"); 161574664626SKris Kennaway SSL_renegotiate(con); 161674664626SKris Kennaway } 161774664626SKris Kennaway #endif 161874664626SKris Kennaway 161974664626SKris Kennaway for (j=0; j<i; ) 162074664626SKris Kennaway { 162174664626SKris Kennaway #ifdef RENEG 162274664626SKris Kennaway { static count=0; if (++count == 13) { SSL_renegotiate(con); } } 162374664626SKris Kennaway #endif 162474664626SKris Kennaway k=BIO_write(io,&(buf[j]),i-j); 162574664626SKris Kennaway if (k <= 0) 162674664626SKris Kennaway { 162774664626SKris Kennaway if (!BIO_should_retry(io)) 162874664626SKris Kennaway goto write_error; 162974664626SKris Kennaway else 163074664626SKris Kennaway { 163174664626SKris Kennaway BIO_printf(bio_s_out,"rwrite W BLOCK\n"); 163274664626SKris Kennaway } 163374664626SKris Kennaway } 163474664626SKris Kennaway else 163574664626SKris Kennaway { 163674664626SKris Kennaway j+=k; 163774664626SKris Kennaway } 163874664626SKris Kennaway } 163974664626SKris Kennaway } 164074664626SKris Kennaway write_error: 164174664626SKris Kennaway BIO_free(file); 164274664626SKris Kennaway break; 164374664626SKris Kennaway } 164474664626SKris Kennaway } 164574664626SKris Kennaway 164674664626SKris Kennaway for (;;) 164774664626SKris Kennaway { 164874664626SKris Kennaway i=(int)BIO_flush(io); 164974664626SKris Kennaway if (i <= 0) 165074664626SKris Kennaway { 165174664626SKris Kennaway if (!BIO_should_retry(io)) 165274664626SKris Kennaway break; 165374664626SKris Kennaway } 165474664626SKris Kennaway else 165574664626SKris Kennaway break; 165674664626SKris Kennaway } 165774664626SKris Kennaway end: 165874664626SKris Kennaway #if 1 165974664626SKris Kennaway /* make sure we re-use sessions */ 166074664626SKris Kennaway SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); 166174664626SKris Kennaway #else 1662f579bf8eSKris Kennaway /* This kills performance */ 166374664626SKris Kennaway /* SSL_shutdown(con); A shutdown gets sent in the 166474664626SKris Kennaway * BIO_free_all(io) procession */ 166574664626SKris Kennaway #endif 166674664626SKris Kennaway 166774664626SKris Kennaway err: 166874664626SKris Kennaway 166974664626SKris Kennaway if (ret >= 0) 167074664626SKris Kennaway BIO_printf(bio_s_out,"ACCEPT\n"); 167174664626SKris Kennaway 1672ddd58736SKris Kennaway if (buf != NULL) OPENSSL_free(buf); 167374664626SKris Kennaway if (io != NULL) BIO_free_all(io); 167474664626SKris Kennaway /* if (ssl_bio != NULL) BIO_free(ssl_bio);*/ 167574664626SKris Kennaway return(ret); 167674664626SKris Kennaway } 167774664626SKris Kennaway 16785c87c606SMark Murray #ifndef OPENSSL_NO_RSA 167974664626SKris Kennaway static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) 168074664626SKris Kennaway { 168174664626SKris Kennaway static RSA *rsa_tmp=NULL; 168274664626SKris Kennaway 168374664626SKris Kennaway if (rsa_tmp == NULL) 168474664626SKris Kennaway { 168574664626SKris Kennaway if (!s_quiet) 168674664626SKris Kennaway { 168774664626SKris Kennaway BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); 168874664626SKris Kennaway (void)BIO_flush(bio_err); 168974664626SKris Kennaway } 169074664626SKris Kennaway rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL); 169174664626SKris Kennaway if (!s_quiet) 169274664626SKris Kennaway { 169374664626SKris Kennaway BIO_printf(bio_err,"\n"); 169474664626SKris Kennaway (void)BIO_flush(bio_err); 169574664626SKris Kennaway } 169674664626SKris Kennaway } 169774664626SKris Kennaway return(rsa_tmp); 169874664626SKris Kennaway } 169974664626SKris Kennaway #endif 17005c87c606SMark Murray 17015c87c606SMark Murray #define MAX_SESSION_ID_ATTEMPTS 10 17025c87c606SMark Murray static int generate_session_id(const SSL *ssl, unsigned char *id, 17035c87c606SMark Murray unsigned int *id_len) 17045c87c606SMark Murray { 17055c87c606SMark Murray unsigned int count = 0; 17065c87c606SMark Murray do { 17075c87c606SMark Murray RAND_pseudo_bytes(id, *id_len); 17085c87c606SMark Murray /* Prefix the session_id with the required prefix. NB: If our 17095c87c606SMark Murray * prefix is too long, clip it - but there will be worse effects 17105c87c606SMark Murray * anyway, eg. the server could only possibly create 1 session 17115c87c606SMark Murray * ID (ie. the prefix!) so all future session negotiations will 17125c87c606SMark Murray * fail due to conflicts. */ 17135c87c606SMark Murray memcpy(id, session_id_prefix, 17145c87c606SMark Murray (strlen(session_id_prefix) < *id_len) ? 17155c87c606SMark Murray strlen(session_id_prefix) : *id_len); 17165c87c606SMark Murray } 17175c87c606SMark Murray while(SSL_has_matching_session_id(ssl, id, *id_len) && 17185c87c606SMark Murray (++count < MAX_SESSION_ID_ATTEMPTS)); 17195c87c606SMark Murray if(count >= MAX_SESSION_ID_ATTEMPTS) 17205c87c606SMark Murray return 0; 17215c87c606SMark Murray return 1; 17225c87c606SMark Murray } 1723