Use SSL_read_ex() and SSL_write_ex() instead of SSL_read() and SSL_write().
This commit is contained in:
@@ -860,6 +860,9 @@
|
|||||||
macro. */
|
macro. */
|
||||||
#undef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
#undef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the 'SSL_read_ex' function. */
|
||||||
|
#undef HAVE_SSL_READ_EX
|
||||||
|
|
||||||
/* Define to 1 to enable SSSD support. */
|
/* Define to 1 to enable SSSD support. */
|
||||||
#undef HAVE_SSSD
|
#undef HAVE_SSSD
|
||||||
|
|
||||||
|
6
configure
vendored
6
configure
vendored
@@ -25969,6 +25969,12 @@ if test "x$ac_cv_func_TLS_method" = xyes
|
|||||||
then :
|
then :
|
||||||
printf "%s\n" "#define HAVE_TLS_METHOD 1" >>confdefs.h
|
printf "%s\n" "#define HAVE_TLS_METHOD 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
ac_fn_c_check_func "$LINENO" "SSL_read_ex" "ac_cv_func_SSL_read_ex"
|
||||||
|
if test "x$ac_cv_func_SSL_read_ex" = xyes
|
||||||
|
then :
|
||||||
|
printf "%s\n" "#define HAVE_SSL_READ_EX 1" >>confdefs.h
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SSL_CTX_set_min_proto_version may be a macro
|
# SSL_CTX_set_min_proto_version may be a macro
|
||||||
|
@@ -908,13 +908,13 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct connection_closure *closure = v;
|
struct connection_closure *closure = v;
|
||||||
struct connection_buffer *buf;
|
struct connection_buffer *buf;
|
||||||
ssize_t nwritten;
|
size_t nwritten;
|
||||||
debug_decl(server_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(server_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to write as part of SSL_read(). */
|
/* For TLS we may need to write as part of SSL_read_ex(). */
|
||||||
if (closure->read_instead_of_write) {
|
if (closure->read_instead_of_write) {
|
||||||
closure->read_instead_of_write = false;
|
closure->read_instead_of_write = false;
|
||||||
/* Delete write event if it was only due to SSL_read(). */
|
/* Delete write event if it was only due to SSL_read_ex(). */
|
||||||
if (closure->temporary_write_event) {
|
if (closure->temporary_write_event) {
|
||||||
closure->temporary_write_event = false;
|
closure->temporary_write_event = false;
|
||||||
sudo_ev_del(closure->evbase, closure->write_ev);
|
sudo_ev_del(closure->evbase, closure->write_ev);
|
||||||
@@ -938,30 +938,29 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (closure->ssl != NULL) {
|
if (closure->ssl != NULL) {
|
||||||
nwritten = SSL_write(closure->ssl, buf->data + buf->off,
|
int err = SSL_write_ex(closure->ssl, buf->data + buf->off,
|
||||||
buf->len - buf->off);
|
buf->len - buf->off, &nwritten);
|
||||||
if (nwritten <= 0) {
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
int err = SSL_get_error(closure->ssl, nwritten);
|
switch (SSL_get_error(closure->ssl, err)) {
|
||||||
switch (err) {
|
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read, read event always active */
|
/* ssl wants to read, read event always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_READ");
|
"SSL_write_ex returns SSL_ERROR_WANT_READ");
|
||||||
/* Redirect persistent read event to finish SSL_write() */
|
/* Redirect persistent read event to finish SSL_write_ex() */
|
||||||
closure->write_instead_of_read = true;
|
closure->write_instead_of_read = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write more, write event remains active */
|
/* ssl wants to write more, write event remains active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_WRITE");
|
"SSL_write_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
sudo_warn("%s: SSL_write", closure->ipaddr);
|
sudo_warn("%s: SSL_write_ex", closure->ipaddr);
|
||||||
goto finished;
|
goto finished;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("%s: SSL_write: %s", closure->ipaddr,
|
sudo_warnx("%s: SSL_write_ex: %s", closure->ipaddr,
|
||||||
errstr ? errstr : strerror(errno));
|
errstr ? errstr : strerror(errno));
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
@@ -969,16 +968,16 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nwritten = write(fd, buf->data + buf->off, buf->len - buf->off);
|
nwritten = (size_t)write(fd, buf->data + buf->off, buf->len - buf->off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nwritten == -1) {
|
if (nwritten == (size_t)-1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("%s: write", closure->ipaddr);
|
sudo_warn("%s: write", closure->ipaddr);
|
||||||
goto finished;
|
goto finished;
|
||||||
}
|
}
|
||||||
buf->off += (size_t)nwritten;
|
buf->off += nwritten;
|
||||||
|
|
||||||
if (buf->off == buf->len) {
|
if (buf->off == buf->len) {
|
||||||
/* sent entire message, move buf to free list */
|
/* sent entire message, move buf to free list */
|
||||||
@@ -1014,10 +1013,10 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
const char *source = closure->journal_path ? closure->journal_path :
|
const char *source = closure->journal_path ? closure->journal_path :
|
||||||
closure->ipaddr;
|
closure->ipaddr;
|
||||||
uint32_t msg_len;
|
uint32_t msg_len;
|
||||||
ssize_t nread;
|
size_t nread;
|
||||||
debug_decl(client_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(client_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to read as part of SSL_write(). */
|
/* For TLS we may need to read as part of SSL_write_ex(). */
|
||||||
if (closure->write_instead_of_read) {
|
if (closure->write_instead_of_read) {
|
||||||
closure->write_instead_of_read = false;
|
closure->write_instead_of_read = false;
|
||||||
server_msg_cb(fd, what, v);
|
server_msg_cb(fd, what, v);
|
||||||
@@ -1031,11 +1030,11 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (closure->ssl != NULL) {
|
if (closure->ssl != NULL) {
|
||||||
nread = SSL_read(closure->ssl, buf->data + buf->len, buf->size);
|
int err = SSL_read_ex(closure->ssl, buf->data + buf->len, buf->size,
|
||||||
if (nread <= 0) {
|
&nread);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
int err = SSL_get_error(closure->ssl, nread);
|
switch (SSL_get_error(closure->ssl, err)) {
|
||||||
switch (err) {
|
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* ssl connection shutdown cleanly */
|
/* ssl connection shutdown cleanly */
|
||||||
nread = 0;
|
nread = 0;
|
||||||
@@ -1043,13 +1042,13 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read more, read event is always active */
|
/* ssl wants to read more, read event is always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_READ");
|
"SSL_read_ex returns SSL_ERROR_WANT_READ");
|
||||||
/* Read event is always active. */
|
/* Read event is always active. */
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write, schedule a write if not pending */
|
/* ssl wants to write, schedule a write if not pending */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_WRITE");
|
"SSL_read_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
if (!sudo_ev_pending(closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
if (!sudo_ev_pending(closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
||||||
/* Enable a temporary write event. */
|
/* Enable a temporary write event. */
|
||||||
if (sudo_ev_add(closure->evbase, closure->write_ev,
|
if (sudo_ev_add(closure->evbase, closure->write_ev,
|
||||||
@@ -1060,7 +1059,7 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
}
|
}
|
||||||
closure->temporary_write_event = true;
|
closure->temporary_write_event = true;
|
||||||
}
|
}
|
||||||
/* Redirect write event to finish SSL_read() */
|
/* Redirect write event to finish SSL_read_ex() */
|
||||||
closure->read_instead_of_write = true;
|
closure->read_instead_of_write = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
@@ -1070,11 +1069,11 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
closure->ipaddr);
|
closure->ipaddr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sudo_warn("%s: SSL_read", closure->ipaddr);
|
sudo_warn("%s: SSL_read_ex", closure->ipaddr);
|
||||||
goto close_connection;
|
goto close_connection;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("%s: SSL_read: %s", closure->ipaddr,
|
sudo_warnx("%s: SSL_read_ex: %s", closure->ipaddr,
|
||||||
errstr ? errstr : strerror(errno));
|
errstr ? errstr : strerror(errno));
|
||||||
goto close_connection;
|
goto close_connection;
|
||||||
}
|
}
|
||||||
@@ -1082,13 +1081,13 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nread = read(fd, buf->data + buf->len, buf->size - buf->len);
|
nread = (size_t)read(fd, buf->data + buf->len, buf->size - buf->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from client %s",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from client %s",
|
||||||
__func__, nread, closure->ipaddr);
|
__func__, nread, closure->ipaddr);
|
||||||
switch (nread) {
|
switch (nread) {
|
||||||
case -1:
|
case (size_t)-1:
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("%s: read", closure->ipaddr);
|
sudo_warn("%s: read", closure->ipaddr);
|
||||||
@@ -1102,7 +1101,7 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf->len += (size_t)nread;
|
buf->len += nread;
|
||||||
|
|
||||||
while (buf->len - buf->off >= sizeof(msg_len)) {
|
while (buf->len - buf->off >= sizeof(msg_len)) {
|
||||||
/* Read wire message size (uint32_t in network byte order). */
|
/* Read wire message size (uint32_t in network byte order). */
|
||||||
|
@@ -695,11 +695,11 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
struct connection_closure *closure = v;
|
struct connection_closure *closure = v;
|
||||||
struct relay_closure *relay_closure = closure->relay_closure;
|
struct relay_closure *relay_closure = closure->relay_closure;
|
||||||
struct connection_buffer *buf = &relay_closure->read_buf;
|
struct connection_buffer *buf = &relay_closure->read_buf;
|
||||||
ssize_t nread;
|
size_t nread;
|
||||||
uint32_t msg_len;
|
uint32_t msg_len;
|
||||||
debug_decl(relay_server_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(relay_server_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to read as part of SSL_write(). */
|
/* For TLS we may need to read as part of SSL_write_ex(). */
|
||||||
if (relay_closure->write_instead_of_read) {
|
if (relay_closure->write_instead_of_read) {
|
||||||
relay_closure->write_instead_of_read = false;
|
relay_closure->write_instead_of_read = false;
|
||||||
relay_client_msg_cb(fd, what, v);
|
relay_client_msg_cb(fd, what, v);
|
||||||
@@ -716,15 +716,17 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (relay_closure->tls_client.ssl != NULL) {
|
if (relay_closure->tls_client.ssl != NULL) {
|
||||||
SSL *ssl = relay_closure->tls_client.ssl;
|
SSL *ssl = relay_closure->tls_client.ssl;
|
||||||
|
int err;
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"%s: ServerMessage from relay %s (%s) [TLS]", __func__,
|
"%s: ServerMessage from relay %s (%s) [TLS]", __func__,
|
||||||
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
||||||
nread = SSL_read(ssl, buf->data + buf->len, buf->size - buf->len);
|
err = SSL_read_ex(ssl, buf->data + buf->len, buf->size - buf->len,
|
||||||
if (nread <= 0) {
|
&nread);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
int err;
|
|
||||||
|
|
||||||
switch (SSL_get_error(ssl, nread)) {
|
switch (SSL_get_error(ssl, err)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* ssl connection shutdown cleanly */
|
/* ssl connection shutdown cleanly */
|
||||||
nread = 0;
|
nread = 0;
|
||||||
@@ -732,12 +734,12 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read more, read event is always active */
|
/* ssl wants to read more, read event is always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_READ");
|
"SSL_read_ex returns SSL_ERROR_WANT_READ");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write, schedule a write if not pending */
|
/* ssl wants to write, schedule a write if not pending */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_WRITE");
|
"SSL_read_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
if (!sudo_ev_pending(relay_closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
if (!sudo_ev_pending(relay_closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
||||||
/* Enable a temporary write event. */
|
/* Enable a temporary write event. */
|
||||||
if (sudo_ev_add(closure->evbase, relay_closure->write_ev, NULL, false) == -1) {
|
if (sudo_ev_add(closure->evbase, relay_closure->write_ev, NULL, false) == -1) {
|
||||||
@@ -747,7 +749,7 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
}
|
}
|
||||||
relay_closure->temporary_write_event = true;
|
relay_closure->temporary_write_event = true;
|
||||||
}
|
}
|
||||||
/* Redirect write event to finish SSL_read() */
|
/* Redirect write event to finish SSL_read_ex() */
|
||||||
relay_closure->read_instead_of_write = true;
|
relay_closure->read_instead_of_write = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
@@ -769,7 +771,7 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
errstr = ERR_reason_error_string(err);
|
errstr = ERR_reason_error_string(err);
|
||||||
closure->errstr = _("error reading from relay");
|
closure->errstr = _("error reading from relay");
|
||||||
}
|
}
|
||||||
sudo_warnx("%s: SSL_read: %s",
|
sudo_warnx("%s: SSL_read_ex: %s",
|
||||||
relay_closure->relay_name.ipaddr,
|
relay_closure->relay_name.ipaddr,
|
||||||
errstr ? errstr : strerror(errno));
|
errstr ? errstr : strerror(errno));
|
||||||
goto send_error;
|
goto send_error;
|
||||||
@@ -780,12 +782,12 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
relay_closure->relay_name.ipaddr);
|
relay_closure->relay_name.ipaddr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sudo_warn("%s: SSL_read", relay_closure->relay_name.ipaddr);
|
sudo_warn("%s: SSL_read_ex", relay_closure->relay_name.ipaddr);
|
||||||
closure->errstr = _("error reading from relay");
|
closure->errstr = _("error reading from relay");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("%s: SSL_read: %s",
|
sudo_warnx("%s: SSL_read_ex: %s",
|
||||||
relay_closure->relay_name.ipaddr,
|
relay_closure->relay_name.ipaddr,
|
||||||
errstr ? errstr : strerror(errno));
|
errstr ? errstr : strerror(errno));
|
||||||
closure->errstr = _("error reading from relay");
|
closure->errstr = _("error reading from relay");
|
||||||
@@ -798,14 +800,14 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"%s: ServerMessage from relay %s (%s)", __func__,
|
"%s: ServerMessage from relay %s (%s)", __func__,
|
||||||
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
||||||
nread = read(fd, buf->data + buf->len, buf->size - buf->len);
|
nread = (size_t)read(fd, buf->data + buf->len, buf->size - buf->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"%s: received %zd bytes from relay %s (%s)", __func__, nread,
|
"%s: received %zd bytes from relay %s (%s)", __func__, nread,
|
||||||
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
|
||||||
switch (nread) {
|
switch (nread) {
|
||||||
case -1:
|
case (size_t)-1:
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("%s: read", relay_closure->relay_name.ipaddr);
|
sudo_warn("%s: read", relay_closure->relay_name.ipaddr);
|
||||||
@@ -833,7 +835,7 @@ relay_server_msg_cb(int fd, int what, void *v)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf->len += (size_t)nread;
|
buf->len += nread;
|
||||||
|
|
||||||
while (buf->len - buf->off >= sizeof(msg_len)) {
|
while (buf->len - buf->off >= sizeof(msg_len)) {
|
||||||
/* Read wire message size (uint32_t in network byte order). */
|
/* Read wire message size (uint32_t in network byte order). */
|
||||||
@@ -890,13 +892,13 @@ relay_client_msg_cb(int fd, int what, void *v)
|
|||||||
struct connection_closure *closure = v;
|
struct connection_closure *closure = v;
|
||||||
struct relay_closure *relay_closure = closure->relay_closure;
|
struct relay_closure *relay_closure = closure->relay_closure;
|
||||||
struct connection_buffer *buf;
|
struct connection_buffer *buf;
|
||||||
ssize_t nwritten;
|
size_t nwritten;
|
||||||
debug_decl(relay_client_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(relay_client_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to write as part of SSL_read(). */
|
/* For TLS we may need to write as part of SSL_read_ex(). */
|
||||||
if (relay_closure->read_instead_of_write) {
|
if (relay_closure->read_instead_of_write) {
|
||||||
relay_closure->read_instead_of_write = false;
|
relay_closure->read_instead_of_write = false;
|
||||||
/* Delete write event if it was only due to SSL_read(). */
|
/* Delete write event if it was only due to SSL_read_ex(). */
|
||||||
if (relay_closure->temporary_write_event) {
|
if (relay_closure->temporary_write_event) {
|
||||||
relay_closure->temporary_write_event = false;
|
relay_closure->temporary_write_event = false;
|
||||||
sudo_ev_del(closure->evbase, relay_closure->write_ev);
|
sudo_ev_del(closure->evbase, relay_closure->write_ev);
|
||||||
@@ -925,11 +927,12 @@ relay_client_msg_cb(int fd, int what, void *v)
|
|||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (relay_closure->tls_client.ssl != NULL) {
|
if (relay_closure->tls_client.ssl != NULL) {
|
||||||
SSL *ssl = relay_closure->tls_client.ssl;
|
SSL *ssl = relay_closure->tls_client.ssl;
|
||||||
nwritten = SSL_write(ssl, buf->data + buf->off, buf->len - buf->off);
|
int err = SSL_write_ex(ssl, buf->data + buf->off, buf->len - buf->off,
|
||||||
if (nwritten <= 0) {
|
&nwritten);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
|
||||||
switch (SSL_get_error(ssl, nwritten)) {
|
switch (SSL_get_error(ssl, err)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* ssl connection shutdown cleanly */
|
/* ssl connection shutdown cleanly */
|
||||||
shutdown(relay_closure->sock, SHUT_RDWR);
|
shutdown(relay_closure->sock, SHUT_RDWR);
|
||||||
@@ -949,23 +952,23 @@ relay_client_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read, read event always active */
|
/* ssl wants to read, read event always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_READ");
|
"SSL_write_ex returns SSL_ERROR_WANT_READ");
|
||||||
/* Redirect read event to finish SSL_write() */
|
/* Redirect read event to finish SSL_write_ex() */
|
||||||
relay_closure->write_instead_of_read = true;
|
relay_closure->write_instead_of_read = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write more, write event remains active */
|
/* ssl wants to write more, write event remains active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_WRITE");
|
"SSL_write_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
sudo_warn("%s: SSL_write",
|
sudo_warn("%s: SSL_write_ex",
|
||||||
relay_closure->relay_name.ipaddr);
|
relay_closure->relay_name.ipaddr);
|
||||||
closure->errstr = _("error writing to relay");
|
closure->errstr = _("error writing to relay");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("%s: SSL_write: %s",
|
sudo_warnx("%s: SSL_write_ex: %s",
|
||||||
relay_closure->relay_name.ipaddr,
|
relay_closure->relay_name.ipaddr,
|
||||||
errstr ? errstr : strerror(errno));
|
errstr ? errstr : strerror(errno));
|
||||||
closure->errstr = _("error writing to relay");
|
closure->errstr = _("error writing to relay");
|
||||||
@@ -975,8 +978,8 @@ relay_client_msg_cb(int fd, int what, void *v)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nwritten = write(fd, buf->data + buf->off, buf->len - buf->off);
|
nwritten = (size_t)write(fd, buf->data + buf->off, buf->len - buf->off);
|
||||||
if (nwritten == -1) {
|
if (nwritten == (size_t)-1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("%s: write", relay_closure->relay_name.ipaddr);
|
sudo_warn("%s: write", relay_closure->relay_name.ipaddr);
|
||||||
@@ -984,7 +987,7 @@ relay_client_msg_cb(int fd, int what, void *v)
|
|||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf->off += (size_t)nwritten;
|
buf->off += nwritten;
|
||||||
|
|
||||||
if (buf->off == buf->len) {
|
if (buf->off == buf->len) {
|
||||||
/* sent entire message, move buf to free list */
|
/* sent entire message, move buf to free list */
|
||||||
|
@@ -279,7 +279,7 @@ read_io_buf(struct client_closure *closure)
|
|||||||
{
|
{
|
||||||
struct timing_closure *timing = &closure->timing;
|
struct timing_closure *timing = &closure->timing;
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
ssize_t nread;
|
size_t nread;
|
||||||
debug_decl(read_io_buf, SUDO_DEBUG_UTIL);
|
debug_decl(read_io_buf, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!closure->iolog_files[timing->event].enabled) {
|
if (!closure->iolog_files[timing->event].enabled) {
|
||||||
@@ -310,7 +310,7 @@ read_io_buf(struct client_closure *closure)
|
|||||||
|
|
||||||
nread = iolog_read(&closure->iolog_files[timing->event], closure->buf,
|
nread = iolog_read(&closure->iolog_files[timing->event], closure->buf,
|
||||||
timing->u.nbytes, &errstr);
|
timing->u.nbytes, &errstr);
|
||||||
if (nread == -1) {
|
if (nread == (size_t)-1) {
|
||||||
sudo_warnx(U_("unable to read %s/%s: %s"), iolog_dir,
|
sudo_warnx(U_("unable to read %s/%s: %s"), iolog_dir,
|
||||||
iolog_fd_to_name(timing->event), errstr);
|
iolog_fd_to_name(timing->event), errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
@@ -1260,11 +1260,11 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct client_closure *closure = v;
|
struct client_closure *closure = v;
|
||||||
struct connection_buffer *buf = &closure->read_buf;
|
struct connection_buffer *buf = &closure->read_buf;
|
||||||
ssize_t nread;
|
size_t nread;
|
||||||
uint32_t msg_len;
|
uint32_t msg_len;
|
||||||
debug_decl(server_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(server_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to read as part of SSL_write(). */
|
/* For TLS we may need to read as part of SSL_write_ex(). */
|
||||||
if (closure->write_instead_of_read) {
|
if (closure->write_instead_of_read) {
|
||||||
closure->write_instead_of_read = false;
|
closure->write_instead_of_read = false;
|
||||||
client_msg_cb(fd, what, v);
|
client_msg_cb(fd, what, v);
|
||||||
@@ -1279,13 +1279,14 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (cert != NULL) {
|
if (cert != NULL) {
|
||||||
SSL *ssl = closure->tls_client.ssl;
|
SSL *ssl = closure->tls_client.ssl;
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage (TLS)", __func__);
|
|
||||||
nread = SSL_read(ssl, buf->data + buf->len, buf->size - buf->len);
|
|
||||||
if (nread <= 0) {
|
|
||||||
const char *errstr;
|
|
||||||
int err;
|
int err;
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage (TLS)", __func__);
|
||||||
|
err = SSL_read_ex(ssl, buf->data + buf->len, buf->size - buf->len,
|
||||||
|
&nread);
|
||||||
|
if (err) {
|
||||||
|
const char *errstr;
|
||||||
|
|
||||||
switch (SSL_get_error(ssl, nread)) {
|
switch (SSL_get_error(ssl, err)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* ssl connection shutdown cleanly */
|
/* ssl connection shutdown cleanly */
|
||||||
nread = 0;
|
nread = 0;
|
||||||
@@ -1293,12 +1294,12 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read more, read event is always active */
|
/* ssl wants to read more, read event is always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_READ");
|
"SSL_read_ex returns SSL_ERROR_WANT_READ");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write, schedule a write if not pending */
|
/* ssl wants to write, schedule a write if not pending */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_WRITE");
|
"SSL_read_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
if (!sudo_ev_pending(closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
if (!sudo_ev_pending(closure->write_ev, SUDO_EV_WRITE, NULL)) {
|
||||||
/* Enable a temporary write event. */
|
/* Enable a temporary write event. */
|
||||||
if (sudo_ev_add(closure->evbase, closure->write_ev, NULL, false) == -1) {
|
if (sudo_ev_add(closure->evbase, closure->write_ev, NULL, false) == -1) {
|
||||||
@@ -1307,7 +1308,7 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
}
|
}
|
||||||
closure->temporary_write_event = true;
|
closure->temporary_write_event = true;
|
||||||
}
|
}
|
||||||
/* Redirect write event to finish SSL_read() */
|
/* Redirect write event to finish SSL_read_ex() */
|
||||||
closure->read_instead_of_write = true;
|
closure->read_instead_of_write = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
@@ -1330,11 +1331,12 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
sudo_warnx("%s", errstr ? errstr : strerror(errno));
|
sudo_warnx("%s", errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
sudo_warn("recv");
|
sudo_warn("SSL_read_ex");
|
||||||
goto bad;
|
goto bad;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("recv: %s", errstr ? errstr : strerror(errno));
|
sudo_warnx("SSL_read_ex: %s",
|
||||||
|
errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1342,15 +1344,15 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
||||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
nread = (size_t)read(fd, buf->data + buf->len, buf->size - buf->len);
|
||||||
}
|
}
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from server",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from server",
|
||||||
__func__, nread);
|
__func__, nread);
|
||||||
switch (nread) {
|
switch (nread) {
|
||||||
case -1:
|
case (size_t)-1:
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("recv");
|
sudo_warn("read");
|
||||||
goto bad;
|
goto bad;
|
||||||
case 0:
|
case 0:
|
||||||
if (closure->state != FINISHED)
|
if (closure->state != FINISHED)
|
||||||
@@ -1359,7 +1361,7 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf->len += (size_t)nread;
|
buf->len += nread;
|
||||||
|
|
||||||
while (buf->len - buf->off >= sizeof(msg_len)) {
|
while (buf->len - buf->off >= sizeof(msg_len)) {
|
||||||
/* Read wire message size (uint32_t in network byte order). */
|
/* Read wire message size (uint32_t in network byte order). */
|
||||||
@@ -1402,7 +1404,7 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct client_closure *closure = v;
|
struct client_closure *closure = v;
|
||||||
struct connection_buffer *buf;
|
struct connection_buffer *buf;
|
||||||
ssize_t nwritten;
|
size_t nwritten;
|
||||||
debug_decl(client_msg_cb, SUDO_DEBUG_UTIL);
|
debug_decl(client_msg_cb, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if ((buf = TAILQ_FIRST(&closure->write_bufs)) == NULL) {
|
if ((buf = TAILQ_FIRST(&closure->write_bufs)) == NULL) {
|
||||||
@@ -1410,10 +1412,10 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For TLS we may need to write as part of SSL_read(). */
|
/* For TLS we may need to write as part of SSL_read_ex(). */
|
||||||
if (closure->read_instead_of_write) {
|
if (closure->read_instead_of_write) {
|
||||||
closure->read_instead_of_write = false;
|
closure->read_instead_of_write = false;
|
||||||
/* Delete write event if it was only due to SSL_read(). */
|
/* Delete write event if it was only due to SSL_read_ex(). */
|
||||||
if (closure->temporary_write_event) {
|
if (closure->temporary_write_event) {
|
||||||
closure->temporary_write_event = false;
|
closure->temporary_write_event = false;
|
||||||
sudo_ev_del(closure->evbase, closure->write_ev);
|
sudo_ev_del(closure->evbase, closure->write_ev);
|
||||||
@@ -1433,47 +1435,49 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (cert != NULL) {
|
if (cert != NULL) {
|
||||||
SSL *ssl = closure->tls_client.ssl;
|
SSL *ssl = closure->tls_client.ssl;
|
||||||
nwritten = SSL_write(ssl, buf->data + buf->off, buf->len - buf->off);
|
int err = SSL_write_ex(ssl, buf->data + buf->off, buf->len - buf->off,
|
||||||
if (nwritten <= 0) {
|
&nwritten);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
|
||||||
switch (SSL_get_error(ssl, nwritten)) {
|
switch (SSL_get_error(ssl, err)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* ssl connection shutdown */
|
/* ssl connection shutdown */
|
||||||
goto bad;
|
goto bad;
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read, read event always active */
|
/* ssl wants to read, read event always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_READ");
|
"SSL_write_ex returns SSL_ERROR_WANT_READ");
|
||||||
/* Redirect read event to finish SSL_write() */
|
/* Redirect read event to finish SSL_write_ex() */
|
||||||
closure->write_instead_of_read = true;
|
closure->write_instead_of_read = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write more, write event remains active */
|
/* ssl wants to write more, write event remains active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_WRITE");
|
"SSL_write_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
sudo_warn("recv");
|
sudo_warn("SSL_write_ex");
|
||||||
goto bad;
|
goto bad;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("send: %s", errstr ? errstr : strerror(errno));
|
sudo_warnx("SSL_write_ex: %s",
|
||||||
|
errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
nwritten = (size_t)write(fd, buf->data + buf->off, buf->len - buf->off);
|
||||||
}
|
}
|
||||||
if (nwritten == -1) {
|
if (nwritten == (size_t)-1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("send");
|
sudo_warn("write");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
buf->off += (size_t)nwritten;
|
buf->off += nwritten;
|
||||||
|
|
||||||
if (buf->off == buf->len) {
|
if (buf->off == buf->len) {
|
||||||
/* sent entire message */
|
/* sent entire message */
|
||||||
|
@@ -156,7 +156,7 @@ AC_DEFUN([SUDO_CHECK_OPENSSL], [
|
|||||||
if test "${enable_openssl-no}" != no; then
|
if test "${enable_openssl-no}" != no; then
|
||||||
OLIBS="$LIBS"
|
OLIBS="$LIBS"
|
||||||
LIBS="$LIBS $LIBTLS"
|
LIBS="$LIBS $LIBTLS"
|
||||||
AC_CHECK_FUNCS([X509_STORE_CTX_get0_cert ASN1_STRING_get0_data SSL_CTX_get0_certificate SSL_CTX_set0_tmp_dh_pkey TLS_method])
|
AC_CHECK_FUNCS([X509_STORE_CTX_get0_cert ASN1_STRING_get0_data SSL_CTX_get0_certificate SSL_CTX_set0_tmp_dh_pkey TLS_method SSL_read_ex])
|
||||||
# SSL_CTX_set_min_proto_version may be a macro
|
# SSL_CTX_set_min_proto_version may be a macro
|
||||||
AC_CHECK_DECL([SSL_CTX_set_min_proto_version], [AC_DEFINE(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)], [], [
|
AC_CHECK_DECL([SSL_CTX_set_min_proto_version], [AC_DEFINE(HAVE_SSL_CTX_SET_MIN_PROTO_VERSION)], [], [
|
||||||
AC_INCLUDES_DEFAULT
|
AC_INCLUDES_DEFAULT
|
||||||
|
@@ -1676,11 +1676,11 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct client_closure *closure = v;
|
struct client_closure *closure = v;
|
||||||
struct connection_buffer *buf = &closure->read_buf;
|
struct connection_buffer *buf = &closure->read_buf;
|
||||||
ssize_t nread;
|
size_t nread;
|
||||||
uint32_t msg_len;
|
uint32_t msg_len;
|
||||||
debug_decl(server_msg_cb, SUDOERS_DEBUG_UTIL);
|
debug_decl(server_msg_cb, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to read as part of SSL_write(). */
|
/* For TLS we may need to read as part of SSL_write_ex(). */
|
||||||
if (closure->write_instead_of_read) {
|
if (closure->write_instead_of_read) {
|
||||||
closure->write_instead_of_read = false;
|
closure->write_instead_of_read = false;
|
||||||
client_msg_cb(fd, what, v);
|
client_msg_cb(fd, what, v);
|
||||||
@@ -1696,10 +1696,10 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: reading ServerMessage", __func__);
|
||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (closure->ssl != NULL) {
|
if (closure->ssl != NULL) {
|
||||||
nread = SSL_read(closure->ssl, buf->data + buf->len, buf->size - buf->len);
|
int err = SSL_read_ex(closure->ssl, buf->data + buf->len,
|
||||||
if (nread <= 0) {
|
buf->size - buf->len, &nread);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
int err;
|
|
||||||
|
|
||||||
switch (SSL_get_error(closure->ssl, nread)) {
|
switch (SSL_get_error(closure->ssl, nread)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
@@ -1711,12 +1711,12 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read more, read event is always active */
|
/* ssl wants to read more, read event is always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_READ");
|
"SSL_read_ex returns SSL_ERROR_WANT_READ");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write, so schedule the write handler */
|
/* ssl wants to write, so schedule the write handler */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_read returns SSL_ERROR_WANT_WRITE");
|
"SSL_read_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
if (!closure->write_ev->pending(closure->write_ev,
|
if (!closure->write_ev->pending(closure->write_ev,
|
||||||
SUDO_PLUGIN_EV_WRITE, NULL)) {
|
SUDO_PLUGIN_EV_WRITE, NULL)) {
|
||||||
/* Enable a temporary write event. */
|
/* Enable a temporary write event. */
|
||||||
@@ -1726,7 +1726,7 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
}
|
}
|
||||||
closure->temporary_write_event = true;
|
closure->temporary_write_event = true;
|
||||||
}
|
}
|
||||||
/* Redirect write event to finish SSL_read() */
|
/* Redirect write event to finish SSL_read_ex() */
|
||||||
closure->read_instead_of_write = true;
|
closure->read_instead_of_write = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
@@ -1752,26 +1752,27 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
if (nread == 0)
|
if (nread == 0)
|
||||||
sudo_warnx("%s", U_("lost connection to log server"));
|
sudo_warnx("%s", U_("lost connection to log server"));
|
||||||
else
|
else
|
||||||
sudo_warn("recv");
|
sudo_warn("SSL_read_ex");
|
||||||
goto bad;
|
goto bad;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("recv: %s", errstr ? errstr : strerror(errno));
|
sudo_warnx("SSL_read_ex: %s",
|
||||||
|
errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
{
|
{
|
||||||
nread = recv(fd, buf->data + buf->len, buf->size - buf->len, 0);
|
nread = (size_t)read(fd, buf->data + buf->len, buf->size - buf->len);
|
||||||
}
|
}
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from server",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: received %zd bytes from server",
|
||||||
__func__, nread);
|
__func__, nread);
|
||||||
switch (nread) {
|
switch (nread) {
|
||||||
case -1:
|
case (size_t)-1:
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
debug_return;
|
debug_return;
|
||||||
sudo_warn("recv");
|
sudo_warn("read");
|
||||||
goto bad;
|
goto bad;
|
||||||
case 0:
|
case 0:
|
||||||
sudo_warnx("%s", U_("lost connection to log server"));
|
sudo_warnx("%s", U_("lost connection to log server"));
|
||||||
@@ -1779,7 +1780,7 @@ server_msg_cb(int fd, int what, void *v)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf->len += (size_t)nread;
|
buf->len += nread;
|
||||||
|
|
||||||
while (buf->len - buf->off >= sizeof(msg_len)) {
|
while (buf->len - buf->off >= sizeof(msg_len)) {
|
||||||
/* Read wire message size (uint32_t in network byte order). */
|
/* Read wire message size (uint32_t in network byte order). */
|
||||||
@@ -1829,13 +1830,13 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct client_closure *closure = v;
|
struct client_closure *closure = v;
|
||||||
struct connection_buffer *buf;
|
struct connection_buffer *buf;
|
||||||
ssize_t nwritten;
|
size_t nwritten;
|
||||||
debug_decl(client_msg_cb, SUDOERS_DEBUG_UTIL);
|
debug_decl(client_msg_cb, SUDOERS_DEBUG_UTIL);
|
||||||
|
|
||||||
/* For TLS we may need to write as part of SSL_read(). */
|
/* For TLS we may need to write as part of SSL_read_ex(). */
|
||||||
if (closure->read_instead_of_write) {
|
if (closure->read_instead_of_write) {
|
||||||
closure->read_instead_of_write = false;
|
closure->read_instead_of_write = false;
|
||||||
/* Delete write event if it was only due to SSL_read(). */
|
/* Delete write event if it was only due to SSL_read_ex(). */
|
||||||
if (closure->temporary_write_event) {
|
if (closure->temporary_write_event) {
|
||||||
closure->temporary_write_event = false;
|
closure->temporary_write_event = false;
|
||||||
closure->write_ev->del(closure->write_ev);
|
closure->write_ev->del(closure->write_ev);
|
||||||
@@ -1860,11 +1861,12 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
if (closure->ssl != NULL) {
|
if (closure->ssl != NULL) {
|
||||||
nwritten = SSL_write(closure->ssl, buf->data + buf->off, buf->len - buf->off);
|
int err = SSL_write_ex(closure->ssl, buf->data + buf->off,
|
||||||
if (nwritten <= 0) {
|
buf->len - buf->off, &nwritten);
|
||||||
|
if (err) {
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
|
|
||||||
switch (SSL_get_error(closure->ssl, nwritten)) {
|
switch (SSL_get_error(closure->ssl, err)) {
|
||||||
case SSL_ERROR_ZERO_RETURN:
|
case SSL_ERROR_ZERO_RETURN:
|
||||||
/* TLS connection shutdown cleanly */
|
/* TLS connection shutdown cleanly */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
@@ -1873,39 +1875,40 @@ client_msg_cb(int fd, int what, void *v)
|
|||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
/* ssl wants to read, read event always active */
|
/* ssl wants to read, read event always active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_READ");
|
"SSL_write_ex returns SSL_ERROR_WANT_READ");
|
||||||
/* Redirect read event to finish SSL_write() */
|
/* Redirect read event to finish SSL_write_ex() */
|
||||||
closure->write_instead_of_read = true;
|
closure->write_instead_of_read = true;
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
/* ssl wants to write more, write event remains active */
|
/* ssl wants to write more, write event remains active */
|
||||||
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO,
|
||||||
"SSL_write returns SSL_ERROR_WANT_WRITE");
|
"SSL_write_ex returns SSL_ERROR_WANT_WRITE");
|
||||||
debug_return;
|
debug_return;
|
||||||
case SSL_ERROR_SSL:
|
case SSL_ERROR_SSL:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("%s", errstr ? errstr : strerror(errno));
|
sudo_warnx("%s", errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
case SSL_ERROR_SYSCALL:
|
case SSL_ERROR_SYSCALL:
|
||||||
sudo_warn("send");
|
sudo_warn("SSL_write_ex");
|
||||||
goto bad;
|
goto bad;
|
||||||
default:
|
default:
|
||||||
errstr = ERR_reason_error_string(ERR_get_error());
|
errstr = ERR_reason_error_string(ERR_get_error());
|
||||||
sudo_warnx("send: %s", errstr ? errstr : strerror(errno));
|
sudo_warnx("SSL_write_ex: %s",
|
||||||
|
errstr ? errstr : strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_OPENSSL */
|
#endif /* HAVE_OPENSSL */
|
||||||
{
|
{
|
||||||
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
|
nwritten = (size_t)write(fd, buf->data + buf->off, buf->len - buf->off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nwritten == -1) {
|
if (nwritten == (size_t)-1) {
|
||||||
sudo_warn("send");
|
sudo_warn("send");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
buf->off += (size_t)nwritten;
|
buf->off += nwritten;
|
||||||
|
|
||||||
if (buf->off == buf->len) {
|
if (buf->off == buf->len) {
|
||||||
/* sent entire message, move buf to free list */
|
/* sent entire message, move buf to free list */
|
||||||
|
Reference in New Issue
Block a user