=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/openssl/s_client.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/openssl/s_client.c 2014/11/18 20:54:28 1.8 +++ src/usr.bin/openssl/s_client.c 2014/12/02 19:44:49 1.9 @@ -1,4 +1,4 @@ -/* $OpenBSD: s_client.c,v 1.8 2014/11/18 20:54:28 krw Exp $ */ +/* $OpenBSD: s_client.c,v 1.9 2014/12/02 19:44:49 deraadt Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -137,7 +137,6 @@ #include #include -#include #include #include @@ -150,6 +149,7 @@ #include #include #include +#include #include "apps.h" @@ -334,11 +334,10 @@ { unsigned int off = 0, clr = 0; SSL *con = NULL; - int s, k, width, state = 0, af = AF_UNSPEC; + int s, k, state = 0, af = AF_UNSPEC; char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; int cbuf_len, cbuf_off; int sbuf_len, sbuf_off; - fd_set readfds, writefds; char *port = PORT_STR; int full_log = 1; char *host = SSL_HOST_NAME; @@ -361,7 +360,7 @@ int socket_type = SOCK_STREAM; BIO *sbio; int mbuf_len = 0; - struct timeval timeout, *timeoutp; + struct timeval timeout; const char *errstr = NULL; #ifndef OPENSSL_NO_ENGINE char *engine_id = NULL; @@ -874,8 +873,6 @@ SSL_set_connect_state(con); /* ok, lets connect */ - width = SSL_get_fd(con) + 1; - read_tty = 1; write_tty = 0; tty_on = 0; @@ -991,14 +988,12 @@ mbuf[0] = 0; } for (;;) { - FD_ZERO(&readfds); - FD_ZERO(&writefds); + struct pollfd pfd[3]; /* stdin, stdout, socket */ + int ptimeout = -1; if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_get_timeout(con, &timeout)) - timeoutp = &timeout; - else - timeoutp = NULL; + ptimeout = timeout.tv_sec * 1000 + timeout.tv_usec / 1000; if (SSL_in_init(con) && !SSL_total_renegotiations(con)) { in_init = 1; @@ -1038,24 +1033,31 @@ ssl_pending = read_ssl && SSL_pending(con); - /* XXX should add tests for fd_set overflow */ - + pfd[0].fd = -1; + pfd[1].fd = -1; if (!ssl_pending) { if (tty_on) { - if (read_tty) - FD_SET(fileno(stdin), &readfds); - if (write_tty) - FD_SET(fileno(stdout), &writefds); + if (read_tty) { + pfd[0].fd = fileno(stdin); + pfd[0].events = POLLIN; + } + if (write_tty) { + pfd[1].fd = fileno(stdout); + pfd[1].events = POLLOUT; + } } + + pfd[2].fd = SSL_get_fd(con); + pfd[2].events = 0; if (read_ssl) - FD_SET(SSL_get_fd(con), &readfds); + pfd[2].events |= POLLIN; if (write_ssl) - FD_SET(SSL_get_fd(con), &writefds); + pfd[2].events |= POLLOUT; + /* printf("mode tty(%d %d%d) ssl(%d%d)\n", tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ - i = select(width, &readfds, &writefds, - NULL, timeoutp); + i = poll(pfd, 3, ptimeout); if (i < 0) { BIO_printf(bio_err, "bad select %d\n", errno); @@ -1066,7 +1068,11 @@ 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)) { + if (!ssl_pending && (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) { + if (pfd[2].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int) cbuf_len); switch (SSL_get_error(con, k)) { @@ -1123,7 +1129,12 @@ ERR_print_errors(bio_err); goto shut; } - } else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds)) { + } else if (!ssl_pending && + (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) { + if (pfd[1].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len); if (i <= 0) { @@ -1138,7 +1149,7 @@ read_ssl = 1; write_tty = 0; } - } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) { + } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) { #ifdef RENEG { static int iiii; @@ -1188,7 +1199,11 @@ goto shut; /* break; */ } - } else if (FD_ISSET(fileno(stdin), &readfds)) { + } else if (pfd[0].revents) { + if (pfd[0].revents & (POLLERR|POLLNVAL)) { + BIO_printf(bio_err, "poll error"); + goto shut; + } if (crlf) { int j, lf_num;