- if (jpake_secret)
- jpake_client_auth(bio_c_out, sbio, jpake_secret);
-#endif
-
- 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");
- (void)BIO_flush(fbio);
- /* 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]=='-');
- (void)BIO_flush(fbio);
- 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)
- {
- 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");
- (void)BIO_flush(fbio);
- /* 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]!='.');
- (void)BIO_flush(fbio);
- 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]=='-');
- (void)BIO_flush(fbio);
- BIO_pop(fbio);
- BIO_free(fbio);
- BIO_printf(sbio,"AUTH TLS\r\n");
- BIO_read(sbio,sbuf,BUFSIZZ);
- }
- 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 ");
- }
-#endif
-#endif
- 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);
- }
- print_stuff(bio_c_out,con,full_log);
- if (full_log > 0) full_log--;
-
- if (starttls_proto)
- {
- BIO_printf(bio_err,"%s",mbuf);
- /* We don't need to know any more */
- starttls_proto = PROTO_OFF;
- }
-
- 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 (jpake_secret)
+ jpake_client_auth(bio_c_out, sbio, jpake_secret);
+#endif
+
+ 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");
+ (void)BIO_flush(fbio);
+ /* 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] == '-');
+ (void)BIO_flush(fbio);
+ 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) {
+ 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");
+ (void)BIO_flush(fbio);
+ /* 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] != '.');
+ (void)BIO_flush(fbio);
+ 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] == '-');
+ (void)BIO_flush(fbio);
+ BIO_pop(fbio);
+ BIO_free(fbio);
+ BIO_printf(sbio, "AUTH TLS\r\n");
+ BIO_read(sbio, sbuf, BUFSIZZ);
+ }
+ 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 ");
+ }
+# endif
+#endif
+ 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);
+ }
+ 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--;
+
+ if (starttls_proto) {
+ BIO_printf(bio_err, "%s", mbuf);
+ /* We don't need to know any more */
+ starttls_proto = PROTO_OFF;
+ }
+
+ 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) {