📄 s_server.c
字号:
/* apps/s_server.c *//* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * 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 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 acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS 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 AUTHOR OR 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. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#ifdef NO_STDIO#define APPS_WIN16#endif/* With IPv6, it looks like Digital has mixed up the proper order of 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)#define __U_INTtypedef unsigned int u_int;#endif#include <openssl/lhash.h>#include <openssl/bn.h>#define USE_SOCKETS#include "apps.h"#include <openssl/err.h>#include <openssl/pem.h>#include <openssl/x509.h>#include <openssl/ssl.h>#include "s_apps.h"#ifdef WINDOWS#include <conio.h>#endif#if (defined(VMS) && __VMS_VER < 70000000)/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */#undef FIONBIO#endif#ifndef NO_RSAstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);#endifstatic int sv_body(char *hostname, int s, unsigned char *context);static int www_body(char *hostname, int s, unsigned char *context);static void close_accept_socket(void );static void sv_usage(void);static int init_ssl_connection(SSL *s);static void print_stats(BIO *bp,SSL_CTX *ctx);#ifndef NO_DHstatic DH *load_dh_param(char *dhfile);static DH *get_dh512(void);#endif#ifdef MONOLITHstatic void s_server_init(void);#endif#ifndef S_ISDIR# if defined(_S_IFMT) && defined(_S_IFDIR)# define S_ISDIR(a) (((a) & _S_IFMT) == _S_IFDIR)# else# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)# endif#endif#ifndef NO_DHstatic 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, 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, 0x47,0x74,0xE8,0x33, };static unsigned char dh512_g[]={ 0x02, };static DH *get_dh512(void) { DH *dh=NULL; if ((dh=DH_new()) == NULL) return(NULL); dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); if ((dh->p == NULL) || (dh->g == NULL)) return(NULL); return(dh); }#endif/* static int load_CA(SSL_CTX *ctx, char *file);*/#undef BUFSIZZ#define BUFSIZZ 16*1024static int bufsize=BUFSIZZ;static int accept_socket= -1;#define TEST_CERT "server.pem"#undef PROG#define PROG s_server_mainextern int verify_depth;static char *cipher=NULL;static int s_server_verify=SSL_VERIFY_NONE;static int s_server_session_id_context = 1; /* anything will do */static char *s_cert_file=TEST_CERT,*s_key_file=NULL;static char *s_dcert_file=NULL,*s_dkey_file=NULL;#ifdef FIONBIOstatic int s_nbio=0;#endifstatic int s_nbio_test=0;int s_crlf=0;static SSL_CTX *ctx=NULL;static int www=0;static BIO *bio_s_out=NULL;static int s_debug=0;static int s_quiet=0;static int hack=0;#ifdef MONOLITHstatic void s_server_init(void) { accept_socket=-1; cipher=NULL; s_server_verify=SSL_VERIFY_NONE; s_dcert_file=NULL; s_dkey_file=NULL; s_cert_file=TEST_CERT; s_key_file=NULL;#ifdef FIONBIO s_nbio=0;#endif s_nbio_test=0; ctx=NULL; www=0; bio_s_out=NULL; s_debug=0; s_quiet=0; hack=0; }#endifstatic void sv_usage(void) { BIO_printf(bio_err,"usage: s_server [args ...]\n"); BIO_printf(bio_err,"\n"); BIO_printf(bio_err," -accept arg - port to accept on (default is %d)\n",PORT); BIO_printf(bio_err," -context arg - set session ID context\n"); BIO_printf(bio_err," -verify arg - turn on peer certificate verification\n"); BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); BIO_printf(bio_err," -cert arg - certificate file to use, PEM format assumed\n"); BIO_printf(bio_err," (default is %s)\n",TEST_CERT); BIO_printf(bio_err," -key arg - Private Key file to use, PEM format assumed, in cert file if\n"); BIO_printf(bio_err," not specified (default is %s)\n",TEST_CERT); BIO_printf(bio_err," -dcert arg - second certificate file to use (usually for DSA)\n"); BIO_printf(bio_err," -dkey arg - second private key file to use (usually for DSA)\n"); BIO_printf(bio_err," -dhparam arg - DH parameter file to use, in cert file if not specified\n"); BIO_printf(bio_err," or a default set of parameters is used\n");#ifdef FIONBIO BIO_printf(bio_err," -nbio - Run with non-blocking IO\n");#endif 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," -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," -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," -ssl3 - Just talk SSLv3\n"); BIO_printf(bio_err," -tls1 - Just talk TLSv1\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 BIO_printf(bio_err," -no_dhe - Disable ephemeral DH\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"); }static int local_argc=0;static char **local_argv;#ifdef CHARSET_EBCDICstatic 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_gets(BIO *bp, char *buf, int size);static int ebcdic_puts(BIO *bp, char *str);#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)static BIO_METHOD methods_ebcdic= { BIO_TYPE_EBCDIC_FILTER, "EBCDIC/ASCII filter", ebcdic_write, ebcdic_read, ebcdic_puts, ebcdic_gets, ebcdic_ctrl, ebcdic_new, ebcdic_free, };typedef struct{ size_t alloced; char buff[1];} EBCDIC_OUTBUFF;BIO_METHOD *BIO_f_ebcdic_filter(){ return(&methods_ebcdic);}static int ebcdic_new(BIO *bi){ EBCDIC_OUTBUFF *wbuf; wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024); wbuf->alloced = 1024; wbuf->buff[0] = '\0'; bi->ptr=(char *)wbuf; bi->init=1; bi->flags=0; return(1);}static int ebcdic_free(BIO *a){ if (a == NULL) return(0); if (a->ptr != NULL) OPENSSL_free(a->ptr); a->ptr=NULL; a->init=0; a->flags=0; return(1);} static int ebcdic_read(BIO *b, char *out, int outl){ int ret=0; if (out == NULL || outl == 0) return(0); if (b->next_bio == NULL) return(0); ret=BIO_read(b->next_bio,out,outl); if (ret > 0) ascii2ebcdic(out,out,ret); return(ret);}static int ebcdic_write(BIO *b, char *in, int inl){ EBCDIC_OUTBUFF *wbuf; int ret=0; int num; unsigned char n; if ((in == NULL) || (inl <= 0)) return(0); if (b->next_bio == NULL) return(0); wbuf=(EBCDIC_OUTBUFF *)b->ptr; if (inl > (num = wbuf->alloced)) { num = num + num; /* double the size */ if (num < inl) num = inl; OPENSSL_free(wbuf); wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num); wbuf->alloced = num; wbuf->buff[0] = '\0'; b->ptr=(char *)wbuf; } ebcdic2ascii(wbuf->buff, in, inl); ret=BIO_write(b->next_bio, wbuf->buff, inl); return(ret);}static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr){ long ret; if (b->next_bio == NULL) return(0); switch (cmd) { case BIO_CTRL_DUP: ret=0L; break; default: ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; } return(ret);}static int ebcdic_gets(BIO *bp, char *buf, int size){ int i, ret; if (bp->next_bio == NULL) return(0);/* return(BIO_gets(bp->next_bio,buf,size));*/ for (i=0; i<size-1; ++i) { ret = ebcdic_read(bp,&buf[i],1); if (ret <= 0) break; else if (buf[i] == '\n') { ++i; break; } } if (i < size) buf[i] = '\0'; return (ret < 0 && i == 0) ? ret : i;}static int ebcdic_puts(BIO *bp, char *str){ if (bp->next_bio == NULL) return(0); return ebcdic_write(bp, str, strlen(str));}#endifint MAIN(int, char **);int MAIN(int argc, char *argv[]) { short port=PORT; char *CApath=NULL,*CAfile=NULL; char *context = NULL; char *dhfile = NULL; int badop=0,bugs=0; int ret=1; int off=0; int no_tmp_rsa=0,no_dhe=0,nocert=0; int state=0; SSL_METHOD *meth=NULL;#ifndef NO_DH DH *dh=NULL;#endif#if !defined(NO_SSL2) && !defined(NO_SSL3) meth=SSLv23_server_method();#elif !defined(NO_SSL3) meth=SSLv3_server_method();#elif !defined(NO_SSL2) meth=SSLv2_server_method();#endif local_argc=argc; local_argv=argv; apps_startup();#ifdef MONOLITH s_server_init();#endif if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); verify_depth=0;#ifdef FIONBIO s_nbio=0;#endif s_nbio_test=0; argc--; argv++; while (argc >= 1) { if ((strcmp(*argv,"-port") == 0) || (strcmp(*argv,"-accept") == 0)) { if (--argc < 1) goto bad; if (!extract_port(*(++argv),&port)) goto bad; } else if (strcmp(*argv,"-verify") == 0) { s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE; if (--argc < 1) goto bad; verify_depth=atoi(*(++argv)); BIO_printf(bio_err,"verify depth is %d\n",verify_depth); } else if (strcmp(*argv,"-Verify") == 0) { s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT| SSL_VERIFY_CLIENT_ONCE; if (--argc < 1) goto bad; verify_depth=atoi(*(++argv)); BIO_printf(bio_err,"verify depth is %d, must return a certificate\n",verify_depth); } else if (strcmp(*argv,"-context") == 0) { if (--argc < 1) goto bad; context= *(++argv); } else if (strcmp(*argv,"-cert") == 0) { if (--argc < 1) goto bad; s_cert_file= *(++argv); } else if (strcmp(*argv,"-key") == 0) { if (--argc < 1) goto bad; s_key_file= *(++argv); } else if (strcmp(*argv,"-dhparam") == 0) { if (--argc < 1) goto bad; dhfile = *(++argv); } else if (strcmp(*argv,"-dcert") == 0) { if (--argc < 1) goto bad; s_dcert_file= *(++argv); } else if (strcmp(*argv,"-dkey") == 0) { if (--argc < 1) goto bad; s_dkey_file= *(++argv); } else if (strcmp(*argv,"-nocert") == 0) { nocert=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -