* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
+/* ====================================================================
+ * Copyright (c) 1998-2001 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef NO_STDIO
+#include <openssl/e_os2.h>
+#ifdef OPENSSL_NO_STDIO
#define APPS_WIN16
#endif
recursive header file inclusion, resulting in the compiler complaining
that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which
is needed to have fileno() declared correctly... So let's define u_int */
-#if defined(VMS) && defined(__DECC) && !defined(__U_INT)
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
#define __U_INT
typedef unsigned int u_int;
#endif
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/ssl.h>
+#include <openssl/rand.h>
#include "s_apps.h"
-#ifdef WINDOWS
+#ifdef OPENSSL_SYS_WINDOWS
#include <conio.h>
#endif
-#if (defined(VMS) && __VMS_VER < 70000000)
+#ifdef OPENSSL_SYS_WINCE
+/* Windows CE incorrectly defines fileno as returning void*, so to avoid problems below... */
+#ifdef fileno
+#undef fileno
+#endif
+#define fileno(a) (int)_fileno(a)
+#endif
+
+#if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
#undef FIONBIO
#endif
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
#endif
static int sv_body(char *hostname, int s, unsigned char *context);
static void sv_usage(void);
static int init_ssl_connection(SSL *s);
static void print_stats(BIO *bp,SSL_CTX *ctx);
-#ifndef NO_DH
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+ unsigned int *id_len);
+#ifndef OPENSSL_NO_DH
static DH *load_dh_param(char *dhfile);
static DH *get_dh512(void);
#endif
+
#ifdef MONOLITH
static void s_server_init(void);
#endif
# endif
#endif
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
static unsigned char dh512_p[]={
0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
}
#endif
+
/* static int load_CA(SSL_CTX *ctx, char *file);*/
#undef BUFSIZZ
static BIO *bio_s_out=NULL;
static int s_debug=0;
+static int s_msg=0;
static int s_quiet=0;
static int hack=0;
+static char *engine_id=NULL;
+static const char *session_id_prefix=NULL;
#ifdef MONOLITH
static void s_server_init(void)
bio_s_out=NULL;
s_debug=0;
+ s_msg=0;
s_quiet=0;
hack=0;
+ engine_id=NULL;
}
#endif
BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n");
BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n");
BIO_printf(bio_err," or a default set of parameters is used\n");
+#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");
+#endif
#ifdef FIONBIO
BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");
#endif
BIO_printf(bio_err," -nbio_test - test with the non-blocking test bio\n");
BIO_printf(bio_err," -crlf - convert LF from terminal into CRLF\n");
BIO_printf(bio_err," -debug - Print more output\n");
+ BIO_printf(bio_err," -msg - Show protocol messages\n");
BIO_printf(bio_err," -state - Print the SSL states\n");
BIO_printf(bio_err," -CApath arg - PEM format directory of CA's\n");
BIO_printf(bio_err," -CAfile arg - PEM format file of CA's\n");
BIO_printf(bio_err," -nocert - Don't use any certificates (Anon-DH)\n");
BIO_printf(bio_err," -cipher arg - play with 'openssl ciphers' to see what goes here\n");
+ 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");
BIO_printf(bio_err," -ssl2 - Just talk SSLv2\n");
BIO_printf(bio_err," -no_ssl2 - Just disable SSLv2\n");
BIO_printf(bio_err," -no_ssl3 - Just disable SSLv3\n");
BIO_printf(bio_err," -no_tls1 - Just disable TLSv1\n");
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\n");
+#endif
+#ifndef OPENSSL_NO_ECDH
+ BIO_printf(bio_err," -no_ecdhe - Disable ephemeral ECDH\n");
#endif
BIO_printf(bio_err," -bugs - Turn on SSL bug compatibility\n");
BIO_printf(bio_err," -www - Respond to a 'GET /' with a status page\n");
BIO_printf(bio_err," -WWW - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+ BIO_printf(bio_err," -HTTP - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
+ BIO_printf(bio_err," with the assumption it contains a complete HTTP response.\n");
+ BIO_printf(bio_err," -engine id - Initialise and use the specified engine\n");
+ BIO_printf(bio_err," -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
+ BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
}
static int local_argc=0;
static int ebcdic_new(BIO *bi);
static int ebcdic_free(BIO *a);
static int ebcdic_read(BIO *b, char *out, int outl);
-static int ebcdic_write(BIO *b, char *in, int inl);
-static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr);
+static int ebcdic_write(BIO *b, const char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
static int ebcdic_gets(BIO *bp, char *buf, int size);
-static int ebcdic_puts(BIO *bp, char *str);
+static int ebcdic_puts(BIO *bp, const char *str);
#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
static BIO_METHOD methods_ebcdic=
{
EBCDIC_OUTBUFF *wbuf;
- wbuf = (EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+ wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
wbuf->alloced = 1024;
wbuf->buff[0] = '\0';
{
if (a == NULL) return(0);
if (a->ptr != NULL)
- Free(a->ptr);
+ OPENSSL_free(a->ptr);
a->ptr=NULL;
a->init=0;
a->flags=0;
return(ret);
}
-static int ebcdic_write(BIO *b, char *in, int inl)
+static int ebcdic_write(BIO *b, const char *in, int inl)
{
EBCDIC_OUTBUFF *wbuf;
int ret=0;
num = num + num; /* double the size */
if (num < inl)
num = inl;
- Free(wbuf);
- wbuf=(EBCDIC_OUTBUFF *)Malloc(sizeof(EBCDIC_OUTBUFF) + num);
+ OPENSSL_free(wbuf);
+ wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
wbuf->alloced = num;
wbuf->buff[0] = '\0';
return(ret);
}
-static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr)
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret;
static int ebcdic_gets(BIO *bp, char *buf, int size)
{
- int i, ret;
+ int i, ret=0;
if (bp->next_bio == NULL) return(0);
/* return(BIO_gets(bp->next_bio,buf,size));*/
for (i=0; i<size-1; ++i)
return (ret < 0 && i == 0) ? ret : i;
}
-static int ebcdic_puts(BIO *bp, char *str)
+static int ebcdic_puts(BIO *bp, const char *str)
{
if (bp->next_bio == NULL) return(0);
return ebcdic_write(bp, str, strlen(str));
}
#endif
+int MAIN(int, char **);
+
int MAIN(int argc, char *argv[])
{
+ X509_STORE *store = NULL;
+ int vflags = 0;
short port=PORT;
char *CApath=NULL,*CAfile=NULL;
char *context = NULL;
char *dhfile = NULL;
+ char *named_curve = NULL;
int badop=0,bugs=0;
int ret=1;
int off=0;
- int no_tmp_rsa=0,no_dhe=0,nocert=0;
+ int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
int state=0;
SSL_METHOD *meth=NULL;
-#ifndef NO_DH
- DH *dh=NULL;
-#endif
+ ENGINE *e=NULL;
+ char *inrand=NULL;
-#if !defined(NO_SSL2) && !defined(NO_SSL3)
+#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_server_method();
-#elif !defined(NO_SSL3)
+#elif !defined(OPENSSL_NO_SSL3)
meth=SSLv3_server_method();
-#elif !defined(NO_SSL2)
+#elif !defined(OPENSSL_NO_SSL2)
meth=SSLv2_server_method();
#endif
if (bio_err == NULL)
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
+ if (!load_config(bio_err, NULL))
+ goto end;
+
verify_depth=0;
#ifdef FIONBIO
s_nbio=0;
if (--argc < 1) goto bad;
dhfile = *(++argv);
}
+#ifndef OPENSSL_NO_ECDH
+ else if (strcmp(*argv,"-named_curve") == 0)
+ {
+ if (--argc < 1) goto bad;
+ named_curve = *(++argv);
+ }
+#endif
else if (strcmp(*argv,"-dcert") == 0)
{
if (--argc < 1) goto bad;
if (--argc < 1) goto bad;
CApath= *(++argv);
}
+ else if (strcmp(*argv,"-crl_check") == 0)
+ {
+ vflags |= X509_V_FLAG_CRL_CHECK;
+ }
+ else if (strcmp(*argv,"-crl_check") == 0)
+ {
+ vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+ }
+ else if (strcmp(*argv,"-serverpref") == 0)
+ { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; }
else if (strcmp(*argv,"-cipher") == 0)
{
if (--argc < 1) goto bad;
}
else if (strcmp(*argv,"-debug") == 0)
{ s_debug=1; }
+ else if (strcmp(*argv,"-msg") == 0)
+ { s_msg=1; }
else if (strcmp(*argv,"-hack") == 0)
{ hack=1; }
else if (strcmp(*argv,"-state") == 0)
{ no_tmp_rsa=1; }
else if (strcmp(*argv,"-no_dhe") == 0)
{ no_dhe=1; }
+ else if (strcmp(*argv,"-no_ecdhe") == 0)
+ { no_ecdhe=1; }
else if (strcmp(*argv,"-www") == 0)
{ www=1; }
else if (strcmp(*argv,"-WWW") == 0)
{ www=2; }
+ else if (strcmp(*argv,"-HTTP") == 0)
+ { www=3; }
else if (strcmp(*argv,"-no_ssl2") == 0)
{ off|=SSL_OP_NO_SSLv2; }
else if (strcmp(*argv,"-no_ssl3") == 0)
{ off|=SSL_OP_NO_SSLv3; }
else if (strcmp(*argv,"-no_tls1") == 0)
{ off|=SSL_OP_NO_TLSv1; }
-#ifndef NO_SSL2
+#ifndef OPENSSL_NO_SSL2
else if (strcmp(*argv,"-ssl2") == 0)
{ meth=SSLv2_server_method(); }
#endif
-#ifndef NO_SSL3
+#ifndef OPENSSL_NO_SSL3
else if (strcmp(*argv,"-ssl3") == 0)
{ meth=SSLv3_server_method(); }
#endif
-#ifndef NO_TLS1
+#ifndef OPENSSL_NO_TLS1
else if (strcmp(*argv,"-tls1") == 0)
{ meth=TLSv1_server_method(); }
#endif
+ else if (strcmp(*argv, "-id_prefix") == 0)
+ {
+ if (--argc < 1) goto bad;
+ session_id_prefix = *(++argv);
+ }
+ else if (strcmp(*argv,"-engine") == 0)
+ {
+ if (--argc < 1) goto bad;
+ engine_id= *(++argv);
+ }
+ else if (strcmp(*argv,"-rand") == 0)
+ {
+ if (--argc < 1) goto bad;
+ inrand= *(++argv);
+ }
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
goto end;
}
- app_RAND_load_file(NULL, bio_err, 0);
+ SSL_load_error_strings();
+ OpenSSL_add_ssl_algorithms();
+
+ e = setup_engine(bio_err, engine_id, 1);
+
+ if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
+ && !RAND_status())
+ {
+ BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
+ }
+ if (inrand != NULL)
+ BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+ app_RAND_load_files(inrand));
if (bio_s_out == NULL)
{
- if (s_quiet && !s_debug)
+ if (s_quiet && !s_debug && !s_msg)
{
bio_s_out=BIO_new(BIO_s_null());
}
}
}
-#if !defined(NO_RSA) || !defined(NO_DSA)
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
if (nocert)
#endif
{
s_dkey_file=NULL;
}
- SSL_load_error_strings();
- SSLeay_add_ssl_algorithms();
-
ctx=SSL_CTX_new(meth);
if (ctx == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
-
+ if (session_id_prefix)
+ {
+ if(strlen(session_id_prefix) >= 32)
+ BIO_printf(bio_err,
+"warning: id_prefix is too long, only one new session will be possible\n");
+ else if(strlen(session_id_prefix) >= 16)
+ BIO_printf(bio_err,
+"warning: id_prefix is too long if you use SSLv2\n");
+ if(!SSL_CTX_set_generate_session_id(ctx, generate_session_id))
+ {
+ BIO_printf(bio_err,"error setting 'id_prefix'\n");
+ ERR_print_errors(bio_err);
+ goto end;
+ }
+ BIO_printf(bio_err,"id_prefix '%s' set.\n", session_id_prefix);
+ }
SSL_CTX_set_quiet_shutdown(ctx,1);
if (bugs) SSL_CTX_set_options(ctx,SSL_OP_ALL);
if (hack) SSL_CTX_set_options(ctx,SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
SSL_CTX_set_options(ctx,off);
- if (hack) SSL_CTX_set_options(ctx,SSL_OP_NON_EXPORT_FIRST);
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
ERR_print_errors(bio_err);
/* goto end; */
}
+ store = SSL_CTX_get_cert_store(ctx);
+ X509_STORE_set_flags(store, vflags);
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
if (!no_dhe)
{
- dh=load_dh_param(dhfile ? dhfile : s_cert_file);
+ DH *dh=NULL;
+
+ if (dhfile)
+ dh = load_dh_param(dhfile);
+ else if (s_cert_file)
+ dh = load_dh_param(s_cert_file);
+
if (dh != NULL)
{
BIO_printf(bio_s_out,"Setting temp DH parameters\n");
DH_free(dh);
}
#endif
+
+#ifndef OPENSSL_NO_ECDH
+ if (!no_ecdhe)
+ {
+ EC_KEY *ecdh=NULL;
+
+ ecdh = EC_KEY_new();
+ if (ecdh == NULL)
+ {
+ BIO_printf(bio_err,"Could not create ECDH struct.\n");
+ goto end;
+ }
+
+ if (named_curve)
+ {
+ int nid = OBJ_sn2nid(named_curve);
+
+ if (nid == 0)
+ {
+ BIO_printf(bio_err, "unknown curve name (%s)\n",
+ named_curve);
+ goto end;
+ }
+
+ ecdh->group = EC_GROUP_new_by_nid(nid);
+ if (ecdh->group == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve (%s)\n",
+ named_curve);
+ goto end;
+ }
+ }
+
+ if (ecdh->group != NULL)
+ {
+ BIO_printf(bio_s_out,"Setting temp ECDH parameters\n");
+ }
+ else
+ {
+ BIO_printf(bio_s_out,"Using default temp ECDH parameters\n");
+ ecdh->group=EC_GROUP_new_by_nid(NID_sect163r2);
+ if (ecdh->group == NULL)
+ {
+ BIO_printf(bio_err, "unable to create curve (sect163r2)\n");
+ goto end;
+ }
+ }
+ (void)BIO_flush(bio_s_out);
+
+ SSL_CTX_set_tmp_ecdh(ctx,ecdh);
+ EC_KEY_free(ecdh);
+ }
+#endif
if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
goto end;
goto end;
}
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
#if 1
- SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
+ if (!no_tmp_rsa)
+ SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);
#else
if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx))
{
BIO_free(bio_s_out);
bio_s_out=NULL;
}
+ apps_shutdown();
EXIT(ret);
}
unsigned long l;
SSL *con=NULL;
BIO *sbio;
-#ifdef WINDOWS
+#ifdef OPENSSL_SYS_WINDOWS
struct timeval tv;
#endif
- if ((buf=Malloc(bufsize)) == NULL)
+ if ((buf=OPENSSL_malloc(bufsize)) == NULL)
{
BIO_printf(bio_err,"out of memory\n");
goto err;
if (con == NULL) {
con=SSL_new(ctx);
+#ifndef OPENSSL_NO_KRB5
+ if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
+ {
+ kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE,
+ KRB5SVC);
+ kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB,
+ KRB5KEYTAB);
+ }
+#endif /* OPENSSL_NO_KRB5 */
if(context)
SSL_set_session_id_context(con, context,
strlen((char *)context));
BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
}
+ if (s_msg)
+ {
+ SSL_set_msg_callback(con, msg_cb);
+ SSL_set_msg_callback_arg(con, bio_s_out);
+ }
width=s+1;
for (;;)
{
- FD_ZERO(&readfds);
-#ifndef WINDOWS
- FD_SET(fileno(stdin),&readfds);
+ int read_from_terminal;
+ int read_from_sslcon;
+
+ read_from_terminal = 0;
+ read_from_sslcon = SSL_pending(con);
+
+ if (!read_from_sslcon)
+ {
+ FD_ZERO(&readfds);
+#ifndef OPENSSL_SYS_WINDOWS
+ FD_SET(fileno(stdin),&readfds);
#endif
- FD_SET(s,&readfds);
- /* Note: under VMS with SOCKETSHR the second parameter is
- * currently of type (int *) whereas under other systems
- * it is (void *) if you don't have a cast it will choke
- * the compiler: if you do have a cast then you can either
- * go for (int *) or (void *).
- */
-#ifdef WINDOWS
- /* Under Windows we can't select on stdin: only
- * on sockets. As a workaround we timeout the select every
- * second and check for any keypress. In a proper Windows
- * application we wouldn't do this because it is inefficient.
- */
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- i=select(width,(void *)&readfds,NULL,NULL,&tv);
- if((i < 0) || (!i && !_kbhit() ) )continue;
- if(_kbhit())
+ FD_SET(s,&readfds);
+ /* Note: under VMS with SOCKETSHR the second parameter is
+ * currently of type (int *) whereas under other systems
+ * it is (void *) if you don't have a cast it will choke
+ * the compiler: if you do have a cast then you can either
+ * go for (int *) or (void *).
+ */
+#ifdef OPENSSL_SYS_WINDOWS
+ /* Under Windows we can't select on stdin: only
+ * on sockets. As a workaround we timeout the select every
+ * second and check for any keypress. In a proper Windows
+ * application we wouldn't do this because it is inefficient.
+ */
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ i=select(width,(void *)&readfds,NULL,NULL,&tv);
+ if((i < 0) || (!i && !_kbhit() ) )continue;
+ if(_kbhit())
+ read_from_terminal = 1;
#else
- i=select(width,(void *)&readfds,NULL,NULL,NULL);
- if (i <= 0) continue;
- if (FD_ISSET(fileno(stdin),&readfds))
+ i=select(width,(void *)&readfds,NULL,NULL,NULL);
+ if (i <= 0) continue;
+ if (FD_ISSET(fileno(stdin),&readfds))
+ read_from_terminal = 1;
#endif
+ if (FD_ISSET(s,&readfds))
+ read_from_sslcon = 1;
+ }
+ if (read_from_terminal)
{
if (s_crlf)
{
if (i <= 0) break;
}
}
- if (FD_ISSET(s,&readfds))
+ if (read_from_sslcon)
{
if (!SSL_is_init_finished(con))
{
if (buf != NULL)
{
memset(buf,0,bufsize);
- Free(buf);
+ OPENSSL_free(buf);
}
if (ret >= 0)
BIO_printf(bio_s_out,"ACCEPT\n");
{
BIO_printf(bio_s_out,"Client certificate\n");
PEM_write_bio_X509(bio_s_out,peer);
- X509_NAME_oneline(X509_get_subject_name(peer),buf,BUFSIZ);
+ X509_NAME_oneline(X509_get_subject_name(peer),buf,sizeof buf);
BIO_printf(bio_s_out,"subject=%s\n",buf);
- X509_NAME_oneline(X509_get_issuer_name(peer),buf,BUFSIZ);
+ X509_NAME_oneline(X509_get_issuer_name(peer),buf,sizeof buf);
BIO_printf(bio_s_out,"issuer=%s\n",buf);
X509_free(peer);
}
- if (SSL_get_shared_ciphers(con,buf,BUFSIZ) != NULL)
+ if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL)
BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf);
str=SSL_CIPHER_get_name(SSL_get_current_cipher(con));
BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)");
return(1);
}
-#ifndef NO_DH
+#ifndef OPENSSL_NO_DH
static DH *load_dh_param(char *dhfile)
{
DH *ret=NULL;
BIO *io,*ssl_bio,*sbio;
long total_bytes;
- buf=Malloc(bufsize);
+ buf=OPENSSL_malloc(bufsize);
if (buf == NULL) return(0);
io=BIO_new(BIO_f_buffer());
ssl_bio=BIO_new(BIO_f_ssl());
if (!BIO_set_write_buffer_size(io,bufsize)) goto err;
if ((con=SSL_new(ctx)) == NULL) goto err;
+#ifndef OPENSSL_NO_KRB5
+ if ((con->kssl_ctx = kssl_ctx_new()) != NULL)
+ {
+ kssl_ctx_setstring(con->kssl_ctx, KSSL_SERVICE, KRB5SVC);
+ kssl_ctx_setstring(con->kssl_ctx, KSSL_KEYTAB, KRB5KEYTAB);
+ }
+#endif /* OPENSSL_NO_KRB5 */
if(context) SSL_set_session_id_context(con, context,
strlen((char *)context));
BIO_set_callback(SSL_get_rbio(con),bio_dump_cb);
BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out);
}
+ if (s_msg)
+ {
+ SSL_set_msg_callback(con, msg_cb);
+ SSL_set_msg_callback_arg(con, bio_s_out);
+ }
blank=0;
for (;;)
else
{
BIO_printf(bio_s_out,"read R BLOCK\n");
-#ifndef MSDOS
+#if !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
sleep(1);
#endif
continue;
BIO_puts(io,"</BODY></HTML>\r\n\r\n");
break;
}
- else if ((www == 2) && (strncmp("GET /",buf,5) == 0))
+ else if ((www == 2 || www == 3)
+ && (strncmp("GET /",buf,5) == 0))
{
BIO *file;
char *p,*e;
/* skip the '/' */
p= &(buf[5]);
- dot=0;
+
+ dot = 1;
for (e=p; *e != '\0'; e++)
{
- if (e[0] == ' ') break;
- if ( (e[0] == '.') &&
- (strncmp(&(e[-1]),"/../",4) == 0))
- dot=1;
+ if (e[0] == ' ')
+ break;
+
+ switch (dot)
+ {
+ case 1:
+ dot = (e[0] == '.') ? 2 : 0;
+ break;
+ case 2:
+ dot = (e[0] == '.') ? 3 : 0;
+ break;
+ case 3:
+ dot = (e[0] == '/') ? -1 : 0;
+ break;
+ }
+ if (dot == 0)
+ dot = (e[0] == '/') ? 1 : 0;
}
-
+ dot = (dot == 3) || (dot == -1); /* filename contains ".." component */
if (*e == '\0')
{
break;
}
+#if 0
/* append if a directory lookup */
if (e[-1] == '/')
strcat(p,"index.html");
+#endif
/* if a directory, do the index thang */
if (stat(p,&st_buf) < 0)
}
if (S_ISDIR(st_buf.st_mode))
{
+#if 0 /* must check buffer size */
strcat(p,"/index.html");
+#else
+ BIO_puts(io,text);
+ BIO_printf(io,"'%s' is a directory\r\n",p);
+ break;
+#endif
}
if ((file=BIO_new_file(p,"r")) == NULL)
if (!s_quiet)
BIO_printf(bio_err,"FILE:%s\n",p);
- i=strlen(p);
- if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
- ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
- ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
- BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
- else
- BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+ if (www == 2)
+ {
+ i=strlen(p);
+ if ( ((i > 5) && (strcmp(&(p[i-5]),".html") == 0)) ||
+ ((i > 4) && (strcmp(&(p[i-4]),".php") == 0)) ||
+ ((i > 4) && (strcmp(&(p[i-4]),".htm") == 0)))
+ BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+ else
+ BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+ }
/* send the file */
total_bytes=0;
for (;;)
if (ret >= 0)
BIO_printf(bio_s_out,"ACCEPT\n");
- if (buf != NULL) Free(buf);
+ if (buf != NULL) OPENSSL_free(buf);
if (io != NULL) BIO_free_all(io);
/* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
return(ret);
}
-#ifndef NO_RSA
+#ifndef OPENSSL_NO_RSA
static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
{
static RSA *rsa_tmp=NULL;
return(rsa_tmp);
}
#endif
+
+#define MAX_SESSION_ID_ATTEMPTS 10
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+ unsigned int *id_len)
+ {
+ unsigned int count = 0;
+ do {
+ RAND_pseudo_bytes(id, *id_len);
+ /* Prefix the session_id with the required prefix. NB: If our
+ * prefix is too long, clip it - but there will be worse effects
+ * anyway, eg. the server could only possibly create 1 session
+ * ID (ie. the prefix!) so all future session negotiations will
+ * fail due to conflicts. */
+ memcpy(id, session_id_prefix,
+ (strlen(session_id_prefix) < *id_len) ?
+ strlen(session_id_prefix) : *id_len);
+ }
+ while(SSL_has_matching_session_id(ssl, id, *id_len) &&
+ (++count < MAX_SESSION_ID_ATTEMPTS));
+ if(count >= MAX_SESSION_ID_ATTEMPTS)
+ return 0;
+ return 1;
+ }