siglen is unsigned, so comparing it to less than 0 is silly, and
[openssl.git] / apps / s_server.c
index e54593d5514b17f89002715aec6ef03d22a77278..b5932832569a693eb6db6e883d33226ea8214eb9 100644 (file)
@@ -94,10 +94,6 @@ typedef unsigned int u_int;
 #undef FIONBIO
 #endif
 
-#if defined(NO_RSA) && !defined(NO_SSL2)
-#define NO_SSL2
-#endif
-
 #ifndef NO_RSA
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
 #endif
@@ -108,7 +104,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
@@ -153,15 +149,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;
@@ -217,10 +211,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
@@ -243,7 +239,7 @@ static void sv_usage(void)
 #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," -bugs         - Turn on SSL bug compatibility\n");
        BIO_printf(bio_err," -www          - Respond to a 'GET /' with a status page\n");
        BIO_printf(bio_err," -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
        }
@@ -289,7 +285,7 @@ static int ebcdic_new(BIO *bi)
 {
        EBCDIC_OUTBUFF *wbuf;
 
-       wbuf = (EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+       wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
        wbuf->alloced = 1024;
        wbuf->buff[0] = '\0';
 
@@ -303,7 +299,7 @@ static int ebcdic_free(BIO *a)
 {
        if (a == NULL) return(0);
        if (a->ptr != NULL)
-               Free(a->ptr);
+               OPENSSL_free(a->ptr);
        a->ptr=NULL;
        a->init=0;
        a->flags=0;
@@ -340,8 +336,8 @@ static int ebcdic_write(BIO *b, char *in, int inl)
                num = num + num;  /* double the size */
                if (num < inl)
                        num = inl;
-               Free((char*)wbuf);
-               wbuf=(EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + num);
+               OPENSSL_free(wbuf);
+               wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
 
                wbuf->alloced = num;
                wbuf->buff[0] = '\0';
@@ -401,11 +397,14 @@ static int ebcdic_puts(BIO *bp, char *str)
 }
 #endif
 
+int MAIN(int, char **);
+
 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;
@@ -483,6 +482,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;
@@ -577,6 +581,8 @@ bad:
                goto end;
                }
 
+       app_RAND_load_file(NULL, bio_err, 0);
+
        if (bio_s_out == NULL)
                {
                if (s_quiet && !s_debug)
@@ -601,7 +607,7 @@ bad:
                }
 
        SSL_load_error_strings();
-       SSLeay_add_ssl_algorithms();
+       OpenSSL_add_ssl_algorithms();
 
        ctx=SSL_CTX_new(meth);
        if (ctx == NULL)
@@ -643,8 +649,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");
@@ -694,7 +699,11 @@ bad:
 #endif
 
        if (cipher != NULL)
-               SSL_CTX_set_cipher_list(ctx,cipher);
+               if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+               BIO_printf(bio_err,"error setting cipher list\n");
+               ERR_print_errors(bio_err);
+               goto end;
+       }
        SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
        SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
                sizeof s_server_session_id_context);
@@ -757,7 +766,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
        struct timeval tv;
 #endif
 
-       if ((buf=Malloc(bufsize)) == NULL)
+       if ((buf=OPENSSL_malloc(bufsize)) == NULL)
                {
                BIO_printf(bio_err,"out of memory\n");
                goto err;
@@ -775,7 +784,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
 #endif
 
        if (con == NULL) {
-               con=(SSL *)SSL_new(ctx);
+               con=SSL_new(ctx);
                if(context)
                      SSL_set_session_id_context(con, context,
                                                 strlen((char *)context));
@@ -804,33 +813,47 @@ static int sv_body(char *hostname, int s, unsigned char *context)
        width=s+1;
        for (;;)
                {
-               FD_ZERO(&readfds);
+               int read_from_terminal;
+               int read_from_sslcon;
+
+               read_from_terminal = 0;
+               read_from_sslcon = SSL_pending(con);
+
+               if (!read_from_sslcon)
+                       {
+                       FD_ZERO(&readfds);
 #ifndef WINDOWS
-               FD_SET(fileno(stdin),&readfds);
+                       FD_SET(fileno(stdin),&readfds);
 #endif
-               FD_SET(s,&readfds);
-               /* Note: under VMS with SOCKETSHR the second parameter is
-                * currently of type (int *) whereas under other systems
-                * it is (void *) if you don't have a cast it will choke
-                * the compiler: if you do have a cast then you can either
-                * go for (int *) or (void *).
-                */
+                       FD_SET(s,&readfds);
+                       /* Note: under VMS with SOCKETSHR the second parameter is
+                        * currently of type (int *) whereas under other systems
+                        * it is (void *) if you don't have a cast it will choke
+                        * the compiler: if you do have a cast then you can either
+                        * go for (int *) or (void *).
+                        */
 #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())
+                       /* 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())
+                               read_from_terminal = 1;
 #else
-               i=select(width,(void *)&readfds,NULL,NULL,NULL);
-               if (i <= 0) continue;
-               if (FD_ISSET(fileno(stdin),&readfds))
+                       i=select(width,(void *)&readfds,NULL,NULL,NULL);
+                       if (i <= 0) continue;
+                       if (FD_ISSET(fileno(stdin),&readfds))
+                               read_from_terminal = 1;
 #endif
+                       if (FD_ISSET(s,&readfds))
+                               read_from_sslcon = 1;
+                       }
+               if (read_from_terminal)
                        {
                        if (s_crlf)
                                {
@@ -943,7 +966,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                                if (i <= 0) break;
                                }
                        }
-               if (FD_ISSET(s,&readfds))
+               if (read_from_sslcon)
                        {
                        if (!SSL_is_init_finished(con))
                                {
@@ -1005,7 +1028,7 @@ err:
        if (buf != NULL)
                {
                memset(buf,0,bufsize);
-               Free(buf);
+               OPENSSL_free(buf);
                }
        if (ret >= 0)
                BIO_printf(bio_s_out,"ACCEPT\n");
@@ -1076,12 +1099,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:
@@ -1122,7 +1145,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
        BIO *io,*ssl_bio,*sbio;
        long total_bytes;
 
-       buf=Malloc(bufsize);
+       buf=OPENSSL_malloc(bufsize);
        if (buf == NULL) return(0);
        io=BIO_new(BIO_f_buffer());
        ssl_bio=BIO_new(BIO_f_ssl());
@@ -1143,7 +1166,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
        /* lets make the output buffer a reasonable size */
        if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
 
-       if ((con=(SSL *)SSL_new(ctx)) == NULL) goto err;
+       if ((con=SSL_new(ctx)) == NULL) goto err;
        if(context) SSL_set_session_id_context(con, context,
                                               strlen((char *)context));
 
@@ -1441,7 +1464,7 @@ end:
        /* make sure we re-use sessions */
        SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
 #else
-       /* This kills performace */
+       /* This kills performance */
 /*     SSL_shutdown(con); A shutdown gets sent in the
  *     BIO_free_all(io) procession */
 #endif
@@ -1451,7 +1474,7 @@ err:
        if (ret >= 0)
                BIO_printf(bio_s_out,"ACCEPT\n");
 
-       if (buf != NULL) Free(buf);
+       if (buf != NULL) OPENSSL_free(buf);
        if (io != NULL) BIO_free_all(io);
 /*     if (ssl_bio != NULL) BIO_free(ssl_bio);*/
        return(ret);