1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/s_server.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2023 @@
1.4 +/* apps/s_server.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +/* ====================================================================
1.62 + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
1.63 + *
1.64 + * Redistribution and use in source and binary forms, with or without
1.65 + * modification, are permitted provided that the following conditions
1.66 + * are met:
1.67 + *
1.68 + * 1. Redistributions of source code must retain the above copyright
1.69 + * notice, this list of conditions and the following disclaimer.
1.70 + *
1.71 + * 2. Redistributions in binary form must reproduce the above copyright
1.72 + * notice, this list of conditions and the following disclaimer in
1.73 + * the documentation and/or other materials provided with the
1.74 + * distribution.
1.75 + *
1.76 + * 3. All advertising materials mentioning features or use of this
1.77 + * software must display the following acknowledgment:
1.78 + * "This product includes software developed by the OpenSSL Project
1.79 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.80 + *
1.81 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.82 + * endorse or promote products derived from this software without
1.83 + * prior written permission. For written permission, please contact
1.84 + * openssl-core@openssl.org.
1.85 + *
1.86 + * 5. Products derived from this software may not be called "OpenSSL"
1.87 + * nor may "OpenSSL" appear in their names without prior written
1.88 + * permission of the OpenSSL Project.
1.89 + *
1.90 + * 6. Redistributions of any form whatsoever must retain the following
1.91 + * acknowledgment:
1.92 + * "This product includes software developed by the OpenSSL Project
1.93 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.94 + *
1.95 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.96 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.97 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.98 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.99 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.100 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.101 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.102 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.103 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.104 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.105 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.106 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.107 + * ====================================================================
1.108 + *
1.109 + * This product includes cryptographic software written by Eric Young
1.110 + * (eay@cryptsoft.com). This product includes software written by Tim
1.111 + * Hudson (tjh@cryptsoft.com).
1.112 + *
1.113 + */
1.114 +/* ====================================================================
1.115 + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1.116 + * ECC cipher suite support in OpenSSL originally developed by
1.117 + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1.118 + */
1.119 +
1.120 +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
1.121 + * deprecated functions for openssl-internal code */
1.122 +#ifdef OPENSSL_NO_DEPRECATED
1.123 +#undef OPENSSL_NO_DEPRECATED
1.124 +#endif
1.125 +
1.126 +#include <assert.h>
1.127 +#include <stdio.h>
1.128 +#include <stdlib.h>
1.129 +#include <string.h>
1.130 +#include <sys/select.h>
1.131 +#include <sys/stat.h>
1.132 +#include <openssl/e_os2.h>
1.133 +#ifdef OPENSSL_NO_STDIO
1.134 +#define APPS_WIN16
1.135 +#endif
1.136 +
1.137 +#if !defined(OPENSSL_SYS_NETWARE) /* conflicts with winsock2 stuff on netware */
1.138 +#include <sys/types.h>
1.139 +#endif
1.140 +
1.141 +/* With IPv6, it looks like Digital has mixed up the proper order of
1.142 + recursive header file inclusion, resulting in the compiler complaining
1.143 + that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
1.144 + is needed to have fileno() declared correctly... So let's define u_int */
1.145 +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
1.146 +#define __U_INT
1.147 +typedef unsigned int u_int;
1.148 +#endif
1.149 +
1.150 +#include <openssl/lhash.h>
1.151 +#include <openssl/bn.h>
1.152 +#define USE_SOCKETS
1.153 +#include "apps.h"
1.154 +#include <openssl/err.h>
1.155 +#include <openssl/pem.h>
1.156 +#include <openssl/x509.h>
1.157 +#include <openssl/ssl.h>
1.158 +#include <openssl/rand.h>
1.159 +#ifndef OPENSSL_NO_DH
1.160 +#include <openssl/dh.h>
1.161 +#endif
1.162 +#ifndef OPENSSL_NO_RSA
1.163 +#include <openssl/rsa.h>
1.164 +#endif
1.165 +#include "s_apps.h"
1.166 +#include "timeouts.h"
1.167 +
1.168 +#ifdef OPENSSL_SYS_WINCE
1.169 +/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
1.170 +#ifdef fileno
1.171 +#undef fileno
1.172 +#endif
1.173 +#define fileno(a) (int)_fileno(a)
1.174 +#endif
1.175 +
1.176 +#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
1.177 +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
1.178 +#undef FIONBIO
1.179 +#endif
1.180 +
1.181 +#ifndef OPENSSL_NO_RSA
1.182 +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
1.183 +#endif
1.184 +static int sv_body(char *hostname, int s, unsigned char *context);
1.185 +static int www_body(char *hostname, int s, unsigned char *context);
1.186 +static void close_accept_socket(void );
1.187 +static void sv_usage(void);
1.188 +static int init_ssl_connection(SSL *s);
1.189 +static void print_stats(BIO *bp,SSL_CTX *ctx);
1.190 +static int generate_session_id(const SSL *ssl, unsigned char *id,
1.191 + unsigned int *id_len);
1.192 +#ifndef OPENSSL_NO_DH
1.193 +static DH *load_dh_param(const char *dhfile);
1.194 +static DH *get_dh512(void);
1.195 +#endif
1.196 +
1.197 +
1.198 +#ifdef MONOLITH
1.199 +static void s_server_init(void);
1.200 +#endif
1.201 +
1.202 +#ifndef S_ISDIR
1.203 +# if defined(_S_IFMT) && defined(_S_IFDIR)
1.204 +# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)
1.205 +# else
1.206 +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
1.207 +# endif
1.208 +#endif
1.209 +
1.210 +#ifndef OPENSSL_NO_DH
1.211 +static unsigned char dh512_p[]={
1.212 + 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
1.213 + 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
1.214 + 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
1.215 + 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
1.216 + 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
1.217 + 0x47,0x74,0xE8,0x33,
1.218 + };
1.219 +static unsigned char dh512_g[]={
1.220 + 0x02,
1.221 + };
1.222 +
1.223 +static DH *get_dh512(void)
1.224 + {
1.225 + DH *dh=NULL;
1.226 +
1.227 + if ((dh=DH_new()) == NULL) return(NULL);
1.228 + dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
1.229 + dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
1.230 + if ((dh->p == NULL) || (dh->g == NULL))
1.231 + return(NULL);
1.232 + return(dh);
1.233 + }
1.234 +#endif
1.235 +
1.236 +
1.237 +/* static int load_CA(SSL_CTX *ctx, char *file);*/
1.238 +
1.239 +#undef BUFSIZZ
1.240 +#define BUFSIZZ 16*1024
1.241 +static int bufsize=BUFSIZZ;
1.242 +static int accept_socket= -1;
1.243 +
1.244 +#define TEST_CERT "server.pem"
1.245 +#undef PROG
1.246 +#define PROG s_server_main
1.247 +
1.248 +extern int verify_depth;
1.249 +
1.250 +static char *cipher=NULL;
1.251 +static int s_server_verify=SSL_VERIFY_NONE;
1.252 +static int s_server_session_id_context = 1; /* anything will do */
1.253 +static const char *s_cert_file=TEST_CERT,*s_key_file=NULL;
1.254 +static char *s_dcert_file=NULL,*s_dkey_file=NULL;
1.255 +#ifdef FIONBIO
1.256 +static int s_nbio=0;
1.257 +#endif
1.258 +static int s_nbio_test=0;
1.259 +int s_crlf=0;
1.260 +static SSL_CTX *ctx=NULL;
1.261 +static int www=0;
1.262 +
1.263 +static BIO *bio_s_out=NULL;
1.264 +static int s_debug=0;
1.265 +static int s_msg=0;
1.266 +static int s_quiet=0;
1.267 +
1.268 +static int hack=0;
1.269 +#ifndef OPENSSL_NO_ENGINE
1.270 +static char *engine_id=NULL;
1.271 +#endif
1.272 +static const char *session_id_prefix=NULL;
1.273 +
1.274 +static int enable_timeouts = 0;
1.275 +#ifdef mtu
1.276 +#undef mtu
1.277 +#endif
1.278 +static long mtu;
1.279 +static int cert_chain = 0;
1.280 +
1.281 +
1.282 +#ifdef MONOLITH
1.283 +static void s_server_init(void)
1.284 + {
1.285 + accept_socket=-1;
1.286 + cipher=NULL;
1.287 + s_server_verify=SSL_VERIFY_NONE;
1.288 + s_dcert_file=NULL;
1.289 + s_dkey_file=NULL;
1.290 + s_cert_file=TEST_CERT;
1.291 + s_key_file=NULL;
1.292 +#ifdef FIONBIO
1.293 + s_nbio=0;
1.294 +#endif
1.295 + s_nbio_test=0;
1.296 + ctx=NULL;
1.297 + www=0;
1.298 +
1.299 + bio_s_out=NULL;
1.300 + s_debug=0;
1.301 + s_msg=0;
1.302 + s_quiet=0;
1.303 + hack=0;
1.304 +#ifndef OPENSSL_NO_ENGINE
1.305 + engine_id=NULL;
1.306 +#endif
1.307 + }
1.308 +#endif
1.309 +
1.310 +static void sv_usage(void)
1.311 + {
1.312 + BIO_printf(bio_err,"usage: s_server [args ...]\n");
1.313 + BIO_printf(bio_err,"\n");
1.314 + BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT);
1.315 + BIO_printf(bio_err," -context arg - set session ID context\n");
1.316 + BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n");
1.317 + BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n");
1.318 + BIO_printf(bio_err," -cert arg - certificate file to use\n");
1.319 + BIO_printf(bio_err," (default is %s)\n",TEST_CERT);
1.320 + BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
1.321 + BIO_printf(bio_err," -key arg - Private Key file to use, in cert file if\n");
1.322 + BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT);
1.323 + BIO_printf(bio_err," -keyform arg - key format (PEM, DER or ENGINE) PEM default\n");
1.324 + BIO_printf(bio_err," -pass arg - private key file pass phrase source\n");
1.325 + BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n");
1.326 + BIO_printf(bio_err," -dcertform x - second certificate format (PEM or DER) PEM default\n");
1.327 + BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n");
1.328 + BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
1.329 + BIO_printf(bio_err," -dpass arg - second private key file pass phrase source\n");
1.330 + BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n");
1.331 + BIO_printf(bio_err," or a default set of parameters is used\n");
1.332 +#ifndef OPENSSL_NO_ECDH
1.333 + BIO_printf(bio_err," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \
1.334 + " Use \"openssl ecparam -list_curves\" for all names\n" \
1.335 + " (default is sect163r2).\n");
1.336 +#endif
1.337 +#ifdef FIONBIO
1.338 + BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
1.339 +#endif
1.340 + BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n");
1.341 + BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
1.342 + BIO_printf(bio_err," -debug - Print more output\n");
1.343 + BIO_printf(bio_err," -msg - Show protocol messages\n");
1.344 + BIO_printf(bio_err," -state - Print the SSL states\n");
1.345 + BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
1.346 + BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
1.347 + BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n");
1.348 + BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n");
1.349 + BIO_printf(bio_err," -serverpref - Use server's cipher preferences\n");
1.350 + BIO_printf(bio_err," -quiet - No server output\n");
1.351 + BIO_printf(bio_err," -no_tmp_rsa - Do not generate a tmp RSA key\n");
1.352 + BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
1.353 + BIO_printf(bio_err," -ssl3 - Just talk SSLv3\n");
1.354 + BIO_printf(bio_err," -tls1 - Just talk TLSv1\n");
1.355 + BIO_printf(bio_err," -dtls1 - Just talk DTLSv1\n");
1.356 + BIO_printf(bio_err," -timeout - Enable timeouts\n");
1.357 + BIO_printf(bio_err," -mtu - Set MTU\n");
1.358 + BIO_printf(bio_err," -chain - Read a certificate chain\n");
1.359 + BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
1.360 + BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
1.361 + BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
1.362 +#ifndef OPENSSL_NO_DH
1.363 + BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
1.364 +#endif
1.365 +#ifndef OPENSSL_NO_ECDH
1.366 + BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n");
1.367 +#endif
1.368 + BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n");
1.369 + BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n");
1.370 + BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
1.371 + BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
1.372 + BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n");
1.373 +#ifndef OPENSSL_NO_ENGINE
1.374 + BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
1.375 +#endif
1.376 + BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
1.377 + BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
1.378 + }
1.379 +
1.380 +static int local_argc=0;
1.381 +static char **local_argv;
1.382 +
1.383 +#ifdef CHARSET_EBCDIC
1.384 +static int ebcdic_new(BIO *bi);
1.385 +static int ebcdic_free(BIO *a);
1.386 +static int ebcdic_read(BIO *b, char *out, int outl);
1.387 +static int ebcdic_write(BIO *b, const char *in, int inl);
1.388 +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
1.389 +static int ebcdic_gets(BIO *bp, char *buf, int size);
1.390 +static int ebcdic_puts(BIO *bp, const char *str);
1.391 +
1.392 +#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
1.393 +static BIO_METHOD methods_ebcdic=
1.394 + {
1.395 + BIO_TYPE_EBCDIC_FILTER,
1.396 + "EBCDIC/ASCII filter",
1.397 + ebcdic_write,
1.398 + ebcdic_read,
1.399 + ebcdic_puts,
1.400 + ebcdic_gets,
1.401 + ebcdic_ctrl,
1.402 + ebcdic_new,
1.403 + ebcdic_free,
1.404 + };
1.405 +
1.406 +typedef struct
1.407 +{
1.408 + size_t alloced;
1.409 + char buff[1];
1.410 +} EBCDIC_OUTBUFF;
1.411 +
1.412 +BIO_METHOD *BIO_f_ebcdic_filter()
1.413 +{
1.414 + return(&methods_ebcdic);
1.415 +}
1.416 +
1.417 +static int ebcdic_new(BIO *bi)
1.418 +{
1.419 + EBCDIC_OUTBUFF *wbuf;
1.420 +
1.421 + wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
1.422 + wbuf->alloced = 1024;
1.423 + wbuf->buff[0] = '\0';
1.424 +
1.425 + bi->ptr=(char *)wbuf;
1.426 + bi->init=1;
1.427 + bi->flags=0;
1.428 + return(1);
1.429 +}
1.430 +
1.431 +static int ebcdic_free(BIO *a)
1.432 +{
1.433 + if (a == NULL) return(0);
1.434 + if (a->ptr != NULL)
1.435 + OPENSSL_free(a->ptr);
1.436 + a->ptr=NULL;
1.437 + a->init=0;
1.438 + a->flags=0;
1.439 + return(1);
1.440 +}
1.441 +
1.442 +static int ebcdic_read(BIO *b, char *out, int outl)
1.443 +{
1.444 + int ret=0;
1.445 +
1.446 + if (out == NULL || outl == 0) return(0);
1.447 + if (b->next_bio == NULL) return(0);
1.448 +
1.449 + ret=BIO_read(b->next_bio,out,outl);
1.450 + if (ret > 0)
1.451 + ascii2ebcdic(out,out,ret);
1.452 + return(ret);
1.453 +}
1.454 +
1.455 +static int ebcdic_write(BIO *b, const char *in, int inl)
1.456 +{
1.457 + EBCDIC_OUTBUFF *wbuf;
1.458 + int ret=0;
1.459 + int num;
1.460 + unsigned char n;
1.461 +
1.462 + if ((in == NULL) || (inl <= 0)) return(0);
1.463 + if (b->next_bio == NULL) return(0);
1.464 +
1.465 + wbuf=(EBCDIC_OUTBUFF *)b->ptr;
1.466 +
1.467 + if (inl > (num = wbuf->alloced))
1.468 + {
1.469 + num = num + num; /* double the size */
1.470 + if (num < inl)
1.471 + num = inl;
1.472 + OPENSSL_free(wbuf);
1.473 + wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
1.474 +
1.475 + wbuf->alloced = num;
1.476 + wbuf->buff[0] = '\0';
1.477 +
1.478 + b->ptr=(char *)wbuf;
1.479 + }
1.480 +
1.481 + ebcdic2ascii(wbuf->buff, in, inl);
1.482 +
1.483 + ret=BIO_write(b->next_bio, wbuf->buff, inl);
1.484 +
1.485 + return(ret);
1.486 +}
1.487 +
1.488 +static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
1.489 +{
1.490 + long ret;
1.491 +
1.492 + if (b->next_bio == NULL) return(0);
1.493 + switch (cmd)
1.494 + {
1.495 + case BIO_CTRL_DUP:
1.496 + ret=0L;
1.497 + break;
1.498 + default:
1.499 + ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
1.500 + break;
1.501 + }
1.502 + return(ret);
1.503 +}
1.504 +
1.505 +static int ebcdic_gets(BIO *bp, char *buf, int size)
1.506 +{
1.507 + int i, ret=0;
1.508 + if (bp->next_bio == NULL) return(0);
1.509 +/* return(BIO_gets(bp->next_bio,buf,size));*/
1.510 + for (i=0; i<size-1; ++i)
1.511 + {
1.512 + ret = ebcdic_read(bp,&buf[i],1);
1.513 + if (ret <= 0)
1.514 + break;
1.515 + else if (buf[i] == '\n')
1.516 + {
1.517 + ++i;
1.518 + break;
1.519 + }
1.520 + }
1.521 + if (i < size)
1.522 + buf[i] = '\0';
1.523 + return (ret < 0 && i == 0) ? ret : i;
1.524 +}
1.525 +
1.526 +static int ebcdic_puts(BIO *bp, const char *str)
1.527 +{
1.528 + if (bp->next_bio == NULL) return(0);
1.529 + return ebcdic_write(bp, str, strlen(str));
1.530 +}
1.531 +#endif
1.532 +
1.533 +int MAIN(int, char **);
1.534 +
1.535 +int MAIN(int argc, char *argv[])
1.536 + {
1.537 + X509_STORE *store = NULL;
1.538 + int vflags = 0;
1.539 + short port=PORT;
1.540 + char *CApath=NULL,*CAfile=NULL;
1.541 + unsigned char *context = NULL;
1.542 + char *dhfile = NULL;
1.543 +#ifndef OPENSSL_NO_ECDH
1.544 + char *named_curve = NULL;
1.545 +#endif
1.546 + int badop=0,bugs=0;
1.547 + int ret=1;
1.548 + int off=0;
1.549 + int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
1.550 + int state=0;
1.551 + SSL_METHOD *meth=NULL;
1.552 +#ifdef sock_type
1.553 +#undef sock_type
1.554 +#endif
1.555 + int sock_type=SOCK_STREAM;
1.556 +#ifndef OPENSSL_NO_ENGINE
1.557 + ENGINE *e=NULL;
1.558 +#endif
1.559 + char *inrand=NULL;
1.560 + int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
1.561 + char *passarg = NULL, *pass = NULL;
1.562 + char *dpassarg = NULL, *dpass = NULL;
1.563 + int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
1.564 + X509 *s_cert = NULL, *s_dcert = NULL;
1.565 + EVP_PKEY *s_key = NULL, *s_dkey = NULL;
1.566 +
1.567 +#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
1.568 + meth=SSLv23_server_method();
1.569 +#elif !defined(OPENSSL_NO_SSL3)
1.570 + meth=SSLv3_server_method();
1.571 +#elif !defined(OPENSSL_NO_SSL2)
1.572 + meth=SSLv2_server_method();
1.573 +#endif
1.574 +
1.575 + local_argc=argc;
1.576 + local_argv=argv;
1.577 +
1.578 + apps_startup();
1.579 +#ifdef MONOLITH
1.580 + s_server_init();
1.581 +#endif
1.582 +
1.583 + if (bio_err == NULL)
1.584 + bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
1.585 +
1.586 + if (!load_config(bio_err, NULL))
1.587 + goto end;
1.588 +
1.589 + verify_depth=0;
1.590 +#ifdef FIONBIO
1.591 + s_nbio=0;
1.592 +#endif
1.593 + s_nbio_test=0;
1.594 +
1.595 + argc--;
1.596 + argv++;
1.597 +
1.598 + while (argc >= 1)
1.599 + {
1.600 + if ((strcmp(*argv,"-port") == 0) ||
1.601 + (strcmp(*argv,"-accept") == 0))
1.602 + {
1.603 + if (--argc < 1) goto bad;
1.604 + if (!extract_port(*(++argv),&port))
1.605 + goto bad;
1.606 + }
1.607 + else if (strcmp(*argv,"-verify") == 0)
1.608 + {
1.609 + s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE;
1.610 + if (--argc < 1) goto bad;
1.611 + verify_depth=atoi(*(++argv));
1.612 + BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
1.613 + }
1.614 + else if (strcmp(*argv,"-Verify") == 0)
1.615 + {
1.616 + s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|
1.617 + SSL_VERIFY_CLIENT_ONCE;
1.618 + if (--argc < 1) goto bad;
1.619 + verify_depth=atoi(*(++argv));
1.620 + BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth);
1.621 + }
1.622 + else if (strcmp(*argv,"-context") == 0)
1.623 + {
1.624 + if (--argc < 1) goto bad;
1.625 + context= (unsigned char *)*(++argv);
1.626 + }
1.627 + else if (strcmp(*argv,"-cert") == 0)
1.628 + {
1.629 + if (--argc < 1) goto bad;
1.630 + s_cert_file= *(++argv);
1.631 + }
1.632 + else if (strcmp(*argv,"-certform") == 0)
1.633 + {
1.634 + if (--argc < 1) goto bad;
1.635 + s_cert_format = str2fmt(*(++argv));
1.636 + }
1.637 + else if (strcmp(*argv,"-key") == 0)
1.638 + {
1.639 + if (--argc < 1) goto bad;
1.640 + s_key_file= *(++argv);
1.641 + }
1.642 + else if (strcmp(*argv,"-keyform") == 0)
1.643 + {
1.644 + if (--argc < 1) goto bad;
1.645 + s_key_format = str2fmt(*(++argv));
1.646 + }
1.647 + else if (strcmp(*argv,"-pass") == 0)
1.648 + {
1.649 + if (--argc < 1) goto bad;
1.650 + passarg = *(++argv);
1.651 + }
1.652 + else if (strcmp(*argv,"-dhparam") == 0)
1.653 + {
1.654 + if (--argc < 1) goto bad;
1.655 + dhfile = *(++argv);
1.656 + }
1.657 +#ifndef OPENSSL_NO_ECDH
1.658 + else if (strcmp(*argv,"-named_curve") == 0)
1.659 + {
1.660 + if (--argc < 1) goto bad;
1.661 + named_curve = *(++argv);
1.662 + }
1.663 +#endif
1.664 + else if (strcmp(*argv,"-dcertform") == 0)
1.665 + {
1.666 + if (--argc < 1) goto bad;
1.667 + s_dcert_format = str2fmt(*(++argv));
1.668 + }
1.669 + else if (strcmp(*argv,"-dcert") == 0)
1.670 + {
1.671 + if (--argc < 1) goto bad;
1.672 + s_dcert_file= *(++argv);
1.673 + }
1.674 + else if (strcmp(*argv,"-dkeyform") == 0)
1.675 + {
1.676 + if (--argc < 1) goto bad;
1.677 + s_dkey_format = str2fmt(*(++argv));
1.678 + }
1.679 + else if (strcmp(*argv,"-dpass") == 0)
1.680 + {
1.681 + if (--argc < 1) goto bad;
1.682 + dpassarg = *(++argv);
1.683 + }
1.684 + else if (strcmp(*argv,"-dkey") == 0)
1.685 + {
1.686 + if (--argc < 1) goto bad;
1.687 + s_dkey_file= *(++argv);
1.688 + }
1.689 + else if (strcmp(*argv,"-nocert") == 0)
1.690 + {
1.691 + nocert=1;
1.692 + }
1.693 + else if (strcmp(*argv,"-CApath") == 0)
1.694 + {
1.695 + if (--argc < 1) goto bad;
1.696 + CApath= *(++argv);
1.697 + }
1.698 + else if (strcmp(*argv,"-crl_check") == 0)
1.699 + {
1.700 + vflags |= X509_V_FLAG_CRL_CHECK;
1.701 + }
1.702 + else if (strcmp(*argv,"-crl_check") == 0)
1.703 + {
1.704 + vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
1.705 + }
1.706 + else if (strcmp(*argv,"-serverpref") == 0)
1.707 + { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
1.708 + else if (strcmp(*argv,"-cipher") == 0)
1.709 + {
1.710 + if (--argc < 1) goto bad;
1.711 + cipher= *(++argv);
1.712 + }
1.713 + else if (strcmp(*argv,"-CAfile") == 0)
1.714 + {
1.715 + if (--argc < 1) goto bad;
1.716 + CAfile= *(++argv);
1.717 + }
1.718 +#ifdef FIONBIO
1.719 + else if (strcmp(*argv,"-nbio") == 0)
1.720 + { s_nbio=1; }
1.721 +#endif
1.722 + else if (strcmp(*argv,"-nbio_test") == 0)
1.723 + {
1.724 +#ifdef FIONBIO
1.725 + s_nbio=1;
1.726 +#endif
1.727 + s_nbio_test=1;
1.728 + }
1.729 + else if (strcmp(*argv,"-debug") == 0)
1.730 + { s_debug=1; }
1.731 + else if (strcmp(*argv,"-msg") == 0)
1.732 + { s_msg=1; }
1.733 + else if (strcmp(*argv,"-hack") == 0)
1.734 + { hack=1; }
1.735 + else if (strcmp(*argv,"-state") == 0)
1.736 + { state=1; }
1.737 + else if (strcmp(*argv,"-crlf") == 0)
1.738 + { s_crlf=1; }
1.739 + else if (strcmp(*argv,"-quiet") == 0)
1.740 + { s_quiet=1; }
1.741 + else if (strcmp(*argv,"-bugs") == 0)
1.742 + { bugs=1; }
1.743 + else if (strcmp(*argv,"-no_tmp_rsa") == 0)
1.744 + { no_tmp_rsa=1; }
1.745 + else if (strcmp(*argv,"-no_dhe") == 0)
1.746 + { no_dhe=1; }
1.747 + else if (strcmp(*argv,"-no_ecdhe") == 0)
1.748 + { no_ecdhe=1; }
1.749 + else if (strcmp(*argv,"-www") == 0)
1.750 + { www=1; }
1.751 + else if (strcmp(*argv,"-WWW") == 0)
1.752 + { www=2; }
1.753 + else if (strcmp(*argv,"-HTTP") == 0)
1.754 + { www=3; }
1.755 + else if (strcmp(*argv,"-no_ssl2") == 0)
1.756 + { off|=SSL_OP_NO_SSLv2; }
1.757 + else if (strcmp(*argv,"-no_ssl3") == 0)
1.758 + { off|=SSL_OP_NO_SSLv3; }
1.759 + else if (strcmp(*argv,"-no_tls1") == 0)
1.760 + { off|=SSL_OP_NO_TLSv1; }
1.761 +#ifndef OPENSSL_NO_SSL2
1.762 + else if (strcmp(*argv,"-ssl2") == 0)
1.763 + { meth=SSLv2_server_method(); }
1.764 +#endif
1.765 +#ifndef OPENSSL_NO_SSL3
1.766 + else if (strcmp(*argv,"-ssl3") == 0)
1.767 + { meth=SSLv3_server_method(); }
1.768 +#endif
1.769 +#ifndef OPENSSL_NO_TLS1
1.770 + else if (strcmp(*argv,"-tls1") == 0)
1.771 + { meth=TLSv1_server_method(); }
1.772 +#endif
1.773 +#ifndef OPENSSL_NO_DTLS1
1.774 + else if (strcmp(*argv,"-dtls1") == 0)
1.775 + {
1.776 + meth=DTLSv1_server_method();
1.777 + sock_type = SOCK_DGRAM;
1.778 + }
1.779 + else if (strcmp(*argv,"-timeout") == 0)
1.780 + enable_timeouts = 1;
1.781 + else if (strcmp(*argv,"-mtu") == 0)
1.782 + {
1.783 + if (--argc < 1) goto bad;
1.784 + mtu = atol(*(++argv));
1.785 + }
1.786 + else if (strcmp(*argv, "-chain") == 0)
1.787 + cert_chain = 1;
1.788 +#endif
1.789 + else if (strcmp(*argv, "-id_prefix") == 0)
1.790 + {
1.791 + if (--argc < 1) goto bad;
1.792 + session_id_prefix = *(++argv);
1.793 + }
1.794 +#ifndef OPENSSL_NO_ENGINE
1.795 + else if (strcmp(*argv,"-engine") == 0)
1.796 + {
1.797 + if (--argc < 1) goto bad;
1.798 + engine_id= *(++argv);
1.799 + }
1.800 +#endif
1.801 + else if (strcmp(*argv,"-rand") == 0)
1.802 + {
1.803 + if (--argc < 1) goto bad;
1.804 + inrand= *(++argv);
1.805 + }
1.806 + else
1.807 + {
1.808 + BIO_printf(bio_err,"unknown option %s\n",*argv);
1.809 + badop=1;
1.810 + break;
1.811 + }
1.812 + argc--;
1.813 + argv++;
1.814 + }
1.815 + if (badop)
1.816 + {
1.817 +bad:
1.818 + sv_usage();
1.819 + goto end;
1.820 + }
1.821 +
1.822 + SSL_load_error_strings();
1.823 + OpenSSL_add_ssl_algorithms();
1.824 +
1.825 +#ifndef OPENSSL_NO_ENGINE
1.826 + e = setup_engine(bio_err, engine_id, 1);
1.827 +#endif
1.828 +
1.829 + if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
1.830 + {
1.831 + BIO_printf(bio_err, "Error getting password\n");
1.832 + goto end;
1.833 + }
1.834 +
1.835 +
1.836 + if (s_key_file == NULL)
1.837 + s_key_file = s_cert_file;
1.838 +
1.839 + if (nocert == 0)
1.840 + {
1.841 + s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
1.842 + "server certificate private key file");
1.843 + if (!s_key)
1.844 + {
1.845 + ERR_print_errors(bio_err);
1.846 + goto end;
1.847 + }
1.848 +
1.849 + s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
1.850 + NULL, e, "server certificate file");
1.851 +
1.852 + if (!s_cert)
1.853 + {
1.854 + ERR_print_errors(bio_err);
1.855 + goto end;
1.856 + }
1.857 + }
1.858 +
1.859 + if (s_dcert_file)
1.860 + {
1.861 +
1.862 + if (s_dkey_file == NULL)
1.863 + s_dkey_file = s_dcert_file;
1.864 +
1.865 + s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
1.866 + 0, dpass, e,
1.867 + "second certificate private key file");
1.868 + if (!s_dkey)
1.869 + {
1.870 + ERR_print_errors(bio_err);
1.871 + goto end;
1.872 + }
1.873 +
1.874 + s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
1.875 + NULL, e, "second server certificate file");
1.876 +
1.877 + if (!s_dcert)
1.878 + {
1.879 + ERR_print_errors(bio_err);
1.880 + goto end;
1.881 + }
1.882 +
1.883 + }
1.884 +
1.885 + if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
1.886 + && !RAND_status())
1.887 + {
1.888 + BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
1.889 + }
1.890 + if (inrand != NULL)
1.891 + BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
1.892 + app_RAND_load_files(inrand));
1.893 +
1.894 + if (bio_s_out == NULL)
1.895 + {
1.896 + if (s_quiet && !s_debug && !s_msg)
1.897 + {
1.898 + bio_s_out=BIO_new(BIO_s_null());
1.899 + }
1.900 + else
1.901 + {
1.902 + if (bio_s_out == NULL)
1.903 + bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE);
1.904 +
1.905 + }
1.906 + }
1.907 +
1.908 +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
1.909 + if (nocert)
1.910 +#endif
1.911 + {
1.912 + s_cert_file=NULL;
1.913 + s_key_file=NULL;
1.914 + s_dcert_file=NULL;
1.915 + s_dkey_file=NULL;
1.916 + }
1.917 +
1.918 + ctx=SSL_CTX_new(meth);
1.919 + if (ctx == NULL)
1.920 + {
1.921 + ERR_print_errors(bio_err);
1.922 + goto end;
1.923 + }
1.924 + if (session_id_prefix)
1.925 + {
1.926 + if(strlen(session_id_prefix) >= 32)
1.927 + BIO_printf(bio_err,
1.928 +"warning: id_prefix is too long, only one new session will be possible\n");
1.929 + else if(strlen(session_id_prefix) >= 16)
1.930 + BIO_printf(bio_err,
1.931 +"warning: id_prefix is too long if you use SSLv2\n");
1.932 + if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
1.933 + {
1.934 + BIO_printf(bio_err,"error setting 'id_prefix'\n");
1.935 + ERR_print_errors(bio_err);
1.936 + goto end;
1.937 + }
1.938 + BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
1.939 + }
1.940 + SSL_CTX_set_quiet_shutdown(ctx,1);
1.941 + if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
1.942 + if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
1.943 + SSL_CTX_set_options(ctx,off);
1.944 + /* DTLS: partial reads end up discarding unread UDP bytes :-(
1.945 + * Setting read ahead solves this problem.
1.946 + */
1.947 + if (sock_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
1.948 +
1.949 + if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
1.950 +
1.951 + SSL_CTX_sess_set_cache_size(ctx,128);
1.952 +
1.953 +#if 0
1.954 + if (cipher == NULL) cipher=getenv("SSL_CIPHER");
1.955 +#endif
1.956 +
1.957 +#if 0
1.958 + if (s_cert_file == NULL)
1.959 + {
1.960 + BIO_printf(bio_err,"You must specify a certificate file for the server to use\n");
1.961 + goto end;
1.962 + }
1.963 +#endif
1.964 +
1.965 + if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
1.966 + (!SSL_CTX_set_default_verify_paths(ctx)))
1.967 + {
1.968 + /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
1.969 + ERR_print_errors(bio_err);
1.970 + /* goto end; */
1.971 + }
1.972 + store = SSL_CTX_get_cert_store(ctx);
1.973 + X509_STORE_set_flags(store, vflags);
1.974 +
1.975 +#ifndef OPENSSL_NO_DH
1.976 + if (!no_dhe)
1.977 + {
1.978 + DH *dh=NULL;
1.979 +
1.980 + if (dhfile)
1.981 + dh = load_dh_param(dhfile);
1.982 + else if (s_cert_file)
1.983 + dh = load_dh_param(s_cert_file);
1.984 +
1.985 + if (dh != NULL)
1.986 + {
1.987 + BIO_printf(bio_s_out,"Setting temp DH parameters\n");
1.988 + }
1.989 + else
1.990 + {
1.991 + BIO_printf(bio_s_out,"Using default temp DH parameters\n");
1.992 + dh=get_dh512();
1.993 + }
1.994 + (void)BIO_flush(bio_s_out);
1.995 +
1.996 + SSL_CTX_set_tmp_dh(ctx,dh);
1.997 + DH_free(dh);
1.998 + }
1.999 +#endif
1.1000 +
1.1001 +#ifndef OPENSSL_NO_ECDH
1.1002 + if (!no_ecdhe)
1.1003 + {
1.1004 + EC_KEY *ecdh=NULL;
1.1005 +
1.1006 + if (named_curve)
1.1007 + {
1.1008 + int nid = OBJ_sn2nid(named_curve);
1.1009 +
1.1010 + if (nid == 0)
1.1011 + {
1.1012 + BIO_printf(bio_err, "unknown curve name (%s)\n",
1.1013 + named_curve);
1.1014 + goto end;
1.1015 + }
1.1016 + ecdh = EC_KEY_new_by_curve_name(nid);
1.1017 + if (ecdh == NULL)
1.1018 + {
1.1019 + BIO_printf(bio_err, "unable to create curve (%s)\n",
1.1020 + named_curve);
1.1021 + goto end;
1.1022 + }
1.1023 + }
1.1024 +
1.1025 + if (ecdh != NULL)
1.1026 + {
1.1027 + BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
1.1028 + }
1.1029 + else
1.1030 + {
1.1031 + BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
1.1032 + ecdh = EC_KEY_new_by_curve_name(NID_sect163r2);
1.1033 + if (ecdh == NULL)
1.1034 + {
1.1035 + BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
1.1036 + goto end;
1.1037 + }
1.1038 + }
1.1039 + (void)BIO_flush(bio_s_out);
1.1040 +
1.1041 + SSL_CTX_set_tmp_ecdh(ctx,ecdh);
1.1042 + EC_KEY_free(ecdh);
1.1043 + }
1.1044 +#endif
1.1045 +
1.1046 + if (!set_cert_key_stuff(ctx,s_cert,s_key))
1.1047 + goto end;
1.1048 + if (s_dcert != NULL)
1.1049 + {
1.1050 + if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
1.1051 + goto end;
1.1052 + }
1.1053 +
1.1054 +#ifndef OPENSSL_NO_RSA
1.1055 +#if 1
1.1056 + if (!no_tmp_rsa)
1.1057 + SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
1.1058 +#else
1.1059 + if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
1.1060 + {
1.1061 + RSA *rsa;
1.1062 +
1.1063 + BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key...");
1.1064 + BIO_flush(bio_s_out);
1.1065 +
1.1066 + rsa=RSA_generate_key(512,RSA_F4,NULL);
1.1067 +
1.1068 + if (!SSL_CTX_set_tmp_rsa(ctx,rsa))
1.1069 + {
1.1070 + ERR_print_errors(bio_err);
1.1071 + goto end;
1.1072 + }
1.1073 + RSA_free(rsa);
1.1074 + BIO_printf(bio_s_out,"\n");
1.1075 + }
1.1076 +#endif
1.1077 +#endif
1.1078 +
1.1079 + if (cipher != NULL)
1.1080 + if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
1.1081 + BIO_printf(bio_err,"error setting cipher list\n");
1.1082 + ERR_print_errors(bio_err);
1.1083 + goto end;
1.1084 + }
1.1085 + SSL_CTX_set_verify(ctx,s_server_verify,verify_callback);
1.1086 + SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,
1.1087 + sizeof s_server_session_id_context);
1.1088 +
1.1089 + if (CAfile != NULL)
1.1090 + SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
1.1091 +
1.1092 + BIO_printf(bio_s_out,"ACCEPT\n");
1.1093 + if (www)
1.1094 + do_server(port,sock_type,&accept_socket,www_body, context);
1.1095 + else
1.1096 + do_server(port,sock_type,&accept_socket,sv_body, context);
1.1097 + print_stats(bio_s_out,ctx);
1.1098 + ret=0;
1.1099 +end:
1.1100 + if (ctx != NULL) SSL_CTX_free(ctx);
1.1101 + if (s_cert)
1.1102 + X509_free(s_cert);
1.1103 + if (s_dcert)
1.1104 + X509_free(s_dcert);
1.1105 + if (s_key)
1.1106 + EVP_PKEY_free(s_key);
1.1107 + if (s_dkey)
1.1108 + EVP_PKEY_free(s_dkey);
1.1109 + if (pass)
1.1110 + OPENSSL_free(pass);
1.1111 + if (dpass)
1.1112 + OPENSSL_free(dpass);
1.1113 + if (bio_s_out != NULL)
1.1114 + {
1.1115 + BIO_free(bio_s_out);
1.1116 + bio_s_out=NULL;
1.1117 + }
1.1118 + apps_shutdown();
1.1119 + OPENSSL_EXIT(ret);
1.1120 + }
1.1121 +
1.1122 +static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
1.1123 + {
1.1124 + BIO_printf(bio,"%4ld items in the session cache\n",
1.1125 + SSL_CTX_sess_number(ssl_ctx));
1.1126 + BIO_printf(bio,"%4ld client connects (SSL_connect())\n",
1.1127 + SSL_CTX_sess_connect(ssl_ctx));
1.1128 + BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
1.1129 + SSL_CTX_sess_connect_renegotiate(ssl_ctx));
1.1130 + BIO_printf(bio,"%4ld client connects that finished\n",
1.1131 + SSL_CTX_sess_connect_good(ssl_ctx));
1.1132 + BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
1.1133 + SSL_CTX_sess_accept(ssl_ctx));
1.1134 + BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
1.1135 + SSL_CTX_sess_accept_renegotiate(ssl_ctx));
1.1136 + BIO_printf(bio,"%4ld server accepts that finished\n",
1.1137 + SSL_CTX_sess_accept_good(ssl_ctx));
1.1138 + BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
1.1139 + BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
1.1140 + BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
1.1141 + BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
1.1142 + BIO_printf(bio,"%4ld cache full overflows (%ld allowed)\n",
1.1143 + SSL_CTX_sess_cache_full(ssl_ctx),
1.1144 + SSL_CTX_sess_get_cache_size(ssl_ctx));
1.1145 + }
1.1146 +
1.1147 +static int sv_body(char *hostname, int s, unsigned char *context)
1.1148 + {
1.1149 + char *buf=NULL;
1.1150 + fd_set readfds;
1.1151 + int ret=1,width;
1.1152 + int k,i;
1.1153 + unsigned long l;
1.1154 + SSL *con=NULL;
1.1155 + BIO *sbio;
1.1156 +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
1.1157 + struct timeval tv;
1.1158 +#endif
1.1159 +
1.1160 + if ((buf=OPENSSL_malloc(bufsize)) == NULL)
1.1161 + {
1.1162 + BIO_printf(bio_err,"out of memory\n");
1.1163 + goto err;
1.1164 + }
1.1165 +#ifdef FIONBIO
1.1166 + if (s_nbio)
1.1167 + {
1.1168 + unsigned long sl=1;
1.1169 +
1.1170 + if (!s_quiet)
1.1171 + BIO_printf(bio_err,"turning on non blocking io\n");
1.1172 + if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
1.1173 + ERR_print_errors(bio_err);
1.1174 + }
1.1175 +#endif
1.1176 +
1.1177 + if (con == NULL) {
1.1178 + con=SSL_new(ctx);
1.1179 +#ifndef OPENSSL_NO_KRB5
1.1180 + if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
1.1181 + {
1.1182 + kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
1.1183 + KRB5SVC);
1.1184 + kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
1.1185 + KRB5KEYTAB);
1.1186 + }
1.1187 +#endif /* OPENSSL_NO_KRB5 */
1.1188 + if(context)
1.1189 + SSL_set_session_id_context(con, context,
1.1190 + strlen((char *)context));
1.1191 + }
1.1192 + SSL_clear(con);
1.1193 +
1.1194 + if (SSL_version(con) == DTLS1_VERSION)
1.1195 + {
1.1196 + struct timeval timeout;
1.1197 +
1.1198 + sbio=BIO_new_dgram(s,BIO_NOCLOSE);
1.1199 +
1.1200 + if ( enable_timeouts)
1.1201 + {
1.1202 + timeout.tv_sec = 0;
1.1203 + timeout.tv_usec = DGRAM_RCV_TIMEOUT;
1.1204 + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
1.1205 +
1.1206 + timeout.tv_sec = 0;
1.1207 + timeout.tv_usec = DGRAM_SND_TIMEOUT;
1.1208 + BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
1.1209 + }
1.1210 +
1.1211 +
1.1212 + if ( mtu > 0)
1.1213 + {
1.1214 + SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
1.1215 + SSL_set_mtu(con, mtu);
1.1216 + }
1.1217 + else
1.1218 + /* want to do MTU discovery */
1.1219 + BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
1.1220 +
1.1221 + /* turn on cookie exchange */
1.1222 + SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
1.1223 + }
1.1224 + else
1.1225 + sbio=BIO_new_socket(s,BIO_NOCLOSE);
1.1226 +
1.1227 + if (s_nbio_test)
1.1228 + {
1.1229 + BIO *test;
1.1230 +
1.1231 + test=BIO_new(BIO_f_nbio_test());
1.1232 + sbio=BIO_push(test,sbio);
1.1233 + }
1.1234 + SSL_set_bio(con,sbio,sbio);
1.1235 + SSL_set_accept_state(con);
1.1236 + /* SSL_set_fd(con,s); */
1.1237 +
1.1238 + if (s_debug)
1.1239 + {
1.1240 + con->debug=1;
1.1241 + BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
1.1242 + BIO_set_callback_arg(SSL_get_rbio(con),(char*)bio_s_out);
1.1243 + }
1.1244 + if (s_msg)
1.1245 + {
1.1246 + SSL_set_msg_callback(con, msg_cb);
1.1247 + SSL_set_msg_callback_arg(con, bio_s_out);
1.1248 + }
1.1249 +
1.1250 + width=s+1;
1.1251 + for (;;)
1.1252 + {
1.1253 + int read_from_terminal;
1.1254 + int read_from_sslcon;
1.1255 +
1.1256 + read_from_terminal = 0;
1.1257 + read_from_sslcon = SSL_pending(con);
1.1258 +
1.1259 + if (!read_from_sslcon)
1.1260 + {
1.1261 + FD_ZERO(&readfds);
1.1262 +#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
1.1263 + FD_SET(fileno(stdin),&readfds);
1.1264 +
1.1265 +#endif
1.1266 + FD_SET(s,&readfds);
1.1267 + /* Note: under VMS with SOCKETSHR the second parameter is
1.1268 + * currently of type (int *) whereas under other systems
1.1269 + * it is (void *) if you don't have a cast it will choke
1.1270 + * the compiler: if you do have a cast then you can either
1.1271 + * go for (int *) or (void *).
1.1272 + */
1.1273 +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
1.1274 + /* Under DOS (non-djgpp) and Windows we can't select on stdin: only
1.1275 + * on sockets. As a workaround we timeout the select every
1.1276 + * second and check for any keypress. In a proper Windows
1.1277 + * application we wouldn't do this because it is inefficient.
1.1278 + */
1.1279 + tv.tv_sec = 1;
1.1280 + tv.tv_usec = 0;
1.1281 + i=select(width,(void *)&readfds,NULL,NULL,&tv);
1.1282 + if((i < 0) || (!i && !_kbhit() ) )continue;
1.1283 + if(_kbhit())
1.1284 + read_from_terminal = 1;
1.1285 +#else
1.1286 + i=select(width,(void *)&readfds,NULL,NULL,NULL);
1.1287 + if (i <= 0) continue;
1.1288 + if (FD_ISSET(fileno(stdin),&readfds))
1.1289 +
1.1290 + read_from_terminal = 1;
1.1291 +#endif
1.1292 + if (FD_ISSET(s,&readfds))
1.1293 + read_from_sslcon = 1;
1.1294 + }
1.1295 + if (read_from_terminal)
1.1296 + {
1.1297 + if (s_crlf)
1.1298 + {
1.1299 + int j, lf_num;
1.1300 + i=read(fileno(stdin), buf, bufsize/2);
1.1301 + lf_num = 0;
1.1302 + /* both loops are skipped when i <= 0 */
1.1303 + for (j = 0; j < i; j++)
1.1304 + if (buf[j] == '\n')
1.1305 + lf_num++;
1.1306 + for (j = i-1; j >= 0; j--)
1.1307 + {
1.1308 + buf[j+lf_num] = buf[j];
1.1309 + if (buf[j] == '\n')
1.1310 + {
1.1311 + lf_num--;
1.1312 + i++;
1.1313 + buf[j+lf_num] = '\r';
1.1314 + }
1.1315 + }
1.1316 + assert(lf_num == 0);
1.1317 + }
1.1318 + else
1.1319 + i=read(fileno(stdin),buf,bufsize);
1.1320 +
1.1321 + if (!s_quiet)
1.1322 + {
1.1323 + if ((i <= 0) || (buf[0] == 'Q'))
1.1324 + {
1.1325 + BIO_printf(bio_s_out,"DONE\n");
1.1326 + SHUTDOWN(s);
1.1327 + close_accept_socket();
1.1328 + ret= -11;
1.1329 + goto err;
1.1330 + }
1.1331 + if ((i <= 0) || (buf[0] == 'q'))
1.1332 + {
1.1333 + BIO_printf(bio_s_out,"DONE\n");
1.1334 + if (SSL_version(con) != DTLS1_VERSION)
1.1335 + SHUTDOWN(s);
1.1336 + /* close_accept_socket();
1.1337 + ret= -11;*/
1.1338 + goto err;
1.1339 + }
1.1340 + if ((buf[0] == 'r') &&
1.1341 + ((buf[1] == '\n') || (buf[1] == '\r')))
1.1342 + {
1.1343 + SSL_renegotiate(con);
1.1344 + i=SSL_do_handshake(con);
1.1345 + printf("SSL_do_handshake -> %d\n",i);
1.1346 +
1.1347 + i=0; /*13; */
1.1348 + continue;
1.1349 + /* strcpy(buf,"server side RE-NEGOTIATE\n"); */
1.1350 + }
1.1351 + if ((buf[0] == 'R') &&
1.1352 + ((buf[1] == '\n') || (buf[1] == '\r')))
1.1353 + {
1.1354 + SSL_set_verify(con,
1.1355 + SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL);
1.1356 + SSL_renegotiate(con);
1.1357 + i=SSL_do_handshake(con);
1.1358 + printf("SSL_do_handshake -> %d\n",i);
1.1359 +
1.1360 + i=0; /* 13; */
1.1361 + continue;
1.1362 + /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */
1.1363 + }
1.1364 + if (buf[0] == 'P')
1.1365 + {
1.1366 + static const char *str="Lets print some clear text\n";
1.1367 + BIO_write(SSL_get_wbio(con),str,strlen(str));
1.1368 + }
1.1369 + if (buf[0] == 'S')
1.1370 + {
1.1371 + print_stats(bio_s_out,SSL_get_SSL_CTX(con));
1.1372 + }
1.1373 + }
1.1374 +#ifdef CHARSET_EBCDIC
1.1375 + ebcdic2ascii(buf,buf,i);
1.1376 +#endif
1.1377 + l=k=0;
1.1378 + for (;;)
1.1379 + {
1.1380 + /* should do a select for the write */
1.1381 +#ifdef RENEG
1.1382 +{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
1.1383 +#endif
1.1384 + k=SSL_write(con,&(buf[l]),(unsigned int)i);
1.1385 + switch (SSL_get_error(con,k))
1.1386 + {
1.1387 + case SSL_ERROR_NONE:
1.1388 + break;
1.1389 + case SSL_ERROR_WANT_WRITE:
1.1390 + case SSL_ERROR_WANT_READ:
1.1391 + case SSL_ERROR_WANT_X509_LOOKUP:
1.1392 + BIO_printf(bio_s_out,"Write BLOCK\n");
1.1393 + break;
1.1394 + case SSL_ERROR_SYSCALL:
1.1395 + case SSL_ERROR_SSL:
1.1396 + BIO_printf(bio_s_out,"ERROR\n");
1.1397 + ERR_print_errors(bio_err);
1.1398 + ret=1;
1.1399 + goto err;
1.1400 + /* break; */
1.1401 + case SSL_ERROR_ZERO_RETURN:
1.1402 + BIO_printf(bio_s_out,"DONE\n");
1.1403 + ret=1;
1.1404 + goto err;
1.1405 + }
1.1406 + l+=k;
1.1407 + i-=k;
1.1408 + if (i <= 0) break;
1.1409 + }
1.1410 + }
1.1411 + if (read_from_sslcon)
1.1412 + {
1.1413 + if (!SSL_is_init_finished(con))
1.1414 + {
1.1415 + i=init_ssl_connection(con);
1.1416 +
1.1417 + if (i < 0)
1.1418 + {
1.1419 + ret=0;
1.1420 + goto err;
1.1421 + }
1.1422 + else if (i == 0)
1.1423 + {
1.1424 + ret=1;
1.1425 + goto err;
1.1426 + }
1.1427 + }
1.1428 + else
1.1429 + {
1.1430 +again:
1.1431 + i=SSL_read(con,(char *)buf,bufsize);
1.1432 + switch (SSL_get_error(con,i))
1.1433 + {
1.1434 + case SSL_ERROR_NONE:
1.1435 +#ifdef CHARSET_EBCDIC
1.1436 + ascii2ebcdic(buf,buf,i);
1.1437 +#endif
1.1438 + write(fileno(stdout),buf,
1.1439 + (unsigned int)i);
1.1440 +
1.1441 + if (SSL_pending(con)) goto again;
1.1442 + break;
1.1443 + case SSL_ERROR_WANT_WRITE:
1.1444 + case SSL_ERROR_WANT_READ:
1.1445 + case SSL_ERROR_WANT_X509_LOOKUP:
1.1446 + BIO_printf(bio_s_out,"Read BLOCK\n");
1.1447 + break;
1.1448 + case SSL_ERROR_SYSCALL:
1.1449 + case SSL_ERROR_SSL:
1.1450 + BIO_printf(bio_s_out,"ERROR\n");
1.1451 + ERR_print_errors(bio_err);
1.1452 + ret=1;
1.1453 + goto err;
1.1454 + case SSL_ERROR_ZERO_RETURN:
1.1455 + BIO_printf(bio_s_out,"DONE\n");
1.1456 + ret=1;
1.1457 + goto err;
1.1458 + }
1.1459 + }
1.1460 + }
1.1461 + }
1.1462 +err:
1.1463 + BIO_printf(bio_s_out,"shutting down SSL\n");
1.1464 +#if 1
1.1465 + SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1.1466 +#else
1.1467 + SSL_shutdown(con);
1.1468 +#endif
1.1469 + if (con != NULL) SSL_free(con);
1.1470 + BIO_printf(bio_s_out,"CONNECTION CLOSED\n");
1.1471 + if (buf != NULL)
1.1472 + {
1.1473 + OPENSSL_cleanse(buf,bufsize);
1.1474 + OPENSSL_free(buf);
1.1475 + }
1.1476 + if (ret >= 0)
1.1477 + BIO_printf(bio_s_out,"ACCEPT\n");
1.1478 + return(ret);
1.1479 + }
1.1480 +
1.1481 +static void close_accept_socket(void)
1.1482 + {
1.1483 + BIO_printf(bio_err,"shutdown accept socket\n");
1.1484 + if (accept_socket >= 0)
1.1485 + {
1.1486 + SHUTDOWN2(accept_socket);
1.1487 + }
1.1488 + }
1.1489 +
1.1490 +static int init_ssl_connection(SSL *con)
1.1491 + {
1.1492 + int i;
1.1493 + const char *str;
1.1494 + X509 *peer;
1.1495 + long verify_error;
1.1496 + MS_STATIC char buf[BUFSIZ];
1.1497 +
1.1498 + if ((i=SSL_accept(con)) <= 0)
1.1499 + {
1.1500 + if (BIO_sock_should_retry(i))
1.1501 + {
1.1502 + BIO_printf(bio_s_out,"DELAY\n");
1.1503 + return(1);
1.1504 + }
1.1505 +
1.1506 + BIO_printf(bio_err,"ERROR\n");
1.1507 + verify_error=SSL_get_verify_result(con);
1.1508 + if (verify_error != X509_V_OK)
1.1509 + {
1.1510 + BIO_printf(bio_err,"verify error:%s\n",
1.1511 + X509_verify_cert_error_string(verify_error));
1.1512 + }
1.1513 + else
1.1514 + ERR_print_errors(bio_err);
1.1515 + return(0);
1.1516 + }
1.1517 +
1.1518 + PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con));
1.1519 +
1.1520 + peer=SSL_get_peer_certificate(con);
1.1521 + if (peer != NULL)
1.1522 + {
1.1523 + BIO_printf(bio_s_out,"Client certificate\n");
1.1524 + PEM_write_bio_X509(bio_s_out,peer);
1.1525 + X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
1.1526 + BIO_printf(bio_s_out,"subject=%s\n",buf);
1.1527 + X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
1.1528 + BIO_printf(bio_s_out,"issuer=%s\n",buf);
1.1529 + X509_free(peer);
1.1530 + }
1.1531 +
1.1532 + if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
1.1533 + BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
1.1534 + str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1.1535 + BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
1.1536 + if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n");
1.1537 + if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
1.1538 + TLS1_FLAGS_TLS_PADDING_BUG)
1.1539 + BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
1.1540 +#ifndef OPENSSL_NO_KRB5
1.1541 + if (con->kssl_ctx->client_princ != NULL)
1.1542 + {
1.1543 + BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
1.1544 + con->kssl_ctx->client_princ);
1.1545 + }
1.1546 +#endif /* OPENSSL_NO_KRB5 */
1.1547 + return(1);
1.1548 + }
1.1549 +
1.1550 +#ifndef OPENSSL_NO_DH
1.1551 +static DH *load_dh_param(const char *dhfile)
1.1552 + {
1.1553 + DH *ret=NULL;
1.1554 + BIO *bio;
1.1555 +
1.1556 + if ((bio=BIO_new_file(dhfile,"r")) == NULL)
1.1557 + goto err;
1.1558 + ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
1.1559 +err:
1.1560 + if (bio != NULL) BIO_free(bio);
1.1561 + return(ret);
1.1562 + }
1.1563 +#endif
1.1564 +
1.1565 +#if 0
1.1566 +static int load_CA(SSL_CTX *ctx, char *file)
1.1567 + {
1.1568 + FILE *in;
1.1569 + X509 *x=NULL;
1.1570 +
1.1571 + if ((in=fopen(file,"r")) == NULL)
1.1572 + return(0);
1.1573 +
1.1574 + for (;;)
1.1575 + {
1.1576 + if (PEM_read_X509(in,&x,NULL) == NULL)
1.1577 + break;
1.1578 + SSL_CTX_add_client_CA(ctx,x);
1.1579 + }
1.1580 + if (x != NULL) X509_free(x);
1.1581 + fclose(in);
1.1582 + return(1);
1.1583 + }
1.1584 +#endif
1.1585 +
1.1586 +static int www_body(char *hostname, int s, unsigned char *context)
1.1587 + {
1.1588 + char *buf=NULL;
1.1589 + int ret=1;
1.1590 + int i,j,k,blank,dot;
1.1591 + struct stat st_buf;
1.1592 + SSL *con;
1.1593 + SSL_CIPHER *c;
1.1594 + BIO *io,*ssl_bio,*sbio;
1.1595 + long total_bytes;
1.1596 +
1.1597 + buf=OPENSSL_malloc(bufsize);
1.1598 + if (buf == NULL) return(0);
1.1599 + io=BIO_new(BIO_f_buffer());
1.1600 + ssl_bio=BIO_new(BIO_f_ssl());
1.1601 + if ((io == NULL) || (ssl_bio == NULL)) goto err;
1.1602 +
1.1603 +#ifdef FIONBIO
1.1604 + if (s_nbio)
1.1605 + {
1.1606 + unsigned long sl=1;
1.1607 +
1.1608 + if (!s_quiet)
1.1609 + BIO_printf(bio_err,"turning on non blocking io\n");
1.1610 + if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0)
1.1611 + ERR_print_errors(bio_err);
1.1612 + }
1.1613 +#endif
1.1614 +
1.1615 + /* lets make the output buffer a reasonable size */
1.1616 + if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
1.1617 +
1.1618 + if ((con=SSL_new(ctx)) == NULL) goto err;
1.1619 +#ifndef OPENSSL_NO_KRB5
1.1620 + if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
1.1621 + {
1.1622 + kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
1.1623 + kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
1.1624 + }
1.1625 +#endif /* OPENSSL_NO_KRB5 */
1.1626 + if(context) SSL_set_session_id_context(con, context,
1.1627 + strlen((char *)context));
1.1628 +
1.1629 + sbio=BIO_new_socket(s,BIO_NOCLOSE);
1.1630 + if (s_nbio_test)
1.1631 + {
1.1632 + BIO *test;
1.1633 +
1.1634 + test=BIO_new(BIO_f_nbio_test());
1.1635 + sbio=BIO_push(test,sbio);
1.1636 + }
1.1637 + SSL_set_bio(con,sbio,sbio);
1.1638 + SSL_set_accept_state(con);
1.1639 +
1.1640 + /* SSL_set_fd(con,s); */
1.1641 + BIO_set_ssl(ssl_bio,con,BIO_CLOSE);
1.1642 + BIO_push(io,ssl_bio);
1.1643 +#ifdef CHARSET_EBCDIC
1.1644 + io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);
1.1645 +#endif
1.1646 +
1.1647 + if (s_debug)
1.1648 + {
1.1649 + con->debug=1;
1.1650 + BIO_set_callback(SSL_get_rbio(con),bio_dump_callback);
1.1651 + BIO_set_callback_arg(SSL_get_rbio(con),(char*)bio_s_out);
1.1652 + }
1.1653 + if (s_msg)
1.1654 + {
1.1655 + SSL_set_msg_callback(con, msg_cb);
1.1656 + SSL_set_msg_callback_arg(con, bio_s_out);
1.1657 + }
1.1658 +
1.1659 + blank=0;
1.1660 + for (;;)
1.1661 + {
1.1662 + if (hack)
1.1663 + {
1.1664 + i=SSL_accept(con);
1.1665 +
1.1666 + switch (SSL_get_error(con,i))
1.1667 + {
1.1668 + case SSL_ERROR_NONE:
1.1669 + break;
1.1670 + case SSL_ERROR_WANT_WRITE:
1.1671 + case SSL_ERROR_WANT_READ:
1.1672 + case SSL_ERROR_WANT_X509_LOOKUP:
1.1673 + continue;
1.1674 + case SSL_ERROR_SYSCALL:
1.1675 + case SSL_ERROR_SSL:
1.1676 + case SSL_ERROR_ZERO_RETURN:
1.1677 + ret=1;
1.1678 + goto err;
1.1679 + /* break; */
1.1680 + }
1.1681 +
1.1682 + SSL_renegotiate(con);
1.1683 + SSL_write(con,NULL,0);
1.1684 + }
1.1685 +
1.1686 + i=BIO_gets(io,buf,bufsize-1);
1.1687 + if (i < 0) /* error */
1.1688 + {
1.1689 + if (!BIO_should_retry(io))
1.1690 + {
1.1691 + if (!s_quiet)
1.1692 + ERR_print_errors(bio_err);
1.1693 + goto err;
1.1694 + }
1.1695 + else
1.1696 + {
1.1697 + BIO_printf(bio_s_out,"read R BLOCK\n");
1.1698 +#if defined(OPENSSL_SYS_NETWARE)
1.1699 + delay(1000);
1.1700 +#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
1.1701 + sleep(1);
1.1702 +#endif
1.1703 + continue;
1.1704 + }
1.1705 + }
1.1706 + else if (i == 0) /* end of input */
1.1707 + {
1.1708 + ret=1;
1.1709 + goto end;
1.1710 + }
1.1711 +
1.1712 + /* else we have data */
1.1713 + if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) ||
1.1714 + ((www == 2) && (strncmp("GET /stats ",buf,10) == 0)))
1.1715 + {
1.1716 + char *p;
1.1717 + X509 *peer;
1.1718 + STACK_OF(SSL_CIPHER) *sk;
1.1719 + static const char *space=" ";
1.1720 +
1.1721 + BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1.1722 + BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n");
1.1723 + BIO_puts(io,"<pre>\n");
1.1724 +/* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
1.1725 + BIO_puts(io,"\n");
1.1726 + for (i=0; i<local_argc; i++)
1.1727 + {
1.1728 + BIO_puts(io,local_argv[i]);
1.1729 + BIO_write(io," ",1);
1.1730 + }
1.1731 + BIO_puts(io,"\n");
1.1732 +
1.1733 + /* The following is evil and should not really
1.1734 + * be done */
1.1735 + BIO_printf(io,"Ciphers supported in s_server binary\n");
1.1736 + sk=SSL_get_ciphers(con);
1.1737 + j=sk_SSL_CIPHER_num(sk);
1.1738 + for (i=0; i<j; i++)
1.1739 + {
1.1740 + c=sk_SSL_CIPHER_value(sk,i);
1.1741 + BIO_printf(io,"%-11s:%-25s",
1.1742 + SSL_CIPHER_get_version(c),
1.1743 + SSL_CIPHER_get_name(c));
1.1744 + if ((((i+1)%2) == 0) && (i+1 != j))
1.1745 + BIO_puts(io,"\n");
1.1746 + }
1.1747 + BIO_puts(io,"\n");
1.1748 + p=SSL_get_shared_ciphers(con,buf,bufsize);
1.1749 + if (p != NULL)
1.1750 + {
1.1751 + BIO_printf(io,"---\nCiphers common between both SSL end points:\n");
1.1752 + j=i=0;
1.1753 + while (*p)
1.1754 + {
1.1755 + if (*p == ':')
1.1756 + {
1.1757 + BIO_write(io,space,26-j);
1.1758 + i++;
1.1759 + j=0;
1.1760 + BIO_write(io,((i%3)?" ":"\n"),1);
1.1761 + }
1.1762 + else
1.1763 + {
1.1764 + BIO_write(io,p,1);
1.1765 + j++;
1.1766 + }
1.1767 + p++;
1.1768 + }
1.1769 + BIO_puts(io,"\n");
1.1770 + }
1.1771 + BIO_printf(io,((con->hit)
1.1772 + ?"---\nReused, "
1.1773 + :"---\nNew, "));
1.1774 + c=SSL_get_current_cipher(con);
1.1775 + BIO_printf(io,"%s, Cipher is %s\n",
1.1776 + SSL_CIPHER_get_version(c),
1.1777 + SSL_CIPHER_get_name(c));
1.1778 + SSL_SESSION_print(io,SSL_get_session(con));
1.1779 + BIO_printf(io,"---\n");
1.1780 + print_stats(io,SSL_get_SSL_CTX(con));
1.1781 + BIO_printf(io,"---\n");
1.1782 + peer=SSL_get_peer_certificate(con);
1.1783 + if (peer != NULL)
1.1784 + {
1.1785 + BIO_printf(io,"Client certificate\n");
1.1786 + X509_print(io,peer);
1.1787 + PEM_write_bio_X509(io,peer);
1.1788 + }
1.1789 + else
1.1790 + BIO_puts(io,"no client certificate available\n");
1.1791 + BIO_puts(io,"</BODY></HTML>\r\n\r\n");
1.1792 + break;
1.1793 + }
1.1794 + else if ((www == 2 || www == 3)
1.1795 + && (strncmp("GET /",buf,5) == 0))
1.1796 + {
1.1797 + BIO *file;
1.1798 + char *p,*e;
1.1799 + static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
1.1800 +
1.1801 + /* skip the '/' */
1.1802 + p= &(buf[5]);
1.1803 +
1.1804 + dot = 1;
1.1805 + for (e=p; *e != '\0'; e++)
1.1806 + {
1.1807 + if (e[0] == ' ')
1.1808 + break;
1.1809 +
1.1810 + switch (dot)
1.1811 + {
1.1812 + case 1:
1.1813 + dot = (e[0] == '.') ? 2 : 0;
1.1814 + break;
1.1815 + case 2:
1.1816 + dot = (e[0] == '.') ? 3 : 0;
1.1817 + break;
1.1818 + case 3:
1.1819 + dot = (e[0] == '/') ? -1 : 0;
1.1820 + break;
1.1821 + }
1.1822 + if (dot == 0)
1.1823 + dot = (e[0] == '/') ? 1 : 0;
1.1824 + }
1.1825 + dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
1.1826 +
1.1827 + if (*e == '\0')
1.1828 + {
1.1829 + BIO_puts(io,text);
1.1830 + BIO_printf(io,"'%s' is an invalid file name\r\n",p);
1.1831 + break;
1.1832 + }
1.1833 + *e='\0';
1.1834 +
1.1835 + if (dot)
1.1836 + {
1.1837 + BIO_puts(io,text);
1.1838 + BIO_printf(io,"'%s' contains '..' reference\r\n",p);
1.1839 + break;
1.1840 + }
1.1841 +
1.1842 + if (*p == '/')
1.1843 + {
1.1844 + BIO_puts(io,text);
1.1845 + BIO_printf(io,"'%s' is an invalid path\r\n",p);
1.1846 + break;
1.1847 + }
1.1848 +
1.1849 +#if 0
1.1850 + /* append if a directory lookup */
1.1851 + if (e[-1] == '/')
1.1852 + strcat(p,"index.html");
1.1853 +#endif
1.1854 +
1.1855 + /* if a directory, do the index thang */
1.1856 + if (stat(p,&st_buf) < 0)
1.1857 + {
1.1858 + BIO_puts(io,text);
1.1859 + BIO_printf(io,"Error accessing '%s'\r\n",p);
1.1860 + ERR_print_errors(io);
1.1861 + break;
1.1862 + }
1.1863 + if (S_ISDIR(st_buf.st_mode))
1.1864 + {
1.1865 +#if 0 /* must check buffer size */
1.1866 + strcat(p,"/index.html");
1.1867 +#else
1.1868 + BIO_puts(io,text);
1.1869 + BIO_printf(io,"'%s' is a directory\r\n",p);
1.1870 + break;
1.1871 +#endif
1.1872 + }
1.1873 +
1.1874 + if ((file=BIO_new_file(p,"r")) == NULL)
1.1875 + {
1.1876 + BIO_puts(io,text);
1.1877 + BIO_printf(io,"Error opening '%s'\r\n",p);
1.1878 + ERR_print_errors(io);
1.1879 + break;
1.1880 + }
1.1881 +
1.1882 + if (!s_quiet)
1.1883 + BIO_printf(bio_err,"FILE:%s\n",p);
1.1884 +
1.1885 + if (www == 2)
1.1886 + {
1.1887 + i=strlen(p);
1.1888 + if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
1.1889 + ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
1.1890 + ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
1.1891 + BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
1.1892 + else
1.1893 + BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
1.1894 + }
1.1895 + /* send the file */
1.1896 + total_bytes=0;
1.1897 + for (;;)
1.1898 + {
1.1899 + i=BIO_read(file,buf,bufsize);
1.1900 + if (i <= 0) break;
1.1901 +
1.1902 +#ifdef RENEG
1.1903 + total_bytes+=i;
1.1904 + fprintf(stderr,"%d\n",i);
1.1905 + if (total_bytes > 3*1024)
1.1906 + {
1.1907 + total_bytes=0;
1.1908 + fprintf(stderr,"RENEGOTIATE\n");
1.1909 + SSL_renegotiate(con);
1.1910 + }
1.1911 +
1.1912 +#endif
1.1913 +
1.1914 + for (j=0; j<i; )
1.1915 + {
1.1916 +#ifdef RENEG
1.1917 +{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }
1.1918 +#endif
1.1919 + k=BIO_write(io,&(buf[j]),i-j);
1.1920 + if (k <= 0)
1.1921 + {
1.1922 + if (!BIO_should_retry(io))
1.1923 + goto write_error;
1.1924 + else
1.1925 + {
1.1926 + BIO_printf(bio_s_out,"rwrite W BLOCK\n");
1.1927 + }
1.1928 + }
1.1929 + else
1.1930 + {
1.1931 + j+=k;
1.1932 + }
1.1933 + }
1.1934 + }
1.1935 +write_error:
1.1936 + BIO_free(file);
1.1937 + break;
1.1938 + }
1.1939 + }
1.1940 +
1.1941 + for (;;)
1.1942 + {
1.1943 + i=(int)BIO_flush(io);
1.1944 + if (i <= 0)
1.1945 + {
1.1946 + if (!BIO_should_retry(io))
1.1947 + break;
1.1948 + }
1.1949 + else
1.1950 + break;
1.1951 + }
1.1952 +end:
1.1953 +#if 1
1.1954 + /* make sure we re-use sessions */
1.1955 + SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1.1956 +#else
1.1957 + /* This kills performance */
1.1958 +/* SSL_shutdown(con); A shutdown gets sent in the
1.1959 + * BIO_free_all(io) procession */
1.1960 +#endif
1.1961 +
1.1962 +err:
1.1963 +
1.1964 + if (ret >= 0)
1.1965 + BIO_printf(bio_s_out,"ACCEPT\n");
1.1966 +
1.1967 + if (buf != NULL) OPENSSL_free(buf);
1.1968 + if (io != NULL) BIO_free_all(io);
1.1969 +/* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
1.1970 + return(ret);
1.1971 + }
1.1972 +
1.1973 +#ifndef OPENSSL_NO_RSA
1.1974 +static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
1.1975 + {
1.1976 + BIGNUM *bn = NULL;
1.1977 + static RSA *rsa_tmp=NULL;
1.1978 +
1.1979 + if (!rsa_tmp && ((bn = BN_new()) == NULL))
1.1980 + BIO_printf(bio_err,"Allocation error in generating RSA key\n");
1.1981 + if (!rsa_tmp && bn)
1.1982 + {
1.1983 + if (!s_quiet)
1.1984 + {
1.1985 + BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
1.1986 + (void)BIO_flush(bio_err);
1.1987 + }
1.1988 + if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
1.1989 + !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
1.1990 + {
1.1991 + if(rsa_tmp) RSA_free(rsa_tmp);
1.1992 + rsa_tmp = NULL;
1.1993 + }
1.1994 + if (!s_quiet)
1.1995 + {
1.1996 + BIO_printf(bio_err,"\n");
1.1997 + (void)BIO_flush(bio_err);
1.1998 + }
1.1999 + BN_free(bn);
1.2000 + }
1.2001 + return(rsa_tmp);
1.2002 + }
1.2003 +#endif
1.2004 +
1.2005 +#define MAX_SESSION_ID_ATTEMPTS 10
1.2006 +static int generate_session_id(const SSL *ssl, unsigned char *id,
1.2007 + unsigned int *id_len)
1.2008 + {
1.2009 + unsigned int count = 0;
1.2010 + do {
1.2011 + RAND_pseudo_bytes(id, *id_len);
1.2012 + /* Prefix the session_id with the required prefix. NB: If our
1.2013 + * prefix is too long, clip it - but there will be worse effects
1.2014 + * anyway, eg. the server could only possibly create 1 session
1.2015 + * ID (ie. the prefix!) so all future session negotiations will
1.2016 + * fail due to conflicts. */
1.2017 + memcpy(id, session_id_prefix,
1.2018 + (strlen(session_id_prefix) < *id_len) ?
1.2019 + strlen(session_id_prefix) : *id_len);
1.2020 + }
1.2021 + while(SSL_has_matching_session_id(ssl, id, *id_len) &&
1.2022 + (++count < MAX_SESSION_ID_ATTEMPTS));
1.2023 + if(count >= MAX_SESSION_ID_ATTEMPTS)
1.2024 + return 0;
1.2025 + return 1;
1.2026 + }