Newer
Older
servername= *(++argv);
/* meth=TLSv1_client_method(); */
}
#endif
else if (strcmp(*argv,"-jpake") == 0)
{
if (--argc < 1) goto bad;
jpake_secret = *++argv;
}
else if (strcmp(*argv,"-use_srtp") == 0)
{
if (--argc < 1) goto bad;
srtp_profiles = *(++argv);
}
else if (strcmp(*argv,"-keymatexport") == 0)
{
if (--argc < 1) goto bad;
keymatexportlabel= *(++argv);
}
else if (strcmp(*argv,"-keymatexportlen") == 0)
{
if (--argc < 1) goto bad;
keymatexportlen=atoi(*(++argv));
if (keymatexportlen == 0) goto bad;
}
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
badop=1;
break;
}
argc--;
argv++;
}
if (badop)
{
bad:
sc_usage();
goto end;
}
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
if (jpake_secret)
{
if (psk_key)
{
BIO_printf(bio_err,
"Can't use JPAKE and PSK together\n");
goto end;
}
psk_identity = "JPAKE";
}
if (cipher)
{
BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
goto end;
}
cipher = "PSK";
#endif
Richard Levitte
committed
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
next_proto.status = -1;
if (next_proto_neg_in)
{
next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
if (next_proto.data == NULL)
{
BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
goto end;
}
}
else
next_proto.data = NULL;
#endif
#ifndef OPENSSL_NO_ENGINE
Richard Levitte
committed
e = setup_engine(bio_err, engine_id, 1);
if (ssl_client_engine_id)
{
ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
if (!ssl_client_engine)
{
BIO_printf(bio_err,
"Error getting client auth engine\n");
goto end;
}
}
if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
{
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
if (key_file == NULL)
key_file = cert_file;
if (key_file)
key = load_key(bio_err, key_file, key_format, 0, pass, e,
"client certificate private key file");
if (!key)
{
ERR_print_errors(bio_err);
goto end;
}
if (cert_file)
cert = load_cert(bio_err,cert_file,cert_format,
NULL, e, "client certificate file");
if (!cert)
{
ERR_print_errors(bio_err);
goto end;
}
Richard Levitte
committed
if (chain_file)
{
chain = load_certs(bio_err, chain_file,FORMAT_PEM,
NULL, e, "client certificate chain");
if (!chain)
goto end;
}
if (crl_file)
{
X509_CRL *crl;
crl = load_crl(crl_file, crl_format);
if (!crl)
{
BIO_puts(bio_err, "Error loading CRL\n");
ERR_print_errors(bio_err);
goto end;
}
crls = sk_X509_CRL_new_null();
if (!crls || !sk_X509_CRL_push(crls, crl))
{
BIO_puts(bio_err, "Error adding CRL\n");
ERR_print_errors(bio_err);
X509_CRL_free(crl);
goto end;
}
}
if (!load_excert(&exc, bio_err))
goto end;
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_c_out == NULL)
{
{
bio_c_out=BIO_new(BIO_s_null());
if (c_msg && !bio_c_msg)
bio_c_msg=BIO_new_fp(stdout,BIO_NOCLOSE);
}
else
{
if (bio_c_out == NULL)
bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
}
}
#ifndef OPENSSL_NO_SRP
if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
{
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
#endif
ctx=SSL_CTX_new(meth);
if (ctx == NULL)
{
ERR_print_errors(bio_err);
goto end;
}
if (vpm)
SSL_CTX_set1_param(ctx, vpm);
if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1))
Dr. Stephen Henson
committed
{
ERR_print_errors(bio_err);
goto end;
}
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
crls, crl_download))
Dr. Stephen Henson
committed
{
BIO_printf(bio_err, "Error loading store locations\n");
ERR_print_errors(bio_err);
goto end;
}
#ifndef OPENSSL_NO_ENGINE
if (ssl_client_engine)
{
if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
{
BIO_puts(bio_err, "Error setting client auth engine\n");
ERR_print_errors(bio_err);
ENGINE_free(ssl_client_engine);
goto end;
}
ENGINE_free(ssl_client_engine);
}
#endif
#ifndef OPENSSL_NO_PSK
#ifdef OPENSSL_NO_JPAKE
if (psk_key != NULL)
#else
if (psk_key != NULL || jpake_secret)
{
if (c_debug)
BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
}
if (srtp_profiles != NULL)
SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
if (exc) ssl_ctx_set_excert(ctx, exc);
/* DTLS: partial reads end up discarding unread UDP bytes :-(
* Setting read ahead solves this problem.
*/
if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.data)
SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
#endif
if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
#if 0
else
SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
#endif
SSL_CTX_set_verify(ctx,verify,verify_callback);
if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
(!SSL_CTX_set_default_verify_paths(ctx)))
{
/* BIO_printf(bio_err,"error setting default verify locations\n"); */
ERR_print_errors(bio_err);
ssl_ctx_add_crls(ctx, crls, crl_download);
if (!set_cert_key_stuff(ctx,cert,key,chain,build_chain))
goto end;
#ifndef OPENSSL_NO_TLSEXT
tlsextcbp.biodebug = bio_err;
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
{
BIO_printf(bio_err,"Unable to set SRP username\n");
goto end;
}
srp_arg.msg = c_msg;
srp_arg.debug = c_debug ;
SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
if (c_msg || c_debug || srp_arg.amp == 0)
SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
}
#endif
if (c_proof_debug)
SSL_CTX_set_tlsext_authz_server_audit_proof_cb(ctx,
audit_proof_cb);
Dr. Stephen Henson
committed
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
if (sess_in)
{
SSL_SESSION *sess;
BIO *stmp = BIO_new_file(sess_in, "r");
if (!stmp)
{
BIO_printf(bio_err, "Can't open session file %s\n",
sess_in);
ERR_print_errors(bio_err);
goto end;
}
sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
BIO_free(stmp);
if (!sess)
{
BIO_printf(bio_err, "Can't open session file %s\n",
sess_in);
ERR_print_errors(bio_err);
goto end;
}
SSL_set_session(con, sess);
SSL_SESSION_free(sess);
}
#ifndef OPENSSL_NO_TLSEXT
if (!SSL_set_tlsext_host_name(con,servername))
BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
ERR_print_errors(bio_err);
goto end;
#ifndef OPENSSL_NO_KRB5
if (con && (kctx = kssl_ctx_new()) != NULL)
Richard Levitte
committed
{
SSL_set0_kssl_ctx(con, kctx);
kssl_ctx_setstring(kctx, KSSL_SERVER, host);
Richard Levitte
committed
}
#endif /* OPENSSL_NO_KRB5 */
/* SSL_set_cipher_list(con,"RC4-MD5"); */
#if 0
#ifdef TLSEXT_TYPE_opaque_prf_input
SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
SHUTDOWN(s);
goto end;
}
BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
#ifdef FIONBIO
if (c_nbio)
{
unsigned long l=1;
BIO_printf(bio_c_out,"turning on non blocking io\n");
if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
{
ERR_print_errors(bio_err);
goto end;
}
if (c_Pause & 0x01) SSL_set_debug(con, 1);
if ( SSL_version(con) == DTLS1_VERSION)
{
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
if (getsockname(s, &peer, (void *)&peerlen) < 0)
{
BIO_printf(bio_err, "getsockname:errno=%d\n",
get_last_socket_error());
SHUTDOWN(s);
goto end;
}
{
timeout.tv_sec = 0;
timeout.tv_usec = DGRAM_RCV_TIMEOUT;
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
timeout.tv_sec = 0;
timeout.tv_usec = DGRAM_SND_TIMEOUT;
BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
}
}
else
/* want to do MTU discovery */
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
}
else
sbio=BIO_new_socket(s,BIO_NOCLOSE);
if (nbio_test)
{
BIO *test;
test=BIO_new(BIO_f_nbio_test());
sbio=BIO_push(test,sbio);
}
if (c_debug)
{
SSL_set_debug(con, 1);
BIO_set_callback(sbio,bio_dump_callback);
BIO_set_callback_arg(sbio,(char *)bio_c_out);
#ifndef OPENSSL_NO_SSL_TRACE
if (c_msg == 2)
SSL_set_msg_callback(con, SSL_trace);
else
#endif
SSL_set_msg_callback(con, msg_cb);
SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
Dr. Stephen Henson
committed
#ifndef OPENSSL_NO_TLSEXT
if (c_tlsextdebug)
{
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_c_out);
}
if (c_status_req)
{
SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
#if 0
{
STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
OCSP_RESPID *id = OCSP_RESPID_new();
id->value.byKey = ASN1_OCTET_STRING_new();
id->type = V_OCSP_RESPID_KEY;
ASN1_STRING_set(id->value.byKey, "Hello World", -1);
sk_OCSP_RESPID_push(ids, id);
SSL_set_tlsext_status_ids(con, ids);
}
#endif
}
Dr. Stephen Henson
committed
#endif
if (jpake_secret)
jpake_client_auth(bio_c_out, sbio, jpake_secret);
SSL_set_bio(con,sbio,sbio);
SSL_set_connect_state(con);
/* ok, lets connect */
width=SSL_get_fd(con)+1;
read_tty=1;
write_tty=0;
tty_on=0;
read_ssl=1;
write_ssl=1;
cbuf_len=0;
cbuf_off=0;
sbuf_len=0;
sbuf_off=0;
/* This is an ugly hack that does a lot of assumptions */
/* We do have to handle multi-line responses which may come
in a single packet or not. We therefore have to use
BIO_gets() which does need a buffering BIO. So during
the initial chitchat we do push a buffering BIO into the
chain that is removed again later on to not disturb the
rest of the s_client operation. */
if (starttls_proto == PROTO_SMTP)
{
int foundit=0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from SMTP */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
}
while (mbuf_len>3 && mbuf[3]=='-');
/* STARTTLS command requires EHLO... */
BIO_printf(fbio,"EHLO openssl.client.net\r\n");
/* wait for multi-line response to end EHLO SMTP response */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
if (strstr(mbuf,"STARTTLS"))
foundit=1;
}
while (mbuf_len>3 && mbuf[3]=='-');
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't found starttls in server response,"
" try anyway...\n");
BIO_printf(sbio,"STARTTLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_POP3)
Lutz Jänicke
committed
{
BIO_read(sbio,mbuf,BUFSIZZ);
BIO_printf(sbio,"STLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_IMAP)
{
int foundit=0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
BIO_gets(fbio,mbuf,BUFSIZZ);
/* STARTTLS command requires CAPABILITY... */
BIO_printf(fbio,". CAPABILITY\r\n");
/* wait for multi-line CAPABILITY response */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
if (strstr(mbuf,"STARTTLS"))
foundit=1;
}
while (mbuf_len>3 && mbuf[0]!='.');
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't found STARTTLS in server response,"
" try anyway...\n");
BIO_printf(sbio,". STARTTLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
else if (starttls_proto == PROTO_FTP)
{
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from FTP */
do
{
mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
}
while (mbuf_len>3 && mbuf[3]=='-');
BIO_pop(fbio);
BIO_free(fbio);
BIO_printf(sbio,"AUTH TLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
if (starttls_proto == PROTO_XMPP)
{
int seen = 0;
BIO_printf(sbio,"<stream:stream "
"xmlns:stream='http://etherx.jabber.org/streams' "
"xmlns='jabber:client' to='%s' version='1.0'>", host);
seen = BIO_read(sbio,mbuf,BUFSIZZ);
mbuf[seen] = 0;
while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
{
if (strstr(mbuf, "/stream:features>"))
goto shut;
seen = BIO_read(sbio,mbuf,BUFSIZZ);
mbuf[seen] = 0;
}
BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
seen = BIO_read(sbio,sbuf,BUFSIZZ);
sbuf[seen] = 0;
if (!strstr(sbuf, "<proceed"))
goto shut;
mbuf[0] = 0;
}
for (;;)
{
FD_ZERO(&readfds);
FD_ZERO(&writefds);
if ((SSL_version(con) == DTLS1_VERSION) &&
DTLSv1_get_timeout(con, &timeout))
timeoutp = &timeout;
else
timeoutp = NULL;
if (SSL_in_init(con) && !SSL_total_renegotiations(con))
{
in_init=1;
tty_on=0;
}
else
{
tty_on=1;
if (in_init)
{
in_init=0;
#if 0 /* This test doesn't really work as intended (needs to be fixed) */
#ifndef OPENSSL_NO_TLSEXT
if (servername != NULL && !SSL_session_reused(con))
{
BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
}
Dr. Stephen Henson
committed
if (sess_out)
{
BIO *stmp = BIO_new_file(sess_out, "w");
if (stmp)
{
PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
BIO_free(stmp);
}
else
BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
}
Dr. Stephen Henson
committed
if (c_brief)
{
BIO_puts(bio_err,
"CONNECTION ESTABLISHED\n");
print_ssl_summary(bio_err, con);
}
print_stuff(bio_c_out,con,full_log);
if (full_log > 0) full_log--;
Lutz Jänicke
committed
if (starttls_proto)
{
BIO_printf(bio_err,"%s",mbuf);
/* We don't need to know any more */
}
if (reconnect)
{
reconnect--;
BIO_printf(bio_c_out,"drop connection and then reconnect\n");
SSL_shutdown(con);
SSL_set_connect_state(con);
SHUTDOWN(SSL_get_fd(con));
goto re_start;
}
}
}
ssl_pending = read_ssl && SSL_pending(con);
if (!ssl_pending)
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
if (tty_on)
{
if (read_tty) openssl_fdset(fileno(stdin),&readfds);
if (write_tty) openssl_fdset(fileno(stdout),&writefds);
}
if (read_ssl)
openssl_fdset(SSL_get_fd(con),&readfds);
if (write_ssl)
openssl_fdset(SSL_get_fd(con),&writefds);
Dr. Stephen Henson
committed
#else
if(!tty_on || !write_tty) {
if (read_ssl)
openssl_fdset(SSL_get_fd(con),&readfds);
Dr. Stephen Henson
committed
if (write_ssl)
openssl_fdset(SSL_get_fd(con),&writefds);
Dr. Stephen Henson
committed
}
#endif
/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
/* 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)
/* Under Windows/DOS we make the assumption that we can
Dr. Stephen Henson
committed
* always write to the tty: therefore if we need to
* write to the tty we just fall through. Otherwise
* we timeout the select every second and see if there
* are any keypresses. Note: this is a hack, in a proper
* Windows application we wouldn't do this.
*/
Dr. Stephen Henson
committed
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
if(!i && (!_kbhit() || !read_tty) ) continue;
#else
if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
Dr. Stephen Henson
committed
} else i=select(width,(void *)&readfds,(void *)&writefds,
Dr. Stephen Henson
committed
}
#elif defined(OPENSSL_SYS_NETWARE)
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
} else i=select(width,(void *)&readfds,(void *)&writefds,
#elif defined(OPENSSL_SYS_BEOS_R5)
/* Under BeOS-R5 the situation is similar to DOS */
i=0;
stdin_set = 0;
(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
if(!write_tty) {
if(read_tty) {
tv.tv_sec = 1;
tv.tv_usec = 0;
i=select(width,(void *)&readfds,(void *)&writefds,
NULL,&tv);
if (read(fileno(stdin), sbuf, 0) >= 0)
stdin_set = 1;
if (!i && (stdin_set != 1 || !read_tty))
continue;
} else i=select(width,(void *)&readfds,(void *)&writefds,
Dr. Stephen Henson
committed
#else
Dr. Stephen Henson
committed
#endif
if ( i < 0)
{
BIO_printf(bio_err,"bad select %d\n",
get_last_socket_error());
goto shut;
/* goto end; */
}
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
{
BIO_printf(bio_err,"TIMEOUT occured\n");
}
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
{
k=SSL_write(con,&(cbuf[cbuf_off]),
(unsigned int)cbuf_len);
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
cbuf_off+=k;
cbuf_len-=k;
if (k <= 0) goto end;
/* we have done a write(con,NULL,0); */
if (cbuf_len <= 0)
{
read_tty=1;
write_ssl=0;
}
else /* if (cbuf_len > 0) */
{
read_tty=0;
write_ssl=1;
}
break;
case SSL_ERROR_WANT_WRITE:
BIO_printf(bio_c_out,"write W BLOCK\n");
write_ssl=1;
read_tty=0;
break;
case SSL_ERROR_WANT_READ:
BIO_printf(bio_c_out,"write R BLOCK\n");
write_tty=0;
read_ssl=1;
write_ssl=0;
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_c_out,"write X BLOCK\n");
break;
case SSL_ERROR_ZERO_RETURN:
if (cbuf_len != 0)
{
BIO_printf(bio_c_out,"shutdown\n");
ret = 0;
goto shut;
}
else
{
read_tty=1;
write_ssl=0;
break;
}
case SSL_ERROR_SYSCALL:
if ((k != 0) || (cbuf_len != 0))
{
BIO_printf(bio_err,"write:errno=%d\n",
get_last_socket_error());
goto shut;
}
else
{
read_tty=1;
write_ssl=0;
}
break;
case SSL_ERROR_SSL:
ERR_print_errors(bio_err);
goto shut;
}
}
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
/* Assume Windows/DOS/BeOS can always write */
Dr. Stephen Henson
committed
else if (!ssl_pending && write_tty)
#else
else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
Dr. Stephen Henson
committed
#endif
#ifdef CHARSET_EBCDIC
ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
#endif
i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
if (i <= 0)
{
BIO_printf(bio_c_out,"DONE\n");
ret = 0;
goto shut;
/* goto end; */
}
sbuf_len-=i;;
sbuf_off+=i;
if (sbuf_len <= 0)
{
read_ssl=1;
write_tty=0;
}
}
else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
#ifdef RENEG
{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
#endif
k=SSL_read(con,sbuf,1024 /* BUFSIZZ */ );
#else
/* Demo for pending and peek :-) */
k=SSL_read(con,sbuf,16);
{ char zbuf[10240];
printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
}
#endif
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
if (k <= 0)
goto end;
sbuf_off=0;
sbuf_len=k;
read_ssl=0;
write_tty=1;
break;
case SSL_ERROR_WANT_WRITE:
BIO_printf(bio_c_out,"read W BLOCK\n");
write_ssl=1;
read_tty=0;
break;
case SSL_ERROR_WANT_READ:
BIO_printf(bio_c_out,"read R BLOCK\n");
write_tty=0;
read_ssl=1;
if ((read_tty == 0) && (write_ssl == 0))
write_ssl=1;
break;
case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_c_out,"read X BLOCK\n");
break;
case SSL_ERROR_SYSCALL:
ret=get_last_socket_error();
Dr. Stephen Henson
committed
BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
else
BIO_printf(bio_err,"read:errno=%d\n",ret);
goto shut;
case SSL_ERROR_ZERO_RETURN:
BIO_printf(bio_c_out,"closed\n");
ret=0;
goto shut;
case SSL_ERROR_SSL:
ERR_print_errors(bio_err);
goto shut;
/* break; */
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
else if (_kbhit())
#elif defined(OPENSSL_SYS_BEOS_R5)
else if (stdin_set)
Dr. Stephen Henson
committed
#else
else if (FD_ISSET(fileno(stdin),&readfds))
Dr. Stephen Henson
committed
#endif
if (crlf)
{
int j, lf_num;
i=raw_read_stdin(cbuf,BUFSIZZ/2);
lf_num = 0;
/* both loops are skipped when i <= 0 */
for (j = 0; j < i; j++)
if (cbuf[j] == '\n')
lf_num++;
for (j = i-1; j >= 0; j--)
{
cbuf[j+lf_num] = cbuf[j];
if (cbuf[j] == '\n')
{
lf_num--;
i++;
cbuf[j+lf_num] = '\r';
}
}
assert(lf_num == 0);
}
else
i=raw_read_stdin(cbuf,BUFSIZZ);
if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
{
BIO_printf(bio_err,"DONE\n");
ret=0;
goto shut;
}
if ((!c_ign_eof) && (cbuf[0] == 'R'))
SSL_renegotiate(con);
#ifndef OPENSSL_NO_HEARTBEATS
else if ((!c_ign_eof) && (cbuf[0] == 'B'))
{
BIO_printf(bio_err,"HEARTBEATING\n");
SSL_heartbeat(con);
cbuf_len=0;
}
#endif
else
{
cbuf_len=i;
cbuf_off=0;
#ifdef CHARSET_EBCDIC
ebcdic2ascii(cbuf, cbuf, i);
#endif
}
write_ssl=1;