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)
/* buf->base points to start of the tls receive buffer.
Decode data free space in session wire buffer. */
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;
}
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
kr_log_verbose("[%s] TLS rehandshake with %s has started\n",
logstring, kr_straddr(peer));
tls_set_hs_state(tls_p, TLS_HS_IN_PROGRESS);
int err = kr_ok();
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)) {
break;
} else if (err != kr_ok()) {
return err;
}
}
/* Wait for more data */
break;
if (err == kr_error(EAGAIN)) {
/* pull function is out of data */
break;
}
/* There are can be data available, check it. */
continue;
} else if (count < 0) {
kr_log_verbose("[%s] gnutls_record_recv failed: %s (%zd)\n",
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
wire_buf += count;
wire_buf_size -= 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;
}
......
......@@ -94,7 +94,7 @@ struct tls_common_ctx {
const uint8_t *buf;
ssize_t nread;
ssize_t consumed;
uint8_t recv_buf[8192];
uint8_t recv_buf[16384];
tls_handshake_cb handshake_cb;
struct worker_ctx *worker;
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