Merge some common functionality in the apps, delete
[openssl.git] / apps / s_server.c
index 144dfa662fdc73cd264c46337d13f8a7188ef79c..a33e0ff1477046506bca972a357bd2d948c5e469 100644 (file)
@@ -85,6 +85,10 @@ typedef unsigned int u_int;
 #include <openssl/ssl.h>
 #include "s_apps.h"
 
+#ifdef WINDOWS
+#include <conio.h>
+#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
@@ -104,7 +108,7 @@ 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
 #ifdef MONOLITH
@@ -149,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;
@@ -213,10 +215,12 @@ 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
@@ -402,6 +406,7 @@ 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;
@@ -479,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;
@@ -573,6 +583,8 @@ bad:
                goto end;
                }
 
+       app_RAND_load_file(NULL, bio_err, 0);
+
        if (bio_s_out == NULL)
                {
                if (s_quiet && !s_debug)
@@ -639,8 +651,7 @@ bad:
 #ifndef NO_DH
        if (!no_dhe)
                {
-               /* EAY EAY EAY evil hack */
-               dh=load_dh_param();
+               dh=load_dh_param(dhfile ? dhfile : s_cert_file);
                if (dh != NULL)
                        {
                        BIO_printf(bio_s_out,"Setting temp DH parameters\n");
@@ -695,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)
@@ -748,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)
                {
@@ -807,9 +822,22 @@ 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
                        {
                        if (s_crlf)
                                {
@@ -1055,12 +1083,12 @@ 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,NULL);
 err: