📄 s_server.c
字号:
} else if (strcmp(*argv,"-CApath") == 0) { if (--argc < 1) goto bad; CApath= *(++argv); } else if (strcmp(*argv,"-cipher") == 0) { if (--argc < 1) goto bad; cipher= *(++argv); } else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); }#ifdef FIONBIO else if (strcmp(*argv,"-nbio") == 0) { s_nbio=1; }#endif else if (strcmp(*argv,"-nbio_test") == 0) {#ifdef FIONBIO s_nbio=1;#endif s_nbio_test=1; } else if (strcmp(*argv,"-debug") == 0) { s_debug=1; } else if (strcmp(*argv,"-hack") == 0) { hack=1; } else if (strcmp(*argv,"-state") == 0) { state=1; } else if (strcmp(*argv,"-crlf") == 0) { s_crlf=1; } else if (strcmp(*argv,"-quiet") == 0) { s_quiet=1; } else if (strcmp(*argv,"-bugs") == 0) { bugs=1; } else if (strcmp(*argv,"-no_tmp_rsa") == 0) { no_tmp_rsa=1; } else if (strcmp(*argv,"-no_dhe") == 0) { no_dhe=1; } else if (strcmp(*argv,"-www") == 0) { www=1; } else if (strcmp(*argv,"-WWW") == 0) { www=2; } 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 else if (strcmp(*argv,"-ssl2") == 0) { meth=SSLv2_server_method(); }#endif#ifndef NO_SSL3 else if (strcmp(*argv,"-ssl3") == 0) { meth=SSLv3_server_method(); }#endif#ifndef NO_TLS1 else if (strcmp(*argv,"-tls1") == 0) { meth=TLSv1_server_method(); }#endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); badop=1; break; } argc--; argv++; } if (badop) {bad: sv_usage(); goto end; } app_RAND_load_file(NULL, bio_err, 0); if (bio_s_out == NULL) { if (s_quiet && !s_debug) { bio_s_out=BIO_new(BIO_s_null()); } else { if (bio_s_out == NULL) bio_s_out=BIO_new_fp(stdout,BIO_NOCLOSE); } }#if !defined(NO_RSA) || !defined(NO_DSA) if (nocert)#endif { s_cert_file=NULL; s_key_file=NULL; s_dcert_file=NULL; s_dkey_file=NULL; } SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); ctx=SSL_CTX_new(meth); if (ctx == NULL) { ERR_print_errors(bio_err); goto end; } 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); SSL_CTX_sess_set_cache_size(ctx,128);#if 0 if (cipher == NULL) cipher=getenv("SSL_CIPHER");#endif#if 0 if (s_cert_file == NULL) { BIO_printf(bio_err,"You must specify a certificate file for the server to use\n"); goto end; }#endif if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) || (!SSL_CTX_set_default_verify_paths(ctx))) { /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */ ERR_print_errors(bio_err); /* goto end; */ }#ifndef NO_DH if (!no_dhe) { dh=load_dh_param(dhfile ? dhfile : s_cert_file); if (dh != NULL) { BIO_printf(bio_s_out,"Setting temp DH parameters\n"); } else { BIO_printf(bio_s_out,"Using default temp DH parameters\n"); dh=get_dh512(); } (void)BIO_flush(bio_s_out); SSL_CTX_set_tmp_dh(ctx,dh); DH_free(dh); }#endif if (!set_cert_stuff(ctx,s_cert_file,s_key_file)) goto end; if (s_dcert_file != NULL) { if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file)) goto end; }#ifndef NO_RSA#if 1 SSL_CTX_set_tmp_rsa_callback(ctx,tmp_rsa_cb);#else if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) { RSA *rsa; BIO_printf(bio_s_out,"Generating temp (512 bit) RSA key..."); BIO_flush(bio_s_out); rsa=RSA_generate_key(512,RSA_F4,NULL); if (!SSL_CTX_set_tmp_rsa(ctx,rsa)) { ERR_print_errors(bio_err); goto end; } RSA_free(rsa); BIO_printf(bio_s_out,"\n"); }#endif#endif if (cipher != NULL) if(!SSL_CTX_set_cipher_list(ctx,cipher)) { BIO_printf(bio_err,"error setting cipher list\n"); ERR_print_errors(bio_err); goto end; } SSL_CTX_set_verify(ctx,s_server_verify,verify_callback); SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context, sizeof s_server_session_id_context); if (CAfile != NULL) SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); BIO_printf(bio_s_out,"ACCEPT\n"); if (www) do_server(port,&accept_socket,www_body, context); else do_server(port,&accept_socket,sv_body, context); print_stats(bio_s_out,ctx); ret=0;end: if (ctx != NULL) SSL_CTX_free(ctx); if (bio_s_out != NULL) { BIO_free(bio_s_out); bio_s_out=NULL; } EXIT(ret); }static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) { BIO_printf(bio,"%4ld items in the session cache\n", SSL_CTX_sess_number(ssl_ctx)); BIO_printf(bio,"%4d client connects (SSL_connect())\n", SSL_CTX_sess_connect(ssl_ctx)); BIO_printf(bio,"%4d client renegotiates (SSL_connect())\n", SSL_CTX_sess_connect_renegotiate(ssl_ctx)); BIO_printf(bio,"%4d client connects that finished\n", SSL_CTX_sess_connect_good(ssl_ctx)); BIO_printf(bio,"%4d server accepts (SSL_accept())\n", SSL_CTX_sess_accept(ssl_ctx)); BIO_printf(bio,"%4d server renegotiates (SSL_accept())\n", SSL_CTX_sess_accept_renegotiate(ssl_ctx)); BIO_printf(bio,"%4d server accepts that finished\n", SSL_CTX_sess_accept_good(ssl_ctx)); BIO_printf(bio,"%4d session cache hits\n",SSL_CTX_sess_hits(ssl_ctx)); BIO_printf(bio,"%4d session cache misses\n",SSL_CTX_sess_misses(ssl_ctx)); BIO_printf(bio,"%4d session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx)); BIO_printf(bio,"%4d callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx)); BIO_printf(bio,"%4d cache full overflows (%d allowed)\n", SSL_CTX_sess_cache_full(ssl_ctx), SSL_CTX_sess_get_cache_size(ssl_ctx)); }static int sv_body(char *hostname, int s, unsigned char *context) { char *buf=NULL; fd_set readfds; int ret=1,width; int k,i; unsigned long l; SSL *con=NULL; BIO *sbio;#ifdef WINDOWS struct timeval tv;#endif if ((buf=OPENSSL_malloc(bufsize)) == NULL) { BIO_printf(bio_err,"out of memory\n"); goto err; }#ifdef FIONBIO if (s_nbio) { unsigned long sl=1; if (!s_quiet) BIO_printf(bio_err,"turning on non blocking io\n"); if (BIO_socket_ioctl(s,FIONBIO,&sl) < 0) ERR_print_errors(bio_err); }#endif if (con == NULL) { con=SSL_new(ctx); if(context) SSL_set_session_id_context(con, context, strlen((char *)context)); } SSL_clear(con); sbio=BIO_new_socket(s,BIO_NOCLOSE); if (s_nbio_test) { BIO *test; test=BIO_new(BIO_f_nbio_test()); sbio=BIO_push(test,sbio); } SSL_set_bio(con,sbio,sbio); SSL_set_accept_state(con); /* SSL_set_fd(con,s); */ if (s_debug) { con->debug=1; BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); BIO_set_callback_arg(SSL_get_rbio(con),bio_s_out); } width=s+1; for (;;) { int read_from_terminal; int read_from_sslcon; read_from_terminal = 0; read_from_sslcon = SSL_pending(con); if (!read_from_sslcon) { FD_ZERO(&readfds);#ifndef WINDOWS FD_SET(fileno(stdin),&readfds);#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()) read_from_terminal = 1;#else 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) { int j, lf_num; i=read(fileno(stdin), buf, bufsize/2); lf_num = 0; /* both loops are skipped when i <= 0 */ for (j = 0; j < i; j++) if (buf[j] == '\n') lf_num++; for (j = i-1; j >= 0; j--) { buf[j+lf_num] = buf[j]; if (buf[j] == '\n') { lf_num--; i++; buf[j+lf_num] = '\r'; } } assert(lf_num == 0); } else i=read(fileno(stdin),buf,bufsize); if (!s_quiet) { if ((i <= 0) || (buf[0] == 'Q')) { BIO_printf(bio_s_out,"DONE\n"); SHUTDOWN(s); close_accept_socket(); ret= -11; goto err; } if ((i <= 0) || (buf[0] == 'q')) { BIO_printf(bio_s_out,"DONE\n"); SHUTDOWN(s); /* close_accept_socket(); ret= -11;*/ goto err; } if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) { SSL_renegotiate(con); i=SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n",i); i=0; /*13; */ continue; /* strcpy(buf,"server side RE-NEGOTIATE\n"); */ } if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) { SSL_set_verify(con, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,NULL); SSL_renegotiate(con); i=SSL_do_handshake(con); printf("SSL_do_handshake -> %d\n",i); i=0; /* 13; */ continue; /* strcpy(buf,"server side RE-NEGOTIATE asking for client cert\n"); */ } if (buf[0] == 'P') { static char *str="Lets print some clear text\n"; BIO_write(SSL_get_wbio(con),str,strlen(str)); } if (buf[0] == 'S') { print_stats(bio_s_out,SSL_get_SSL_CTX(con)); } }#ifdef CHARSET_EBCDIC ebcdic2ascii(buf,buf,i);#endif l=k=0; for (;;) { /* should do a select for the write */#ifdef RENEG{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }#endif k=SSL_write(con,&(buf[l]),(unsigned int)i); switch (SSL_get_error(con,k)) { case SSL_ERROR_NONE: break; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_s_out,"Write BLOCK\n"); break; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf(bio_s_out,"ERROR\n"); ERR_print_errors(bio_err); ret=1; goto err; /* break; */ case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_s_out,"DONE\n"); ret=1; goto err; } l+=k; i-=k; if (i <= 0) break; } } if (read_from_sslcon) { if (!SSL_is_init_finished(con)) { i=init_ssl_connection(con); if (i < 0) { ret=0; goto err; } else if (i == 0) { ret=1; goto err; } } else {again: i=SSL_read(con,(char *)buf,bufsize); switch (SSL_get_error(con,i)) { case SSL_ERROR_NONE:#ifdef CHARSET_EBCDIC ascii2ebcdic(buf,buf,i);#endif write(fileno(stdout),buf, (unsigned int)i); if (SSL_pending(con)) goto again; break; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_s_out,"Read BLOCK\n"); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -