Commit d939dd33 authored by Vladimír Čunát's avatar Vladimír Čunát

Merge !739: daemon/tls: fix rare case of improperly handled rehandshake

parents 95fcfbd3 7d2ffa24
...@@ -235,7 +235,17 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) ...@@ -235,7 +235,17 @@ static void tcp_recv(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
/* buf->base points to start of the tls receive buffer. /* buf->base points to start of the tls receive buffer.
Decode data free space in session wire buffer. */ Decode data free space in session wire buffer. */
consumed = tls_process_input_data(s, (const uint8_t *)buf->base, nread); consumed = tls_process_input_data(s, (const uint8_t *)buf->base, nread);
if (consumed <= 0) { if (consumed < 0) {
if (kr_verbose_status) {
struct sockaddr *peer = session_get_peer(s);
char *peer_str = kr_straddr(peer);
kr_log_verbose("[io] => connection to '%s': "
"error processing TLS data, close\n",
peer_str ? peer_str : "");
}
worker_end_tcp(s);
return;
} else if (consumed == 0) {
return; return;
} }
data = session_wirebuf_get_free_start(s); data = session_wirebuf_get_free_start(s);
......
...@@ -493,16 +493,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr ...@@ -493,16 +493,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr
kr_log_verbose("[%s] TLS rehandshake with %s has started\n", kr_log_verbose("[%s] TLS rehandshake with %s has started\n",
logstring, kr_straddr(peer)); logstring, kr_straddr(peer));
tls_set_hs_state(tls_p, TLS_HS_IN_PROGRESS); tls_set_hs_state(tls_p, TLS_HS_IN_PROGRESS);
int err = kr_ok();
while (tls_p->handshake_state <= TLS_HS_IN_PROGRESS) { while (tls_p->handshake_state <= TLS_HS_IN_PROGRESS) {
int err = tls_handshake(tls_p, tls_p->handshake_cb); err = tls_handshake(tls_p, tls_p->handshake_cb);
if (err == kr_error(EAGAIN)) { if (err == kr_error(EAGAIN)) {
break; break;
} else if (err != kr_ok()) { } else if (err != kr_ok()) {
return err; return err;
} }
} }
/* Wait for more data */ if (err == kr_error(EAGAIN)) {
break; /* pull function is out of data */
break;
}
/* There are can be data available, check it. */
continue;
} else if (count < 0) { } else if (count < 0) {
kr_log_verbose("[%s] gnutls_record_recv failed: %s (%zd)\n", kr_log_verbose("[%s] gnutls_record_recv failed: %s (%zd)\n",
logstring, gnutls_strerror_name(count), count); logstring, gnutls_strerror_name(count), count);
...@@ -514,8 +519,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr ...@@ -514,8 +519,21 @@ ssize_t tls_process_input_data(struct session *s, const uint8_t *buf, ssize_t nr
wire_buf += count; wire_buf += count;
wire_buf_size -= count; wire_buf_size -= count;
submitted += count; submitted += count;
if (wire_buf_size == 0 && tls_p->consumed != tls_p->nread) {
/* session buffer is full
* whereas not all the data were consumed */
return kr_error(ENOSPC);
}
}
/* Here all data must be consumed. */
if (tls_p->consumed != tls_p->nread) {
/* Something went wrong, better return error.
* This is most probably due to gnutls_record_recv() did not
* consume all available network data by calling kres_gnutls_pull().
* TODO assess the need for buffering of data amount.
*/
return kr_error(ENOSPC);
} }
assert(tls_p->consumed == tls_p->nread);
return submitted; return submitted;
} }
......
...@@ -94,7 +94,7 @@ struct tls_common_ctx { ...@@ -94,7 +94,7 @@ struct tls_common_ctx {
const uint8_t *buf; const uint8_t *buf;
ssize_t nread; ssize_t nread;
ssize_t consumed; ssize_t consumed;
uint8_t recv_buf[8192]; uint8_t recv_buf[16384];
tls_handshake_cb handshake_cb; tls_handshake_cb handshake_cb;
struct worker_ctx *worker; struct worker_ctx *worker;
size_t write_queue_size; size_t write_queue_size;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment