summaryrefslogtreecommitdiff
path: root/src/usr.bin/openssl/s_client.c
diff options
context:
space:
mode:
authorderaadt <>2014-12-02 19:44:49 +0000
committerderaadt <>2014-12-02 19:44:49 +0000
commit6f5388d11ca7552025496dc1e465ad003e94f27e (patch)
tree6002058f0b7accfb8746cc5c4022e1bd924d4eea /src/usr.bin/openssl/s_client.c
parentc8143494d57c2153f018143c0a4c9f301036495c (diff)
downloadopenbsd-6f5388d11ca7552025496dc1e465ad003e94f27e.tar.gz
openbsd-6f5388d11ca7552025496dc1e465ad003e94f27e.tar.bz2
openbsd-6f5388d11ca7552025496dc1e465ad003e94f27e.zip
convert select() to poll(). This is one of the most complicated
conversions in the tree, because the original code is very rotten and fragile. Please test and report any failures. Assistance from millert, bcook, and jsing.
Diffstat (limited to 'src/usr.bin/openssl/s_client.c')
-rw-r--r--src/usr.bin/openssl/s_client.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/usr.bin/openssl/s_client.c b/src/usr.bin/openssl/s_client.c
index 988d799b97..94e24dacaa 100644
--- a/src/usr.bin/openssl/s_client.c
+++ b/src/usr.bin/openssl/s_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s_client.c,v 1.8 2014/11/18 20:54:28 krw Exp $ */ 1/* $OpenBSD: s_client.c,v 1.9 2014/12/02 19:44:49 deraadt Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -137,7 +137,6 @@
137 137
138#include <sys/types.h> 138#include <sys/types.h>
139#include <sys/ioctl.h> 139#include <sys/ioctl.h>
140#include <sys/select.h>
141#include <sys/socket.h> 140#include <sys/socket.h>
142 141
143#include <netinet/in.h> 142#include <netinet/in.h>
@@ -150,6 +149,7 @@
150#include <stdlib.h> 149#include <stdlib.h>
151#include <string.h> 150#include <string.h>
152#include <unistd.h> 151#include <unistd.h>
152#include <poll.h>
153 153
154#include "apps.h" 154#include "apps.h"
155 155
@@ -334,11 +334,10 @@ s_client_main(int argc, char **argv)
334{ 334{
335 unsigned int off = 0, clr = 0; 335 unsigned int off = 0, clr = 0;
336 SSL *con = NULL; 336 SSL *con = NULL;
337 int s, k, width, state = 0, af = AF_UNSPEC; 337 int s, k, state = 0, af = AF_UNSPEC;
338 char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL; 338 char *cbuf = NULL, *sbuf = NULL, *mbuf = NULL;
339 int cbuf_len, cbuf_off; 339 int cbuf_len, cbuf_off;
340 int sbuf_len, sbuf_off; 340 int sbuf_len, sbuf_off;
341 fd_set readfds, writefds;
342 char *port = PORT_STR; 341 char *port = PORT_STR;
343 int full_log = 1; 342 int full_log = 1;
344 char *host = SSL_HOST_NAME; 343 char *host = SSL_HOST_NAME;
@@ -361,7 +360,7 @@ s_client_main(int argc, char **argv)
361 int socket_type = SOCK_STREAM; 360 int socket_type = SOCK_STREAM;
362 BIO *sbio; 361 BIO *sbio;
363 int mbuf_len = 0; 362 int mbuf_len = 0;
364 struct timeval timeout, *timeoutp; 363 struct timeval timeout;
365 const char *errstr = NULL; 364 const char *errstr = NULL;
366#ifndef OPENSSL_NO_ENGINE 365#ifndef OPENSSL_NO_ENGINE
367 char *engine_id = NULL; 366 char *engine_id = NULL;
@@ -874,8 +873,6 @@ re_start:
874 SSL_set_connect_state(con); 873 SSL_set_connect_state(con);
875 874
876 /* ok, lets connect */ 875 /* ok, lets connect */
877 width = SSL_get_fd(con) + 1;
878
879 read_tty = 1; 876 read_tty = 1;
880 write_tty = 0; 877 write_tty = 0;
881 tty_on = 0; 878 tty_on = 0;
@@ -991,14 +988,12 @@ re_start:
991 mbuf[0] = 0; 988 mbuf[0] = 0;
992 } 989 }
993 for (;;) { 990 for (;;) {
994 FD_ZERO(&readfds); 991 struct pollfd pfd[3]; /* stdin, stdout, socket */
995 FD_ZERO(&writefds); 992 int ptimeout = -1;
996 993
997 if ((SSL_version(con) == DTLS1_VERSION) && 994 if ((SSL_version(con) == DTLS1_VERSION) &&
998 DTLSv1_get_timeout(con, &timeout)) 995 DTLSv1_get_timeout(con, &timeout))
999 timeoutp = &timeout; 996 ptimeout = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
1000 else
1001 timeoutp = NULL;
1002 997
1003 if (SSL_in_init(con) && !SSL_total_renegotiations(con)) { 998 if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
1004 in_init = 1; 999 in_init = 1;
@@ -1038,24 +1033,31 @@ re_start:
1038 1033
1039 ssl_pending = read_ssl && SSL_pending(con); 1034 ssl_pending = read_ssl && SSL_pending(con);
1040 1035
1041 /* XXX should add tests for fd_set overflow */ 1036 pfd[0].fd = -1;
1042 1037 pfd[1].fd = -1;
1043 if (!ssl_pending) { 1038 if (!ssl_pending) {
1044 if (tty_on) { 1039 if (tty_on) {
1045 if (read_tty) 1040 if (read_tty) {
1046 FD_SET(fileno(stdin), &readfds); 1041 pfd[0].fd = fileno(stdin);
1047 if (write_tty) 1042 pfd[0].events = POLLIN;
1048 FD_SET(fileno(stdout), &writefds); 1043 }
1044 if (write_tty) {
1045 pfd[1].fd = fileno(stdout);
1046 pfd[1].events = POLLOUT;
1047 }
1049 } 1048 }
1049
1050 pfd[2].fd = SSL_get_fd(con);
1051 pfd[2].events = 0;
1050 if (read_ssl) 1052 if (read_ssl)
1051 FD_SET(SSL_get_fd(con), &readfds); 1053 pfd[2].events |= POLLIN;
1052 if (write_ssl) 1054 if (write_ssl)
1053 FD_SET(SSL_get_fd(con), &writefds); 1055 pfd[2].events |= POLLOUT;
1056
1054/* printf("mode tty(%d %d%d) ssl(%d%d)\n", 1057/* printf("mode tty(%d %d%d) ssl(%d%d)\n",
1055 tty_on,read_tty,write_tty,read_ssl,write_ssl);*/ 1058 tty_on,read_tty,write_tty,read_ssl,write_ssl);*/
1056 1059
1057 i = select(width, &readfds, &writefds, 1060 i = poll(pfd, 3, ptimeout);
1058 NULL, timeoutp);
1059 if (i < 0) { 1061 if (i < 0) {
1060 BIO_printf(bio_err, "bad select %d\n", 1062 BIO_printf(bio_err, "bad select %d\n",
1061 errno); 1063 errno);
@@ -1066,7 +1068,11 @@ re_start:
1066 if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) { 1068 if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0) {
1067 BIO_printf(bio_err, "TIMEOUT occured\n"); 1069 BIO_printf(bio_err, "TIMEOUT occured\n");
1068 } 1070 }
1069 if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) { 1071 if (!ssl_pending && (pfd[2].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1072 if (pfd[2].revents & (POLLERR|POLLNVAL)) {
1073 BIO_printf(bio_err, "poll error");
1074 goto shut;
1075 }
1070 k = SSL_write(con, &(cbuf[cbuf_off]), 1076 k = SSL_write(con, &(cbuf[cbuf_off]),
1071 (unsigned int) cbuf_len); 1077 (unsigned int) cbuf_len);
1072 switch (SSL_get_error(con, k)) { 1078 switch (SSL_get_error(con, k)) {
@@ -1123,7 +1129,12 @@ re_start:
1123 ERR_print_errors(bio_err); 1129 ERR_print_errors(bio_err);
1124 goto shut; 1130 goto shut;
1125 } 1131 }
1126 } else if (!ssl_pending && FD_ISSET(fileno(stdout), &writefds)) { 1132 } else if (!ssl_pending &&
1133 (pfd[1].revents & (POLLOUT|POLLERR|POLLNVAL))) {
1134 if (pfd[1].revents & (POLLERR|POLLNVAL)) {
1135 BIO_printf(bio_err, "poll error");
1136 goto shut;
1137 }
1127 i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len); 1138 i = write(fileno(stdout), &(sbuf[sbuf_off]), sbuf_len);
1128 1139
1129 if (i <= 0) { 1140 if (i <= 0) {
@@ -1138,7 +1149,7 @@ re_start:
1138 read_ssl = 1; 1149 read_ssl = 1;
1139 write_tty = 0; 1150 write_tty = 0;
1140 } 1151 }
1141 } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) { 1152 } else if (ssl_pending || (pfd[2].revents & (POLLIN|POLLHUP))) {
1142#ifdef RENEG 1153#ifdef RENEG
1143 { 1154 {
1144 static int iiii; 1155 static int iiii;
@@ -1188,7 +1199,11 @@ re_start:
1188 goto shut; 1199 goto shut;
1189 /* break; */ 1200 /* break; */
1190 } 1201 }
1191 } else if (FD_ISSET(fileno(stdin), &readfds)) { 1202 } else if (pfd[0].revents) {
1203 if (pfd[0].revents & (POLLERR|POLLNVAL)) {
1204 BIO_printf(bio_err, "poll error");
1205 goto shut;
1206 }
1192 if (crlf) { 1207 if (crlf) {
1193 int j, lf_num; 1208 int j, lf_num;
1194 1209