Overhaul of by_dir code to handle dynamic loading of CRLs.
[openssl.git] / apps / s_server.c
index 7dc864fab9b39963412249d4398dc6c013e4d459..ac43e5aac1de0b3d46cc48cc39fe0f6140fee4b5 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * ECC cipher suite support in OpenSSL originally developed by 
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
 
 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
  * deprecated functions for openssl-internal code */
 #endif
 
 #include <assert.h>
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -166,6 +193,10 @@ typedef unsigned int u_int;
 #undef FIONBIO
 #endif
 
+#if defined(OPENSSL_SYS_BEOS_R5)
+#include <fcntl.h>
+#endif
+
 #ifndef OPENSSL_NO_RSA
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
 #endif
@@ -227,7 +258,7 @@ static int accept_socket= -1;
 #undef PROG
 #define PROG           s_server_main
 
-extern int verify_depth;
+extern int verify_depth, verify_return_error;
 
 static char *cipher=NULL;
 static int s_server_verify=SSL_VERIFY_NONE;
@@ -260,9 +291,73 @@ static char *engine_id=NULL;
 static const char *session_id_prefix=NULL;
 
 static int enable_timeouts = 0;
-static long socketMtu;
+static long socket_mtu;
 static int cert_chain = 0;
 
+#ifndef OPENSSL_NO_PSK
+static char *psk_identity="Client_identity";
+static char *psk_key=NULL; /* by default PSK is not used */
+
+static unsigned int psk_server_cb(SSL *ssl, const char *identity,
+       unsigned char *psk, unsigned int max_psk_len)
+       {
+       unsigned int psk_len = 0;
+       int ret;
+       BIGNUM *bn = NULL;
+
+       if (s_debug)
+               BIO_printf(bio_s_out,"psk_server_cb\n");
+       if (!identity)
+               {
+               BIO_printf(bio_err,"Error: client did not send PSK identity\n");
+               goto out_err;
+               }
+       if (s_debug)
+               BIO_printf(bio_s_out,"identity_len=%d identity=%s\n",
+                       identity ? strlen(identity) : 0, identity);
+
+       /* here we could lookup the given identity e.g. from a database */
+       if (strcmp(identity, psk_identity) != 0)
+               {
+                BIO_printf(bio_s_out, "PSK error: client identity not found\n");
+               goto out_err;
+                }
+       if (s_debug)
+               BIO_printf(bio_s_out, "PSK client identity found\n");
+
+       /* convert the PSK key to binary */
+       ret = BN_hex2bn(&bn, psk_key);
+       if (!ret)
+               {
+               BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", psk_key);
+               if (bn)
+                       BN_free(bn);
+               return 0;
+               }
+       if (BN_num_bytes(bn) > (int)max_psk_len)
+               {
+               BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n",
+                       max_psk_len, BN_num_bytes(bn));
+               BN_free(bn);
+               return 0;
+               }
+
+       ret = BN_bn2bin(bn, psk);
+       BN_free(bn);
+
+       if (ret < 0)
+               goto out_err;
+       psk_len = (unsigned int)ret;
+
+       if (s_debug)
+               BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
+        return psk_len;
+ out_err:
+       if (s_debug)
+               BIO_printf(bio_err, "Error in PSK server callback\n");
+       return 0;
+        }
+#endif
 
 #ifdef MONOLITH
 static void s_server_init(void)
@@ -322,7 +417,7 @@ static void sv_usage(void)
 #ifndef OPENSSL_NO_ECDH
        BIO_printf(bio_err," -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n" \
                           "                 Use \"openssl ecparam -list_curves\" for all names\n" \
-                          "                 (default is sect163r2).\n");
+                          "                 (default is nistp256).\n");
 #endif
 #ifdef FIONBIO
        BIO_printf(bio_err," -nbio         - Run with non-blocking IO\n");
@@ -339,6 +434,10 @@ static void sv_usage(void)
        BIO_printf(bio_err," -serverpref   - Use server's cipher preferences\n");
        BIO_printf(bio_err," -quiet        - No server output\n");
        BIO_printf(bio_err," -no_tmp_rsa   - Do not generate a tmp RSA key\n");
+#ifndef OPENSSL_NO_PSK
+       BIO_printf(bio_err," -psk_hint arg - PSK identity hint to use\n");
+       BIO_printf(bio_err," -psk arg      - PSK in hex (without 0x)\n");
+#endif
        BIO_printf(bio_err," -ssl2         - Just talk SSLv2\n");
        BIO_printf(bio_err," -ssl3         - Just talk SSLv3\n");
        BIO_printf(bio_err," -tls1         - Just talk TLSv1\n");
@@ -366,12 +465,12 @@ static void sv_usage(void)
        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);
 #ifndef OPENSSL_NO_TLSEXT
-       BIO_printf(bio_err," -servername host - check TLS1 servername\n");
+       BIO_printf(bio_err," -servername host - servername for HostName TLS extension\n");
+       BIO_printf(bio_err," -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
        BIO_printf(bio_err," -cert2 arg    - certificate file to use for servername\n");
        BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT2);
        BIO_printf(bio_err," -key2 arg     - Private Key file to use for servername, in cert file if\n");
        BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT2);
-       BIO_printf(bio_err," -servername host - check TLS1 servername\n");
 #endif
        }
 
@@ -534,28 +633,31 @@ static int ebcdic_puts(BIO *bp, const char *str)
 typedef struct tlsextctx_st {
    char * servername;
    BIO * biodebug;
+   int extension_error;
 } tlsextctx;
 
 
-static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg) {
+static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
+       {
        tlsextctx * p = (tlsextctx *) arg;
-       const char * servername = SSL_get_servername(s, TLSEXT_TYPE_SERVER_host);
-        if (servername) 
+       const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+        if (servername && p->biodebug
                BIO_printf(p->biodebug,"Hostname in TLS extension: \"%s\"\n",servername);
         
-       if (!p->servername) {
-               SSL_set_tlsext_servername_done(s,2);
-               return SSL_ERROR_NONE;
-       }
+       if (!p->servername)
+               return SSL_TLSEXT_ERR_NOACK;
        
-       if (servername) {
+       if (servername)
+               {
                if (strcmp(servername,p->servername)) 
-                       return TLS1_AD_UNRECOGNIZED_NAME;
-               if (ctx2) 
+                       return p->extension_error;
+               if (ctx2)
+                       {
+                       BIO_printf(p->biodebug,"Swiching server context.\n");
                        SSL_set_SSL_CTX(s,ctx2);
-               SSL_set_tlsext_servername_done(s,1);
-       }
-       return SSL_ERROR_NONE;
+                       }     
+               }
+       return SSL_TLSEXT_ERR_OK;
 }
 #endif
 
@@ -578,7 +680,7 @@ int MAIN(int argc, char *argv[])
        int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
        int state=0;
        const SSL_METHOD *meth=NULL;
-       int socketType=SOCK_STREAM;
+       int socket_type=SOCK_STREAM;
 #ifndef OPENSSL_NO_ENGINE
        ENGINE *e=NULL;
 #endif
@@ -595,9 +697,11 @@ int MAIN(int argc, char *argv[])
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
-        tlsextctx tlsextcbp = 
-        {NULL,NULL
-        };
+        tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
+#endif
+#ifndef OPENSSL_NO_PSK
+       /* by default do not send a PSK identity hint */
+       static char *psk_identity_hint=NULL;
 #endif
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
        meth=SSLv23_server_method();
@@ -738,6 +842,8 @@ int MAIN(int argc, char *argv[])
                        {
                        vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
                        }
+               else if (strcmp(*argv,"-verify_return_error") == 0)
+                       verify_return_error = 1;
                else if (strcmp(*argv,"-serverpref") == 0)
                        { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
                else if (strcmp(*argv,"-cipher") == 0)
@@ -781,6 +887,27 @@ int MAIN(int argc, char *argv[])
                        { no_dhe=1; }
                else if (strcmp(*argv,"-no_ecdhe") == 0)
                        { no_ecdhe=1; }
+#ifndef OPENSSL_NO_PSK
+                else if (strcmp(*argv,"-psk_hint") == 0)
+                       {
+                        if (--argc < 1) goto bad;
+                        psk_identity_hint= *(++argv);
+                        }
+                else if (strcmp(*argv,"-psk") == 0)
+                       {
+                       size_t i;
+
+                       if (--argc < 1) goto bad;
+                       psk_key=*(++argv);
+                       for (i=0; i<strlen(psk_key); i++)
+                               {
+                               if (isxdigit((int)psk_key[i]))
+                                       continue;
+                               BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
+                               goto bad;
+                               }
+                       }
+#endif
                else if (strcmp(*argv,"-www") == 0)
                        { www=1; }
                else if (strcmp(*argv,"-WWW") == 0)
@@ -811,14 +938,14 @@ int MAIN(int argc, char *argv[])
                else if (strcmp(*argv,"-dtls1") == 0)
                        { 
                        meth=DTLSv1_server_method();
-                       socketType = SOCK_DGRAM;
+                       socket_type = SOCK_DGRAM;
                        }
                else if (strcmp(*argv,"-timeout") == 0)
                        enable_timeouts = 1;
                else if (strcmp(*argv,"-mtu") == 0)
                        {
                        if (--argc < 1) goto bad;
-                       socketMtu = atol(*(++argv));
+                       socket_mtu = atol(*(++argv));
                        }
                else if (strcmp(*argv, "-chain") == 0)
                        cert_chain = 1;
@@ -845,8 +972,9 @@ int MAIN(int argc, char *argv[])
                        {
                        if (--argc < 1) goto bad;
                        tlsextcbp.servername= *(++argv);
-                       /* meth=TLSv1_server_method(); */
                        }
+               else if (strcmp(*argv,"-servername_fatal") == 0)
+                       { tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL; }
                else if (strcmp(*argv,"-cert2") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -915,19 +1043,19 @@ bad:
                        }
 
 #ifndef OPENSSL_NO_TLSEXT
-                       if (tlsextcbp.servername) 
+               if (tlsextcbp.servername) 
                        {
                        s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
-                       "second server certificate private key file");
+                               "second server certificate private key file");
                        if (!s_key2)
                                {
                                ERR_print_errors(bio_err);
                                goto end;
                                }
-
+                       
                        s_cert2 = load_cert(bio_err,s_cert_file2,s_cert_format,
                                NULL, e, "second server certificate file");
-
+                       
                        if (!s_cert2)
                                {
                                ERR_print_errors(bio_err);
@@ -1029,7 +1157,7 @@ bad:
        /* DTLS: partial reads end up discarding unread UDP bytes :-( 
         * Setting read ahead solves this problem.
         */
-       if (socketType == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
+       if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
 
        if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
 
@@ -1058,56 +1186,59 @@ bad:
        X509_STORE_set_flags(store, vflags);
 
 #ifndef OPENSSL_NO_TLSEXT
-       if (s_cert2) {
-       ctx2=SSL_CTX_new(meth);
-       if (ctx2 == NULL)
-               {
-               ERR_print_errors(bio_err);
-               goto end;
-               }
-       }
-       
-       if (ctx2) {
-                       BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
-       if (session_id_prefix)
+       if (s_cert2)
                {
-               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(ctx2, generate_session_id))
+               ctx2=SSL_CTX_new(meth);
+               if (ctx2 == NULL)
                        {
-                       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(ctx2,1);
-       if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
-       if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
-       SSL_CTX_set_options(ctx2,off);
-       /* DTLS: partial reads end up discarding unread UDP bytes :-( 
-        * Setting read ahead solves this problem.
-        */
-       if (socketType == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
+       
+       if (ctx2)
+               {
+               BIO_printf(bio_s_out,"Setting secondary ctx parameters\n");
+
+               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(ctx2, 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(ctx2,1);
+               if (bugs) SSL_CTX_set_options(ctx2,SSL_OP_ALL);
+               if (hack) SSL_CTX_set_options(ctx2,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
+               SSL_CTX_set_options(ctx2,off);
+               /* DTLS: partial reads end up discarding unread UDP bytes :-( 
+                * Setting read ahead solves this problem.
+                */
+               if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx2, 1);
 
-       if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
+               if (state) SSL_CTX_set_info_callback(ctx2,apps_ssl_info_callback);
 
-       SSL_CTX_sess_set_cache_size(ctx2,128);
+               SSL_CTX_sess_set_cache_size(ctx2,128);
 
-       if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
-               (!SSL_CTX_set_default_verify_paths(ctx2)))
-               {
+               if ((!SSL_CTX_load_verify_locations(ctx2,CAfile,CApath)) ||
+                       (!SSL_CTX_set_default_verify_paths(ctx2)))
+                       {
                        ERR_print_errors(bio_err);
+                       }
+               store = SSL_CTX_get_cert_store(ctx2);
+               X509_STORE_set_flags(store, vflags);
                }
-       store = SSL_CTX_get_cert_store(ctx2);
-       X509_STORE_set_flags(store, vflags);
-
-       }
 #endif 
+
 #ifndef OPENSSL_NO_DH
        if (!no_dhe)
                {
@@ -1131,20 +1262,22 @@ bad:
 
                SSL_CTX_set_tmp_dh(ctx,dh);
 #ifndef OPENSSL_NO_TLSEXT
-               if (ctx2) {
-                       if (!dhfile) { 
+               if (ctx2)
+                       {
+                       if (!dhfile)
+                               { 
                                DH *dh2=load_dh_param(s_cert_file2);
                                if (dh2 != NULL)
-                               {
+                                       {
                                        BIO_printf(bio_s_out,"Setting temp DH parameters\n");
                                        (void)BIO_flush(bio_s_out);
 
                                        DH_free(dh);
                                        dh = dh2;
+                                       }
                                }
-                       }
                        SSL_CTX_set_tmp_dh(ctx2,dh);
-               }
+                       }
 #endif
                DH_free(dh);
                }
@@ -1181,10 +1314,10 @@ bad:
                else
                        {
                        BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
-                       ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
+                       ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
                        if (ecdh == NULL) 
                                {
-                               BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
+                               BIO_printf(bio_err, "unable to create curve (nistp256)\n");
                                goto end;
                                }
                        }
@@ -1213,13 +1346,14 @@ bad:
 
 #ifndef OPENSSL_NO_RSA
 #if 1
-       if (!no_tmp_rsa) {
+       if (!no_tmp_rsa)
+               {
                SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
 #ifndef OPENSSL_NO_TLSEXT
                if (ctx2) 
                        SSL_CTX_set_tmp_rsa_callback(ctx2,tmp_rsa_cb);
 #endif         
-       }
+               }
 #else
        if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
                {
@@ -1236,13 +1370,14 @@ bad:
                        goto end;
                        }
 #ifndef OPENSSL_NO_TLSEXT
-                       if (ctx2) {
-                               if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+                       if (ctx2)
                                {
+                               if (!SSL_CTX_set_tmp_rsa(ctx2,rsa))
+                                       {
                                        ERR_print_errors(bio_err);
                                        goto end;
+                                       }
                                }
-                       }
 #endif
                RSA_free(rsa);
                BIO_printf(bio_s_out,"\n");
@@ -1250,50 +1385,72 @@ bad:
 #endif
 #endif
 
-       if (cipher != NULL) {
-               if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
+#ifndef OPENSSL_NO_PSK
+       if (psk_key != NULL)
+               {
+               if (s_debug)
+                       BIO_printf(bio_s_out, "PSK key given, setting server callback\n");
+               SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+               }
+
+       if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint))
+               {
+               BIO_printf(bio_err,"error setting PSK identity hint to context\n");
+               ERR_print_errors(bio_err);
+               goto end;
+               }
+#endif
+
+       if (cipher != NULL)
+               {
+               if(!SSL_CTX_set_cipher_list(ctx,cipher))
+                       {
                        BIO_printf(bio_err,"error setting cipher list\n");
                        ERR_print_errors(bio_err);
                        goto end;
-               }
+                       }
 #ifndef OPENSSL_NO_TLSEXT
-               if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher)) {
+               if (ctx2 && !SSL_CTX_set_cipher_list(ctx2,cipher))
+                       {
                        BIO_printf(bio_err,"error setting cipher list\n");
                        ERR_print_errors(bio_err);
                        goto end;
-               }
+                       }
 #endif
-       }
+               }
        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);
 
 #ifndef OPENSSL_NO_TLSEXT
-       if (ctx2) {
+       if (ctx2)
+               {
                SSL_CTX_set_verify(ctx2,s_server_verify,verify_callback);
                SSL_CTX_set_session_id_context(ctx2,(void*)&s_server_session_id_context,
                        sizeof s_server_session_id_context);
 
-       }
-       tlsextcbp.biodebug = bio_s_out;
-       SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
-       SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
-       SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
-       SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
-#endif
-       if (CAfile != NULL) {
-           SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+               tlsextcbp.biodebug = bio_s_out;
+               SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+               SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+               SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+               SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+               }
+#endif
+
+       if (CAfile != NULL)
+               {
+               SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
 #ifndef OPENSSL_NO_TLSEXT
                if (ctx2) 
-                        SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
+                       SSL_CTX_set_client_CA_list(ctx2,SSL_load_client_CA_file(CAfile));
 #endif
-       }
+               }
 
        BIO_printf(bio_s_out,"ACCEPT\n");
        if (www)
-               do_server(port,socketType,&accept_socket,www_body, context);
+               do_server(port,socket_type,&accept_socket,www_body, context);
        else
-               do_server(port,socketType,&accept_socket,sv_body, context);
+               do_server(port,socket_type,&accept_socket,sv_body, context);
        print_stats(bio_s_out,ctx);
        ret=0;
 end:
@@ -1360,7 +1517,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
        unsigned long l;
        SSL *con=NULL;
        BIO *sbio;
-#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
        struct timeval tv;
 #endif
 
@@ -1404,7 +1561,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
 
                sbio=BIO_new_dgram(s,BIO_NOCLOSE);
 
-               if ( enable_timeouts)
+               if (enable_timeouts)
                        {
                        timeout.tv_sec = 0;
                        timeout.tv_usec = DGRAM_RCV_TIMEOUT;
@@ -1415,11 +1572,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                        BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
                        }
 
-               
-               if ( socketMtu > 0)
+               if (socket_mtu > 0)
                        {
                        SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
-                       SSL_set_mtu(con, socketMtu);
+                       SSL_set_mtu(con, socket_mtu);
                        }
                else
                        /* want to do MTU discovery */
@@ -1466,10 +1622,10 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                if (!read_from_sslcon)
                        {
                        FD_ZERO(&readfds);
-#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
-                       FD_SET(fileno(stdin),&readfds);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
+                       openssl_fdset(fileno(stdin),&readfds);
 #endif
-                       FD_SET(s,&readfds);
+                       openssl_fdset(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
@@ -1488,6 +1644,17 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                        if((i < 0) || (!i && !_kbhit() ) )continue;
                        if(_kbhit())
                                read_from_terminal = 1;
+#elif defined(OPENSSL_SYS_BEOS_R5)
+                       /* Under BeOS-R5 the situation is similar to DOS */
+                       tv.tv_sec = 1;
+                       tv.tv_usec = 0;
+                       (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
+                       i=select(width,(void *)&readfds,NULL,NULL,&tv);
+                       if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
+                               continue;
+                       if (read(fileno(stdin), buf, 0) >= 0)
+                               read_from_terminal = 1;
+                       (void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
                        i=select(width,(void *)&readfds,NULL,NULL,NULL);
                        if (i <= 0) continue;
@@ -1542,6 +1709,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
                                        ret= -11;*/
                                        goto err;
                                        }
+
                                if ((buf[0] == 'r') && 
                                        ((buf[1] == '\n') || (buf[1] == '\r')))
                                        {
@@ -1662,13 +1830,16 @@ again:
                        }
                }
 err:
-       BIO_printf(bio_s_out,"shutting down SSL\n");
+       if (con != NULL)
+               {
+               BIO_printf(bio_s_out,"shutting down SSL\n");
 #if 1
-       SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+               SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
 #else
-       SSL_shutdown(con);
+               SSL_shutdown(con);
 #endif
-       if (con != NULL) SSL_free(con);
+               SSL_free(con);
+               }
        BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
        if (buf != NULL)
                {