Newer
Older
#ifndef OPENSSL_NO_RSA
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))
{
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
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)
print_stats(bio_s_out,ctx);
ret=0;
end:
if (ctx != NULL) SSL_CTX_free(ctx);
if (s_cert)
X509_free(s_cert);
if (s_dcert)
X509_free(s_dcert);
if (s_key)
EVP_PKEY_free(s_key);
if (s_dkey)
EVP_PKEY_free(s_dkey);
if (pass)
OPENSSL_free(pass);
if (dpass)
OPENSSL_free(dpass);
if (bio_s_out != NULL)
{
BIO_free(bio_s_out);
bio_s_out=NULL;
}
apps_shutdown();
OPENSSL_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,"%4ld client connects (SSL_connect())\n",
SSL_CTX_sess_connect(ssl_ctx));
BIO_printf(bio,"%4ld client renegotiates (SSL_connect())\n",
SSL_CTX_sess_connect_renegotiate(ssl_ctx));
BIO_printf(bio,"%4ld client connects that finished\n",
SSL_CTX_sess_connect_good(ssl_ctx));
BIO_printf(bio,"%4ld server accepts (SSL_accept())\n",
SSL_CTX_sess_accept(ssl_ctx));
BIO_printf(bio,"%4ld server renegotiates (SSL_accept())\n",
SSL_CTX_sess_accept_renegotiate(ssl_ctx));
BIO_printf(bio,"%4ld server accepts that finished\n",
SSL_CTX_sess_accept_good(ssl_ctx));
BIO_printf(bio,"%4ld session cache hits\n",SSL_CTX_sess_hits(ssl_ctx));
BIO_printf(bio,"%4ld session cache misses\n",SSL_CTX_sess_misses(ssl_ctx));
BIO_printf(bio,"%4ld session cache timeouts\n",SSL_CTX_sess_timeouts(ssl_ctx));
BIO_printf(bio,"%4ld callback cache hits\n",SSL_CTX_sess_cb_hits(ssl_ctx));
BIO_printf(bio,"%4ld cache full overflows (%ld 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;
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
Dr. Stephen Henson
committed
struct timeval tv;
#endif
Richard Levitte
committed
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);
#ifndef OPENSSL_NO_KRB5
Richard Levitte
committed
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);
Richard Levitte
committed
}
#endif /* OPENSSL_NO_KRB5 */
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_callback);
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 (;;)
{
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);
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE)
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 *).
*/
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
/* Under DOS (non-djgpp) and 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;
Dr. Stephen Henson
committed
#else
i=select(width,(void *)&readfds,NULL,NULL,NULL);
if (i <= 0) continue;
if (FD_ISSET(fileno(stdin),&readfds))
read_from_terminal = 1;
Dr. Stephen Henson
committed
#endif
if (FD_ISSET(s,&readfds))
read_from_sslcon = 1;
}
if (read_from_terminal)
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
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') &&
{
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')
{
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); } }
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 (!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))
#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;
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)
{
OPENSSL_cleanse(buf,bufsize);
Richard Levitte
committed
OPENSSL_free(buf);
}
if (ret >= 0)
BIO_printf(bio_s_out,"ACCEPT\n");
return(ret);
}
{
BIO_printf(bio_err,"shutdown accept socket\n");
if (accept_socket >= 0)
{
SHUTDOWN2(accept_socket);
}
}
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
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,sizeof buf);
BIO_printf(bio_s_out,"subject=%s\n",buf);
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,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)");
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");
#ifndef OPENSSL_NO_KRB5
if (con->kssl_ctx->client_princ != NULL)
{
BIO_printf(bio_s_out,"Kerberos peer principal is %s\n",
con->kssl_ctx->client_princ);
}
#endif /* OPENSSL_NO_KRB5 */
return(1);
}
#ifndef OPENSSL_NO_DH
Dr. Stephen Henson
committed
static DH *load_dh_param(char *dhfile)
{
DH *ret=NULL;
BIO *bio;
Dr. Stephen Henson
committed
if ((bio=BIO_new_file(dhfile,"r")) == NULL)
ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
err:
if (bio != NULL) BIO_free(bio);
return(ret);
}
{
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);
}
#endif
static 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;
Richard Levitte
committed
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)
{
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;
#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));
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_callback);
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);
}
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
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");
#if defined(OPENSSL_SYS_NETWARE)
delay(1000);
#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
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;
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);
for (i=0; i<j; 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");
else if ((www == 2 || www == 3)
&& (strncmp("GET /",buf,5) == 0))
{
BIO *file;
char *p,*e;
static const char *text="HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
/* skip the '/' */
p= &(buf[5]);
dot = 1;
for (e=p; *e != '\0'; e++)
{
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 */
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
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");
#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)
{
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);
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");
}
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);
}
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))
else
{
BIO_printf(bio_s_out,"rwrite W BLOCK\n");
}
}
else
{
j+=k;
}
}
}
BIO_free(file);
break;
}
}
for (;;)
{
i=(int)BIO_flush(io);
if (i <= 0)
{
if (!BIO_should_retry(io))
break;
}
else
break;
}
end:
/* make sure we re-use sessions */
SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
#else
/* SSL_shutdown(con); A shutdown gets sent in the
* BIO_free_all(io) procession */
#endif
err:
if (ret >= 0)
BIO_printf(bio_s_out,"ACCEPT\n");
Richard Levitte
committed
if (buf != NULL) OPENSSL_free(buf);
if (io != NULL) BIO_free_all(io);
/* if (ssl_bio != NULL) BIO_free(ssl_bio);*/
return(ret);
}
#ifndef OPENSSL_NO_RSA
static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
BIGNUM *bn = NULL;
static RSA *rsa_tmp=NULL;
if (!rsa_tmp && ((bn = BN_new()) == NULL))
BIO_printf(bio_err,"Allocation error in generating RSA key\n");
if (!rsa_tmp && bn)
{
if (!s_quiet)
{
BIO_printf(bio_err,"Generating temp (%d bit) RSA key...",keylength);
if(!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
!RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL))
Geoff Thorpe
committed
{
if(rsa_tmp) RSA_free(rsa_tmp);
rsa_tmp = NULL;
}
if (!s_quiet)
{
BIO_printf(bio_err,"\n");
BN_free(bn);
}
return(rsa_tmp);
}
#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);
}
(++count < MAX_SESSION_ID_ATTEMPTS));
if(count >= MAX_SESSION_ID_ATTEMPTS)
return 0;
return 1;
}