X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=a33e0ff1477046506bca972a357bd2d948c5e469;hp=aeca2ea7276f4f965150867192cbf71e8685e17e;hb=954ef7ef693f97edbd6be727d417333c28cda0eb;hpb=df63a389a5cae779e535a9dd3ba7a6bfaaf313ec diff --git a/apps/s_server.c b/apps/s_server.c index aeca2ea727..a33e0ff147 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -56,6 +56,16 @@ * [including the GNU Public Licence.] */ +#include +#include +#include +#include +#include +#include +#ifdef NO_STDIO +#define APPS_WIN16 +#endif + /* With IPv6, it looks like Digital has mixed up the proper order of recursive header file inclusion, resulting in the compiler complaining that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which @@ -65,14 +75,6 @@ typedef unsigned int u_int; #endif -#include -#include -#include -#include -#include -#ifdef NO_STDIO -#define APPS_WIN16 -#endif #include #include #define USE_SOCKETS @@ -83,6 +85,10 @@ typedef unsigned int u_int; #include #include "s_apps.h" +#ifdef WINDOWS +#include +#endif + #if (defined(VMS) && __VMS_VER < 70000000) /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ #undef FIONBIO @@ -102,10 +108,12 @@ static void sv_usage(void); static int init_ssl_connection(SSL *s); static void print_stats(BIO *bp,SSL_CTX *ctx); #ifndef NO_DH -static DH *load_dh_param(void ); +static DH *load_dh_param(char *dhfile); static DH *get_dh512(void); #endif -/* static void s_server_init(void);*/ +#ifdef MONOLITH +static void s_server_init(void); +#endif #ifndef S_ISDIR # if defined(_S_IFMT) && defined(_S_IFDIR) @@ -145,15 +153,13 @@ static DH *get_dh512(void) #undef BUFSIZZ #define BUFSIZZ 16*1024 -static int bufsize=32; +static int bufsize=BUFSIZZ; static int accept_socket= -1; #define TEST_CERT "server.pem" #undef PROG #define PROG s_server_main -#define DH_PARAM "server.pem" - extern int verify_depth; static char *cipher=NULL; @@ -165,6 +171,7 @@ static char *s_dcert_file=NULL,*s_dkey_file=NULL; static int s_nbio=0; #endif static int s_nbio_test=0; +int s_crlf=0; static SSL_CTX *ctx=NULL; static int www=0; @@ -172,9 +179,12 @@ static BIO *bio_s_out=NULL; static int s_debug=0; static int s_quiet=0; -#if 0 +static int hack=0; + +#ifdef MONOLITH static void s_server_init(void) { + accept_socket=-1; cipher=NULL; s_server_verify=SSL_VERIFY_NONE; s_dcert_file=NULL; @@ -191,6 +201,7 @@ static void s_server_init(void) bio_s_out=NULL; s_debug=0; s_quiet=0; + hack=0; } #endif @@ -204,14 +215,17 @@ static void sv_usage(void) BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); BIO_printf(bio_err," (default is %s)\n",TEST_CERT); - BIO_printf(bio_err," -key arg - RSA file to use, PEM format assumed, in cert file if\n"); + BIO_printf(bio_err," -key arg - Private Key file to use, PEM format assumed, in cert file if\n"); BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT); BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n"); BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n"); + BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n"); + BIO_printf(bio_err," or a default set of parameters is used\n"); #ifdef FIONBIO BIO_printf(bio_err," -nbio - Run with non-blocking IO\n"); #endif BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n"); + BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n"); BIO_printf(bio_err," -debug - Print more output\n"); BIO_printf(bio_err," -state - Print the SSL states\n"); BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n"); @@ -226,6 +240,9 @@ static void sv_usage(void) BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n"); BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n"); BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n"); +#ifndef NO_DH + BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n"); +#endif BIO_printf(bio_err," -bugs - Turn on SSL bug compatability\n"); BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n"); BIO_printf(bio_err," -WWW - Respond to a 'GET / HTTP/1.0' with file ./\n"); @@ -233,7 +250,6 @@ static void sv_usage(void) static int local_argc=0; static char **local_argv; -static int hack=0; #ifdef CHARSET_EBCDIC static int ebcdic_new(BIO *bi); @@ -390,10 +406,11 @@ int MAIN(int argc, char *argv[]) short port=PORT; char *CApath=NULL,*CAfile=NULL; char *context = NULL; + char *dhfile = NULL; int badop=0,bugs=0; int ret=1; int off=0; - int no_tmp_rsa=0,nocert=0; + int no_tmp_rsa=0,no_dhe=0,nocert=0; int state=0; SSL_METHOD *meth=NULL; #ifndef NO_DH @@ -412,8 +429,9 @@ int MAIN(int argc, char *argv[]) local_argv=argv; apps_startup(); - s_quiet=0; - s_debug=0; +#ifdef MONOLITH + s_server_init(); +#endif if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); @@ -466,6 +484,11 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; s_key_file= *(++argv); } + else if (strcmp(*argv,"-dhparam") == 0) + { + if (--argc < 1) goto bad; + dhfile = *(++argv); + } else if (strcmp(*argv,"-dcert") == 0) { if (--argc < 1) goto bad; @@ -512,12 +535,16 @@ int MAIN(int argc, char *argv[]) { hack=1; } else if (strcmp(*argv,"-state") == 0) { state=1; } + else if (strcmp(*argv,"-crlf") == 0) + { s_crlf=1; } else if (strcmp(*argv,"-quiet") == 0) { s_quiet=1; } else if (strcmp(*argv,"-bugs") == 0) { bugs=1; } else if (strcmp(*argv,"-no_tmp_rsa") == 0) { no_tmp_rsa=1; } + else if (strcmp(*argv,"-no_dhe") == 0) + { no_dhe=1; } else if (strcmp(*argv,"-www") == 0) { www=1; } else if (strcmp(*argv,"-WWW") == 0) @@ -556,6 +583,8 @@ bad: goto end; } + app_RAND_load_file(NULL, bio_err, 0); + if (bio_s_out == NULL) { if (s_quiet && !s_debug) @@ -620,21 +649,23 @@ bad: } #ifndef NO_DH - /* EAY EAY EAY evil hack */ - dh=load_dh_param(); - if (dh != NULL) - { - BIO_printf(bio_s_out,"Setting temp DH parameters\n"); - } - else + if (!no_dhe) { - BIO_printf(bio_s_out,"Using default temp DH parameters\n"); - dh=get_dh512(); - } - BIO_flush(bio_s_out); + dh=load_dh_param(dhfile ? dhfile : s_cert_file); + if (dh != NULL) + { + BIO_printf(bio_s_out,"Setting temp DH parameters\n"); + } + else + { + BIO_printf(bio_s_out,"Using default temp DH parameters\n"); + dh=get_dh512(); + } + (void)BIO_flush(bio_s_out); - SSL_CTX_set_tmp_dh(ctx,dh); - DH_free(dh); + SSL_CTX_set_tmp_dh(ctx,dh); + DH_free(dh); + } #endif if (!set_cert_stuff(ctx,s_cert_file,s_key_file)) @@ -675,7 +706,8 @@ bad: SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, sizeof s_server_session_id_context); - SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); + if (CAfile != NULL) + SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); BIO_printf(bio_s_out,"ACCEPT\n"); if (www) @@ -728,6 +760,9 @@ static int sv_body(char *hostname, int s, unsigned char *context) unsigned long l; SSL *con=NULL; BIO *sbio; +#ifdef WINDOWS + struct timeval tv; +#endif if ((buf=Malloc(bufsize)) == NULL) { @@ -787,11 +822,47 @@ static int sv_body(char *hostname, int s, unsigned char *context) * the compiler: if you do have a cast then you can either * go for (int *) or (void *). */ - i=select(width,(void *)&readfds,NULL,NULL,NULL); - if (i <= 0) continue; - if (FD_ISSET(fileno(stdin),&readfds)) +#ifdef WINDOWS + /* Under Windows we can't select on stdin: only + * on sockets. As a workaround we timeout the select every + * second and check for any keypress. In a proper Windows + * application we wouldn't do this because it is inefficient. + */ + tv.tv_sec = 1; + tv.tv_usec = 0; + i=select(width,(void *)&readfds,NULL,NULL,&tv); + if((i < 0) || (!i && !_kbhit() ) )continue; + if(_kbhit()) +#else + i=select(width,(void *)&readfds,NULL,NULL,NULL); + if (i <= 0) continue; + if (FD_ISSET(fileno(stdin),&readfds)) +#endif { - i=read(fileno(stdin),buf,bufsize); + if (s_crlf) + { + int j, lf_num; + + i=read(fileno(stdin), buf, bufsize/2); + lf_num = 0; + /* both loops are skipped when i <= 0 */ + for (j = 0; j < i; j++) + if (buf[j] == '\n') + lf_num++; + for (j = i-1; j >= 0; j--) + { + buf[j+lf_num] = buf[j]; + if (buf[j] == '\n') + { + lf_num--; + i++; + buf[j+lf_num] = '\r'; + } + } + assert(lf_num == 0); + } + else + i=read(fileno(stdin),buf,bufsize); if (!s_quiet) { if ((i <= 0) || (buf[0] == 'Q')) @@ -1012,14 +1083,14 @@ static int init_ssl_connection(SSL *con) } #ifndef NO_DH -static DH *load_dh_param(void) +static DH *load_dh_param(char *dhfile) { DH *ret=NULL; BIO *bio; - if ((bio=BIO_new_file(DH_PARAM,"r")) == NULL) + if ((bio=BIO_new_file(dhfile,"r")) == NULL) goto err; - ret=PEM_read_bio_DHparams(bio,NULL,NULL); + ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL); err: if (bio != NULL) BIO_free(bio); return(ret); @@ -1403,13 +1474,13 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) if (!s_quiet) { BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); - BIO_flush(bio_err); + (void)BIO_flush(bio_err); } rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL); if (!s_quiet) { BIO_printf(bio_err,"\n"); - BIO_flush(bio_err); + (void)BIO_flush(bio_err); } } return(rsa_tmp);