📄 s_server.c
字号:
case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf(bio_s_out,"ERROR\n"); ERR_print_errors(bio_err); ret=1; goto err; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_s_out,"DONE\n"); ret=1; goto err; } } } }err: BIO_printf(bio_s_out,"shutting down SSL\n");#if 1 SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);#else SSL_shutdown(con);#endif if (con != NULL) SSL_free(con); BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); if (buf != NULL) { memset(buf,0,bufsize); OPENSSL_free(buf); } if (ret >= 0) BIO_printf(bio_s_out,"ACCEPT\n"); return(ret); }static void close_accept_socket(void) { BIO_printf(bio_err,"shutdown accept socket\n"); if (accept_socket >= 0) { SHUTDOWN2(accept_socket); } }static int init_ssl_connection(SSL *con) { int i; const char *str; X509 *peer; long verify_error; MS_STATIC char buf[BUFSIZ]; if ((i=SSL_accept(con)) <= 0) { if (BIO_sock_should_retry(i)) { BIO_printf(bio_s_out,"DELAY\n"); return(1); } BIO_printf(bio_err,"ERROR\n"); verify_error=SSL_get_verify_result(con); if (verify_error != X509_V_OK) { BIO_printf(bio_err,"verify error:%s\n", X509_verify_cert_error_string(verify_error)); } else ERR_print_errors(bio_err); return(0); } PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); peer=SSL_get_peer_certificate(con); if (peer != NULL) { 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); BIO_printf(bio_s_out,"subject=%s\n",buf); X509_NAME_oneline(X509_get_issuer_name(peer),buf,BUFSIZ); BIO_printf(bio_s_out,"issuer=%s\n",buf); X509_free(peer); } if (SSL_get_shared_ciphers(con,buf,BUFSIZ) != 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)"); if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & TLS1_FLAGS_TLS_PADDING_BUG) BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n"); return(1); }#ifndef NO_DHstatic DH *load_dh_param(char *dhfile) { DH *ret=NULL; BIO *bio; if ((bio=BIO_new_file(dhfile,"r")) == NULL) goto err; ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);err: if (bio != NULL) BIO_free(bio); return(ret); }#endif#if 0static int load_CA(SSL_CTX *ctx, char *file) { FILE *in; X509 *x=NULL; if ((in=fopen(file,"r")) == NULL) return(0); for (;;) { if (PEM_read_X509(in,&x,NULL) == NULL) break; SSL_CTX_add_client_CA(ctx,x); } if (x != NULL) X509_free(x); fclose(in); return(1); }#endifstatic int www_body(char *hostname, int s, unsigned char *context) { char *buf=NULL; int ret=1; int i,j,k,blank,dot; struct stat st_buf; SSL *con; SSL_CIPHER *c; BIO *io,*ssl_bio,*sbio; long total_bytes; buf=OPENSSL_malloc(bufsize); if (buf == NULL) return(0); io=BIO_new(BIO_f_buffer()); ssl_bio=BIO_new(BIO_f_ssl()); if ((io == NULL) || (ssl_bio == NULL)) 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 /* lets make the output buffer a reasonable size */ if (!BIO_set_write_buffer_size(io,bufsize)) goto err; if ((con=SSL_new(ctx)) == NULL) goto err; if(context) SSL_set_session_id_context(con, context, strlen((char *)context)); 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); */ BIO_set_ssl(ssl_bio,con,BIO_CLOSE); BIO_push(io,ssl_bio);#ifdef CHARSET_EBCDIC io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io);#endif 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); } blank=0; for (;;) { if (hack) { i=SSL_accept(con); switch (SSL_get_error(con,i)) { case SSL_ERROR_NONE: break; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: continue; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: case SSL_ERROR_ZERO_RETURN: ret=1; goto err; /* break; */ } SSL_renegotiate(con); SSL_write(con,NULL,0); } i=BIO_gets(io,buf,bufsize-1); if (i < 0) /* error */ { if (!BIO_should_retry(io)) { if (!s_quiet) ERR_print_errors(bio_err); goto err; } else { BIO_printf(bio_s_out,"read R BLOCK\n");#ifndef MSDOS sleep(1);#endif continue; } } else if (i == 0) /* end of input */ { ret=1; goto end; } /* else we have data */ if ( ((www == 1) && (strncmp("GET ",buf,4) == 0)) || ((www == 2) && (strncmp("GET /stats ",buf,10) == 0))) { char *p; X509 *peer; STACK_OF(SSL_CIPHER) *sk; static char *space=" "; BIO_puts(io,"HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n"); BIO_puts(io,"<HTML><BODY BGCOLOR=\"#ffffff\">\n"); BIO_puts(io,"<pre>\n");/* BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/ BIO_puts(io,"\n"); for (i=0; i<local_argc; i++) { BIO_puts(io,local_argv[i]); BIO_write(io," ",1); } BIO_puts(io,"\n"); /* The following is evil and should not really * be done */ BIO_printf(io,"Ciphers supported in s_server binary\n"); sk=SSL_get_ciphers(con); j=sk_SSL_CIPHER_num(sk); for (i=0; i<j; i++) { c=sk_SSL_CIPHER_value(sk,i); BIO_printf(io,"%-11s:%-25s", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); if ((((i+1)%2) == 0) && (i+1 != j)) BIO_puts(io,"\n"); } BIO_puts(io,"\n"); p=SSL_get_shared_ciphers(con,buf,bufsize); if (p != NULL) { BIO_printf(io,"---\nCiphers common between both SSL end points:\n"); j=i=0; while (*p) { if (*p == ':') { BIO_write(io,space,26-j); i++; j=0; BIO_write(io,((i%3)?" ":"\n"),1); } else { BIO_write(io,p,1); j++; } p++; } BIO_puts(io,"\n"); } BIO_printf(io,((con->hit) ?"---\nReused, " :"---\nNew, ")); c=SSL_get_current_cipher(con); BIO_printf(io,"%s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); SSL_SESSION_print(io,SSL_get_session(con)); BIO_printf(io,"---\n"); print_stats(io,SSL_get_SSL_CTX(con)); BIO_printf(io,"---\n"); peer=SSL_get_peer_certificate(con); if (peer != NULL) { BIO_printf(io,"Client certificate\n"); X509_print(io,peer); PEM_write_bio_X509(io,peer); } else BIO_puts(io,"no client certificate available\n"); BIO_puts(io,"</BODY></HTML>\r\n\r\n"); break; } else if ((www == 2) && (strncmp("GET /",buf,5) == 0)) { BIO *file; char *p,*e; static char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n"; /* skip the '/' */ p= &(buf[5]); dot=0; for (e=p; *e != '\0'; e++) { if (e[0] == ' ') break; if ( (e[0] == '.') && (strncmp(&(e[-1]),"/../",4) == 0)) dot=1; } if (*e == '\0') { BIO_puts(io,text); BIO_printf(io,"'%s' is an invalid file name\r\n",p); break; } *e='\0'; if (dot) { BIO_puts(io,text); BIO_printf(io,"'%s' contains '..' reference\r\n",p); break; } if (*p == '/') { BIO_puts(io,text); BIO_printf(io,"'%s' is an invalid path\r\n",p); break; } /* append if a directory lookup */ if (e[-1] == '/') strcat(p,"index.html"); /* if a directory, do the index thang */ if (stat(p,&st_buf) < 0) { BIO_puts(io,text); BIO_printf(io,"Error accessing '%s'\r\n",p); ERR_print_errors(io); break; } if (S_ISDIR(st_buf.st_mode)) { strcat(p,"/index.html"); } if ((file=BIO_new_file(p,"r")) == NULL) { BIO_puts(io,text); BIO_printf(io,"Error opening '%s'\r\n",p); ERR_print_errors(io); break; } 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"); /* send the file */ total_bytes=0; for (;;) { i=BIO_read(file,buf,bufsize); if (i <= 0) break;#ifdef RENEG total_bytes+=i; fprintf(stderr,"%d\n",i); if (total_bytes > 3*1024) { total_bytes=0; fprintf(stderr,"RENEGOTIATE\n"); SSL_renegotiate(con); }#endif for (j=0; j<i; ) {#ifdef RENEG{ static count=0; if (++count == 13) { SSL_renegotiate(con); } }#endif k=BIO_write(io,&(buf[j]),i-j); if (k <= 0) { if (!BIO_should_retry(io)) goto write_error; else { BIO_printf(bio_s_out,"rwrite W BLOCK\n"); } } else { j+=k; } } }write_error: BIO_free(file); break; } } for (;;) { i=(int)BIO_flush(io); if (i <= 0) { if (!BIO_should_retry(io)) break; } else break; }end:#if 1 /* make sure we re-use sessions */ SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);#else /* This kills performance *//* SSL_shutdown(con); A shutdown gets sent in the * BIO_free_all(io) procession */#endiferr: if (ret >= 0) BIO_printf(bio_s_out,"ACCEPT\n"); 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_RSAstatic RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) { static RSA *rsa_tmp=NULL; if (rsa_tmp == NULL) { if (!s_quiet) { BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength); (void)BIO_flush(bio_err); } rsa_tmp=RSA_generate_key(keylength,RSA_F4,NULL,NULL); if (!s_quiet) { BIO_printf(bio_err,"\n"); (void)BIO_flush(bio_err); } } return(rsa_tmp); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -