X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=561e3a2358fbbc951c7a6fa55e9e6b4db93da1d4;hp=c83337b828f5ffe6be58c943af6e862e40c7c1c4;hb=1aa0d9478159b8be4249fc96f575afe8b84e2fa9;hpb=cf1b7d96647d55e533f779e476e3d4371f40445a diff --git a/apps/s_server.c b/apps/s_server.c index c83337b828..561e3a2358 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -62,6 +62,7 @@ #include #include #include +#include #ifdef OPENSSL_NO_STDIO #define APPS_WIN16 #endif @@ -70,7 +71,7 @@ recursive header file inclusion, resulting in the compiler complaining that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is needed to have fileno() declared correctly... So let's define u_int */ -#if defined(VMS) && defined(__DECC) && !defined(__U_INT) +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT) #define __U_INT typedef unsigned int u_int; #endif @@ -86,11 +87,11 @@ typedef unsigned int u_int; #include #include "s_apps.h" -#ifdef WINDOWS +#ifdef OPENSSL_SYS_WINDOWS #include #endif -#if (defined(VMS) && __VMS_VER < 70000000) +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ #undef FIONBIO #endif @@ -104,6 +105,8 @@ static void close_accept_socket(void ); static void sv_usage(void); static int init_ssl_connection(SSL *s); static void print_stats(BIO *bp,SSL_CTX *ctx); +static int generate_session_id(const SSL *ssl, unsigned char *id, + unsigned int *id_len); #ifndef OPENSSL_NO_DH static DH *load_dh_param(char *dhfile); static DH *get_dh512(void); @@ -178,6 +181,7 @@ static int s_quiet=0; static int hack=0; static char *engine_id=NULL; +static const char *session_id_prefix=NULL; #ifdef MONOLITH static void s_server_init(void) @@ -247,6 +251,7 @@ static void sv_usage(void) 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"); BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n"); + BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n"); BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); } @@ -572,6 +577,11 @@ int MAIN(int argc, char *argv[]) else if (strcmp(*argv,"-tls1") == 0) { meth=TLSv1_server_method(); } #endif + else if (strcmp(*argv, "-id_prefix") == 0) + { + if (--argc < 1) goto bad; + session_id_prefix = *(++argv); + } else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; @@ -662,7 +672,22 @@ bad: ERR_print_errors(bio_err); goto end; } - + if (session_id_prefix) + { + if(strlen(session_id_prefix) >= 32) + BIO_printf(bio_err, +"warning: id_prefix is too long, only one new session will be possible\n"); + else if(strlen(session_id_prefix) >= 16) + BIO_printf(bio_err, +"warning: id_prefix is too long if you use SSLv2\n"); + if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) + { + BIO_printf(bio_err,"error setting 'id_prefix'\n"); + ERR_print_errors(bio_err); + goto end; + } + BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix); + } SSL_CTX_set_quiet_shutdown(ctx,1); if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL); if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG); @@ -729,7 +754,8 @@ bad: #ifndef OPENSSL_NO_RSA #if 1 - SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); + if (!no_tmp_rsa) + SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb); #else if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) { @@ -815,7 +841,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) unsigned long l; SSL *con=NULL; BIO *sbio; -#ifdef WINDOWS +#ifdef OPENSSL_SYS_WINDOWS struct timeval tv; #endif @@ -882,7 +908,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) if (!read_from_sslcon) { FD_ZERO(&readfds); -#ifndef WINDOWS +#ifndef OPENSSL_SYS_WINDOWS FD_SET(fileno(stdin),&readfds); #endif FD_SET(s,&readfds); @@ -892,7 +918,7 @@ 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 *). */ -#ifdef WINDOWS +#ifdef OPENSSL_SYS_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 @@ -1294,7 +1320,7 @@ static int www_body(char *hostname, int s, unsigned char *context) else { BIO_printf(bio_s_out,"read R BLOCK\n"); -#ifndef MSDOS +#ifndef OPENSSL_SYS_MSDOS sleep(1); #endif continue; @@ -1562,3 +1588,26 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) return(rsa_tmp); } #endif + +#define MAX_SESSION_ID_ATTEMPTS 10 +static int generate_session_id(const SSL *ssl, unsigned char *id, + unsigned int *id_len) + { + unsigned int count = 0; + do { + RAND_pseudo_bytes(id, *id_len); + /* Prefix the session_id with the required prefix. NB: If our + * prefix is too long, clip it - but there will be worse effects + * anyway, eg. the server could only possibly create 1 session + * ID (ie. the prefix!) so all future session negotiations will + * fail due to conflicts. */ + memcpy(id, session_id_prefix, + (strlen(session_id_prefix) < *id_len) ? + strlen(session_id_prefix) : *id_len); + } + while(SSL_CTX_has_matching_session_id(ssl->ctx, id, *id_len) && + (++count < MAX_SESSION_ID_ATTEMPTS)); + if(count >= MAX_SESSION_ID_ATTEMPTS) + return 0; + return 1; + }