From fdc09ced67b5c5ae0e2eb799d2cec608f58d1aa9 Mon Sep 17 00:00:00 2001 From: Tomas Krizek Date: Wed, 9 Jan 2019 16:07:12 +0100 Subject: pytests/test_rehandshake: use new proxy --- tests/pytests/rehandshake/Makefile | 28 -- tests/pytests/rehandshake/array.h | 1 - tests/pytests/rehandshake/tcp-proxy.c | 336 -------------- tests/pytests/rehandshake/tcp-proxy.h | 12 - tests/pytests/rehandshake/tcproxy.c | 25 - tests/pytests/rehandshake/tls-proxy.c | 848 ---------------------------------- tests/pytests/rehandshake/tls-proxy.h | 14 - tests/pytests/rehandshake/tlsproxy.c | 31 -- tests/pytests/test_rehandshake.py | 74 +-- 9 files changed, 25 insertions(+), 1344 deletions(-) delete mode 100644 tests/pytests/rehandshake/Makefile delete mode 120000 tests/pytests/rehandshake/array.h delete mode 100644 tests/pytests/rehandshake/tcp-proxy.c delete mode 100644 tests/pytests/rehandshake/tcp-proxy.h delete mode 100644 tests/pytests/rehandshake/tcproxy.c delete mode 100644 tests/pytests/rehandshake/tls-proxy.c delete mode 100644 tests/pytests/rehandshake/tls-proxy.h delete mode 100644 tests/pytests/rehandshake/tlsproxy.c (limited to 'tests/pytests') diff --git a/tests/pytests/rehandshake/Makefile b/tests/pytests/rehandshake/Makefile deleted file mode 100644 index 170b89e2..00000000 --- a/tests/pytests/rehandshake/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -CC=gcc -CFLAGS_TLS=-DDEBUG -ggdb3 -O0 -lgnutls -luv -CFLAGS_TCP=-DDEBUG -ggdb3 -O0 -luv - -all: tcproxy tlsproxy - -tlsproxy: tls-proxy.o tlsproxy.o - $(CC) tls-proxy.o tlsproxy.o -o tlsproxy $(CFLAGS_TLS) - -tls-proxy.o: tls-proxy.c tls-proxy.h array.h - $(CC) -c -o $@ $< $(CFLAGS_TLS) - -tlsproxy.o: tlsproxy.c tls-proxy.h - $(CC) -c -o $@ $< $(CFLAGS_TLS) - -tcproxy: tcp-proxy.o tcproxy.o - $(CC) tcp-proxy.o tcproxy.o -o tcproxy $(CFLAGS_TCP) - -tcp-proxy.o: tcp-proxy.c tcp-proxy.h array.h - $(CC) -c -o $@ $< $(CFLAGS_TCP) - -tcproxy.o: tcproxy.c tcp-proxy.h - $(CC) -c -o $@ $< $(CFLAGS_TCP) - -clean: - rm -f tcp-proxy.o tcproxy.o tcproxy tls-proxy.o tlsproxy.o tlsproxy - -.PHONY: all clean diff --git a/tests/pytests/rehandshake/array.h b/tests/pytests/rehandshake/array.h deleted file mode 120000 index 33f18f44..00000000 --- a/tests/pytests/rehandshake/array.h +++ /dev/null @@ -1 +0,0 @@ -../../../lib/generic/array.h \ No newline at end of file diff --git a/tests/pytests/rehandshake/tcp-proxy.c b/tests/pytests/rehandshake/tcp-proxy.c deleted file mode 100644 index ba7198bc..00000000 --- a/tests/pytests/rehandshake/tcp-proxy.c +++ /dev/null @@ -1,336 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "array.h" - -struct buf { - char buf[16 * 1024]; - size_t size; -}; - -enum peer_state { - STATE_NOT_CONNECTED, - STATE_LISTENING, - STATE_CONNECTED, - STATE_CONNECT_IN_PROGRESS, - STATE_CLOSING_IN_PROGRESS -}; - -struct proxy_ctx { - uv_loop_t *loop; - uv_tcp_t server; - uv_tcp_t client; - uv_tcp_t upstream; - struct sockaddr_storage server_addr; - struct sockaddr_storage upstream_addr; - - int server_state; - int client_state; - int upstream_state; - - array_t(struct buf *) buffer_pool; - array_t(struct buf *) upstream_pending; -}; - -static void read_from_upstream_cb(uv_stream_t *upstream, ssize_t nread, const uv_buf_t *buf); -static void read_from_client_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf); - -static struct buf *borrow_io_buffer(struct proxy_ctx *proxy) -{ - struct buf *buf = NULL; - if (proxy->buffer_pool.len > 0) { - buf = array_tail(proxy->buffer_pool); - array_pop(proxy->buffer_pool); - } else { - buf = calloc(1, sizeof (struct buf)); - } - return buf; -} - -static void release_io_buffer(struct proxy_ctx *proxy, struct buf *buf) -{ - if (!buf) { - return; - } - - if (proxy->buffer_pool.len < 1000) { - buf->size = 0; - array_push(proxy->buffer_pool, buf); - } else { - free(buf); - } -} - -static void push_to_upstream_pending(struct proxy_ctx *proxy, const char *buf, size_t size) -{ - while (size > 0) { - struct buf *b = borrow_io_buffer(proxy); - b->size = size <= sizeof(b->buf) ? size : sizeof(b->buf); - memcpy(b->buf, buf, b->size); - array_push(proxy->upstream_pending, b); - size -= b->size; - } -} - -static struct buf *get_first_upstream_pending(struct proxy_ctx *proxy) -{ - struct buf *buf = NULL; - if (proxy->upstream_pending.len > 0) { - buf = proxy->upstream_pending.at[0]; - } - return buf; -} - -static void remove_first_upstream_pending(struct proxy_ctx *proxy) -{ - for (int i = 1; i < proxy->upstream_pending.len; ++i) { - proxy->upstream_pending.at[i - 1] = proxy->upstream_pending.at[i]; - } - if (proxy->upstream_pending.len > 0) { - proxy->upstream_pending.len -= 1; - } -} - -static void clear_upstream_pending(struct proxy_ctx *proxy) -{ - for (int i = 1; i < proxy->upstream_pending.len; ++i) { - struct buf *b = proxy->upstream_pending.at[i]; - release_io_buffer(proxy, b); - } - proxy->upstream_pending.len = 0; -} - -static void clear_buffer_pool(struct proxy_ctx *proxy) -{ - for (int i = 1; i < proxy->buffer_pool.len; ++i) { - struct buf *b = proxy->buffer_pool.at[i]; - free(b); - } - proxy->buffer_pool.len = 0; -} - -static void alloc_uv_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) -{ - buf->base = (char*)malloc(suggested_size); - buf->len = suggested_size; -} - -static void on_client_close(uv_handle_t *handle) -{ - struct proxy_ctx *proxy = (struct proxy_ctx *)handle->loop->data; - proxy->client_state = STATE_NOT_CONNECTED; -} - -static void on_upstream_close(uv_handle_t *handle) -{ - struct proxy_ctx *proxy = (struct proxy_ctx *)handle->loop->data; - proxy->upstream_state = STATE_NOT_CONNECTED; -} - -static void write_to_client_cb(uv_write_t *req, int status) -{ - struct proxy_ctx *proxy = (struct proxy_ctx *)req->handle->loop->data; - free(req); - if (status) { - fprintf(stderr, "error writing to client: %s\n", uv_strerror(status)); - clear_upstream_pending(proxy); - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->client, on_client_close); - } -} - -static void write_to_upstream_cb(uv_write_t *req, int status) -{ - struct proxy_ctx *proxy = (struct proxy_ctx *)req->handle->loop->data; - free(req); - if (status) { - fprintf(stderr, "error writing to upstream: %s\n", uv_strerror(status)); - clear_upstream_pending(proxy); - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - return; - } - if (proxy->upstream_pending.len > 0) { - struct buf *buf = get_first_upstream_pending(proxy); - remove_first_upstream_pending(proxy); - release_io_buffer(proxy, buf); - if (proxy->upstream_state == STATE_CONNECTED && - proxy->upstream_pending.len > 0) { - buf = get_first_upstream_pending(proxy); - /* TODO avoid allocation */ - uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t)); - uv_buf_t wrbuf = uv_buf_init(buf->buf, buf->size); - uv_write(req, (uv_stream_t *)&proxy->upstream, &wrbuf, 1, write_to_upstream_cb); - } - } -} - -static void on_client_connection(uv_stream_t *server, int status) -{ - if (status < 0) { - fprintf(stderr, "incoming connection error: %s\n", uv_strerror(status)); - return; - } - - fprintf(stdout, "incoming connection\n"); - - struct proxy_ctx *proxy = (struct proxy_ctx *)server->loop->data; - if (proxy->client_state != STATE_NOT_CONNECTED) { - fprintf(stderr, "client already connected, ignoring\n"); - return; - } - - uv_tcp_init(proxy->loop, &proxy->client); - proxy->client_state = STATE_CONNECTED; - if (uv_accept(server, (uv_stream_t*)&proxy->client) == 0) { - uv_read_start((uv_stream_t*)&proxy->client, alloc_uv_buffer, read_from_client_cb); - } else { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->client, on_client_close); - } -} - -static void on_connect_to_upstream(uv_connect_t *req, int status) -{ - struct proxy_ctx *proxy = (struct proxy_ctx *)req->handle->loop->data; - free(req); - if (status < 0) { - fprintf(stderr, "error connecting to upstream: %s\n", uv_strerror(status)); - clear_upstream_pending(proxy); - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - return; - } - - proxy->upstream_state = STATE_CONNECTED; - uv_read_start((uv_stream_t*)&proxy->upstream, alloc_uv_buffer, read_from_upstream_cb); - if (proxy->upstream_pending.len > 0) { - struct buf *buf = get_first_upstream_pending(proxy); - /* TODO avoid allocation */ - uv_write_t *wreq = (uv_write_t *) malloc(sizeof(uv_write_t)); - uv_buf_t wrbuf = uv_buf_init(buf->buf, buf->size); - uv_write(wreq, (uv_stream_t *)&proxy->upstream, &wrbuf, 1, write_to_upstream_cb); - } -} - -static void read_from_client_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) -{ - if (nread == 0) { - return; - } - struct proxy_ctx *proxy = (struct proxy_ctx *)client->loop->data; - if (nread < 0) { - if (nread != UV_EOF) { - fprintf(stderr, "error reading from client: %s\n", uv_err_name(nread)); - } - if (proxy->client_state == STATE_CONNECTED) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*) client, on_client_close); - } - return; - } - if (proxy->upstream_state == STATE_CONNECTED) { - if (proxy->upstream_pending.len > 0) { - push_to_upstream_pending(proxy, buf->base, nread); - } else { - /* TODO avoid allocation */ - uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t)); - uv_buf_t wrbuf = uv_buf_init(buf->base, nread); - uv_write(req, (uv_stream_t *)&proxy->upstream, &wrbuf, 1, write_to_upstream_cb); - } - } else if (proxy->upstream_state == STATE_NOT_CONNECTED) { - /* TODO avoid allocation */ - uv_tcp_init(proxy->loop, &proxy->upstream); - uv_connect_t *conn = (uv_connect_t *) malloc(sizeof(uv_connect_t)); - proxy->upstream_state = STATE_CONNECT_IN_PROGRESS; - uv_tcp_connect(conn, &proxy->upstream, (struct sockaddr *)&proxy->upstream_addr, - on_connect_to_upstream); - push_to_upstream_pending(proxy, buf->base, nread); - } else if (proxy->upstream_state == STATE_CONNECT_IN_PROGRESS) { - push_to_upstream_pending(proxy, buf->base, nread); - } -} - -static void read_from_upstream_cb(uv_stream_t *upstream, ssize_t nread, const uv_buf_t *buf) -{ - if (nread == 0) { - return; - } - struct proxy_ctx *proxy = (struct proxy_ctx *)upstream->loop->data; - if (nread < 0) { - if (nread != UV_EOF) { - fprintf(stderr, "error reading from upstream: %s\n", uv_err_name(nread)); - } - clear_upstream_pending(proxy); - if (proxy->upstream_state == STATE_CONNECTED) { - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - } - return; - } - if (proxy->client_state == STATE_CONNECTED) { - /* TODO Avoid allocation */ - uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t)); - uv_buf_t wrbuf = uv_buf_init(buf->base, nread); - uv_write(req, (uv_stream_t *)&proxy->client, &wrbuf, 1, write_to_client_cb); - } -} - -struct proxy_ctx *proxy_allocate() -{ - return malloc(sizeof(struct proxy_ctx)); -} - -int proxy_init(struct proxy_ctx *proxy, - const char *server_addr, int server_port, - const char *upstream_addr, int upstream_port) -{ - proxy->loop = uv_default_loop(); - uv_tcp_init(proxy->loop, &proxy->server); - int res = uv_ip4_addr(server_addr, server_port, (struct sockaddr_in *)&proxy->server_addr); - if (res != 0) { - return res; - } - res = uv_ip4_addr(upstream_addr, upstream_port, (struct sockaddr_in *)&proxy->upstream_addr); - if (res != 0) { - return res; - } - array_init(proxy->buffer_pool); - array_init(proxy->upstream_pending); - proxy->server_state = STATE_NOT_CONNECTED; - proxy->client_state = STATE_NOT_CONNECTED; - proxy->upstream_state = STATE_NOT_CONNECTED; - - proxy->loop->data = proxy; - return 0; -} - -void proxy_free(struct proxy_ctx *proxy) -{ - if (!proxy) { - return; - } - clear_upstream_pending(proxy); - clear_buffer_pool(proxy); - /* TODO correctly close all the uv_tcp_t */ - free(proxy); -} - -int proxy_start_listen(struct proxy_ctx *proxy) -{ - uv_tcp_bind(&proxy->server, (const struct sockaddr*)&proxy->server_addr, 0); - int ret = uv_listen((uv_stream_t*)&proxy->server, 128, on_client_connection); - if (ret == 0) { - proxy->server_state = STATE_LISTENING; - } - return ret; -} - -int proxy_run(struct proxy_ctx *proxy) -{ - return uv_run(proxy->loop, UV_RUN_DEFAULT); -} diff --git a/tests/pytests/rehandshake/tcp-proxy.h b/tests/pytests/rehandshake/tcp-proxy.h deleted file mode 100644 index 668a65fd..00000000 --- a/tests/pytests/rehandshake/tcp-proxy.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -struct proxy_ctx; - -struct proxy_ctx *proxy_allocate(); -void proxy_free(struct proxy_ctx *proxy); -int proxy_init(struct proxy_ctx *proxy, - const char *server_addr, int server_port, - const char *upstream_addr, int upstream_port); -int proxy_start_listen(struct proxy_ctx *proxy); -int proxy_run(struct proxy_ctx *proxy); - diff --git a/tests/pytests/rehandshake/tcproxy.c b/tests/pytests/rehandshake/tcproxy.c deleted file mode 100644 index 87a6b4c1..00000000 --- a/tests/pytests/rehandshake/tcproxy.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include "tcp-proxy.h" - -int main() -{ - struct proxy_ctx *proxy = proxy_allocate(); - if (!proxy) { - fprintf(stderr, "can't allocate proxy structure\n"); - return 1; - } - int res = proxy_init(proxy, "127.0.0.1", 54000, "127.0.0.1", 53001); - if (res) { - fprintf(stderr, "can't initialize proxy by given addresses\n"); - return res; - } - res = proxy_start_listen(proxy); - if (res) { - fprintf(stderr, "error starting listen, error code: %i\n", res); - return res; - } - res = proxy_run(proxy); - proxy_free(proxy); - return res; -} - diff --git a/tests/pytests/rehandshake/tls-proxy.c b/tests/pytests/rehandshake/tls-proxy.c deleted file mode 100644 index bf6cc0d4..00000000 --- a/tests/pytests/rehandshake/tls-proxy.c +++ /dev/null @@ -1,848 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "array.h" - -#define TLS_MAX_SEND_RETRIES 100 -#define CLIENT_ANSWER_CHUNK_SIZE 8 -struct buf { - char buf[16 * 1024]; - size_t size; -}; - -enum peer_state { - STATE_NOT_CONNECTED, - STATE_LISTENING, - STATE_CONNECTED, - STATE_CONNECT_IN_PROGRESS, - STATE_CLOSING_IN_PROGRESS -}; - -enum handshake_state { - TLS_HS_NOT_STARTED = 0, - TLS_HS_EXPECTED, - TLS_HS_IN_PROGRESS, - TLS_HS_DONE, - TLS_HS_CLOSING, - TLS_HS_LAST -}; - -struct tls_ctx { - gnutls_session_t session; - int handshake_state; - gnutls_certificate_credentials_t credentials; - gnutls_priority_t priority_cache; - /* for reading from the network */ - const uint8_t *buf; - ssize_t nread; - ssize_t consumed; - uint8_t recv_buf[4096]; -}; - -struct tls_proxy_ctx { - uv_loop_t *loop; - uv_tcp_t server; - uv_tcp_t client; - uv_tcp_t upstream; - struct sockaddr_storage server_addr; - struct sockaddr_storage upstream_addr; - struct sockaddr_storage client_addr; - - int server_state; - int client_state; - int upstream_state; - - array_t(struct buf *) buffer_pool; - array_t(struct buf *) upstream_pending; - array_t(struct buf *) client_pending; - - char io_buf[0xFFFF]; - struct tls_ctx tls; -}; - -static void read_from_upstream_cb(uv_stream_t *upstream, ssize_t nread, const uv_buf_t *buf); -static void read_from_client_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf); -static ssize_t proxy_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len); -static ssize_t proxy_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len); -static int tls_process_from_upstream(struct tls_proxy_ctx *proxy, const uint8_t *buf, ssize_t nread); -static int tls_process_from_client(struct tls_proxy_ctx *proxy, const uint8_t *buf, ssize_t nread); -static int write_to_upstream_pending(struct tls_proxy_ctx *proxy); -static int write_to_client_pending(struct tls_proxy_ctx *proxy); - - -static int gnutls_references = 0; - -const void *ip_addr(const struct sockaddr *addr) -{ - if (!addr) { - return NULL; - } - switch (addr->sa_family) { - case AF_INET: return (const void *)&(((const struct sockaddr_in *)addr)->sin_addr); - case AF_INET6: return (const void *)&(((const struct sockaddr_in6 *)addr)->sin6_addr); - default: return NULL; - } -} - -uint16_t ip_addr_port(const struct sockaddr *addr) -{ - if (!addr) { - return 0; - } - switch (addr->sa_family) { - case AF_INET: return ntohs(((const struct sockaddr_in *)addr)->sin_port); - case AF_INET6: return ntohs(((const struct sockaddr_in6 *)addr)->sin6_port); - default: return 0; - } -} - -static int ip_addr_str(const struct sockaddr *addr, char *buf, size_t *buflen) -{ - int ret = 0; - if (!addr || !buf || !buflen) { - return EINVAL; - } - - char str[INET6_ADDRSTRLEN + 6]; - if (!inet_ntop(addr->sa_family, ip_addr(addr), str, sizeof(str))) { - return errno; - } - int len = strlen(str); - str[len] = '#'; - snprintf(&str[len + 1], 6, "%uh", ip_addr_port(addr)); - len += 6; - str[len] = 0; - if (len >= *buflen) { - ret = ENOSPC; - } else { - memcpy(buf, str, len + 1); - } - *buflen = len; - return ret; -} - -static inline char *ip_straddr(const struct sockaddr *addr) -{ - assert(addr != NULL); - /* We are the sinle-threaded application */ - static char str[INET6_ADDRSTRLEN + 6]; - size_t len = sizeof(str); - int ret = ip_addr_str(addr, str, &len); - return ret != 0 || len == 0 ? NULL : str; -} - -static struct buf *borrow_io_buffer(struct tls_proxy_ctx *proxy) -{ - struct buf *buf = NULL; - if (proxy->buffer_pool.len > 0) { - buf = array_tail(proxy->buffer_pool); - array_pop(proxy->buffer_pool); - } else { - buf = calloc(1, sizeof (struct buf)); - } - return buf; -} - -static void release_io_buffer(struct tls_proxy_ctx *proxy, struct buf *buf) -{ - if (!buf) { - return; - } - - if (proxy->buffer_pool.len < 1000) { - buf->size = 0; - array_push(proxy->buffer_pool, buf); - } else { - free(buf); - } -} - -static struct buf *get_first_upstream_pending(struct tls_proxy_ctx *proxy) -{ - struct buf *buf = NULL; - if (proxy->upstream_pending.len > 0) { - buf = proxy->upstream_pending.at[0]; - } - return buf; -} - -static struct buf *get_first_client_pending(struct tls_proxy_ctx *proxy) -{ - struct buf *buf = NULL; - if (proxy->client_pending.len > 0) { - buf = proxy->client_pending.at[0]; - } - return buf; -} - -static void remove_first_upstream_pending(struct tls_proxy_ctx *proxy) -{ - for (int i = 1; i < proxy->upstream_pending.len; ++i) { - proxy->upstream_pending.at[i - 1] = proxy->upstream_pending.at[i]; - } - if (proxy->upstream_pending.len > 0) { - proxy->upstream_pending.len -= 1; - } -} - -static void remove_first_client_pending(struct tls_proxy_ctx *proxy) -{ - for (int i = 1; i < proxy->client_pending.len; ++i) { - proxy->client_pending.at[i - 1] = proxy->client_pending.at[i]; - } - if (proxy->client_pending.len > 0) { - proxy->client_pending.len -= 1; - } -} - -static void clear_upstream_pending(struct tls_proxy_ctx *proxy) -{ - for (int i = 0; i < proxy->upstream_pending.len; ++i) { - struct buf *b = proxy->upstream_pending.at[i]; - release_io_buffer(proxy, b); - } - proxy->upstream_pending.len = 0; -} - -static void clear_client_pending(struct tls_proxy_ctx *proxy) -{ - for (int i = 0; i < proxy->client_pending.len; ++i) { - struct buf *b = proxy->client_pending.at[i]; - release_io_buffer(proxy, b); - } - proxy->client_pending.len = 0; -} - -static void clear_buffer_pool(struct tls_proxy_ctx *proxy) -{ - for (int i = 0; i < proxy->buffer_pool.len; ++i) { - struct buf *b = proxy->buffer_pool.at[i]; - free(b); - } - proxy->buffer_pool.len = 0; -} - -static void alloc_uv_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)handle->loop->data; - buf->base = proxy->io_buf; - buf->len = sizeof(proxy->io_buf); -} - -static void on_client_close(uv_handle_t *handle) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)handle->loop->data; - gnutls_deinit(proxy->tls.session); - proxy->tls.handshake_state = TLS_HS_NOT_STARTED; - proxy->client_state = STATE_NOT_CONNECTED; -} - -static void on_dummmy_client_close(uv_handle_t *handle) -{ - free(handle); -} - -static void on_upstream_close(uv_handle_t *handle) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)handle->loop->data; - proxy->upstream_state = STATE_NOT_CONNECTED; -} - -static void write_to_client_cb(uv_write_t *req, int status) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)req->handle->loop->data; - free(req); - if (status) { - fprintf(stderr, "error writing to client: %s\n", uv_strerror(status)); - clear_client_pending(proxy); - clear_upstream_pending(proxy); - if (proxy->client_state == STATE_CONNECTED) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->client, on_client_close); - return; - } - } - fprintf(stdout, "successfully wrote to client, pending len is %zd\n", - proxy->client_pending.len); - if (proxy->client_state == STATE_CONNECTED && - proxy->tls.handshake_state == TLS_HS_DONE) { - write_to_client_pending(proxy); - } -} - -static void write_to_upstream_cb(uv_write_t *req, int status) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)req->handle->loop->data; - if (status) { - free(req); - fprintf(stderr, "error writing to upstream: %s\n", uv_strerror(status)); - clear_upstream_pending(proxy); - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - return; - } - if (req->data != NULL) { - assert(proxy->upstream_pending.len > 0); - struct buf *buf = get_first_upstream_pending(proxy); - assert(req->data == (void *)buf->buf); - fprintf(stdout, "successfully wrote %zi bytes to upstream, pending len is %zd\n", - buf->size, proxy->upstream_pending.len); - remove_first_upstream_pending(proxy); - release_io_buffer(proxy, buf); - } else { - fprintf(stdout, "successfully wrote bytes to upstream, pending len is %zd\n", - proxy->upstream_pending.len); - } - if (proxy->upstream_state == STATE_CONNECTED && - proxy->upstream_pending.len > 0) { - write_to_upstream_pending(proxy); - } - free(req); -} - -static void on_client_connection(uv_stream_t *server, int status) -{ - if (status < 0) { - fprintf(stderr, "incoming connection error: %s\n", uv_strerror(status)); - return; - } - - int err = 0; - int ret = 0; - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)server->loop->data; - if (proxy->client_state != STATE_NOT_CONNECTED) { - fprintf(stderr, "incoming connection"); - uv_tcp_t *dummy_client = malloc(sizeof(uv_tcp_t)); - uv_tcp_init(proxy->loop, dummy_client); - err = uv_accept(server, (uv_stream_t*)dummy_client); - if (err == 0) { - struct sockaddr dummy_addr; - int dummy_addr_len = sizeof(dummy_addr); - ret = uv_tcp_getpeername(dummy_client, - &dummy_addr, - &dummy_addr_len); - if (ret == 0) { - fprintf(stderr, " from %s", ip_straddr(&dummy_addr)); - } - uv_close((uv_handle_t *)dummy_client, on_dummmy_client_close); - } else { - on_dummmy_client_close((uv_handle_t *)dummy_client); - } - fprintf(stderr, " - client already connected, rejecting\n"); - return; - } - - uv_tcp_init(proxy->loop, &proxy->client); - uv_tcp_nodelay((uv_tcp_t *)&proxy->client, 1); - proxy->client_state = STATE_CONNECTED; - err = uv_accept(server, (uv_stream_t*)&proxy->client); - if (err != 0) { - fprintf(stderr, "incoming connection - uv_accept() failed: (%d) %s\n", - err, uv_strerror(err)); - return; - } - - struct sockaddr *addr = (struct sockaddr *)&(proxy->client_addr); - int addr_len = sizeof(proxy->client_addr); - ret = uv_tcp_getpeername(&proxy->client, addr, &addr_len); - if (ret || addr->sa_family == AF_UNSPEC) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->client, on_client_close); - fprintf(stderr, "incoming connection - uv_tcp_getpeername() failed: (%d) %s\n", - err, uv_strerror(err)); - return; - } - - fprintf(stdout, "incoming connection from %s\n", ip_straddr(addr)); - - uv_read_start((uv_stream_t*)&proxy->client, alloc_uv_buffer, read_from_client_cb); - - const char *errpos = NULL; - struct tls_ctx *tls = &proxy->tls; - assert (tls->handshake_state == TLS_HS_NOT_STARTED); - err = gnutls_init(&tls->session, GNUTLS_SERVER | GNUTLS_NONBLOCK); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_init() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - } - err = gnutls_priority_set(tls->session, tls->priority_cache); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_priority_set() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - } - err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, tls->credentials); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_credentials_set() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - } - gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_IGNORE); - gnutls_handshake_set_timeout(tls->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); - - gnutls_transport_set_pull_function(tls->session, proxy_gnutls_pull); - gnutls_transport_set_push_function(tls->session, proxy_gnutls_push); - gnutls_transport_set_ptr(tls->session, proxy); - - tls->handshake_state = TLS_HS_IN_PROGRESS; -} - -static void on_connect_to_upstream(uv_connect_t *req, int status) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)req->handle->loop->data; - free(req); - if (status < 0) { - fprintf(stderr, "error connecting to upstream (%s): %s\n", - ip_straddr((struct sockaddr *)&proxy->upstream_addr), - uv_strerror(status)); - clear_upstream_pending(proxy); - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - return; - } - fprintf(stdout, "connected to %s\n", ip_straddr((struct sockaddr *)&proxy->upstream_addr)); - - proxy->upstream_state = STATE_CONNECTED; - uv_read_start((uv_stream_t*)&proxy->upstream, alloc_uv_buffer, read_from_upstream_cb); - if (proxy->upstream_pending.len > 0) { - write_to_upstream_pending(proxy); - } -} - -static void read_from_client_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) -{ - fprintf(stdout, "reading %zd bytes from client\n", nread); - if (nread == 0) { - return; - } - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)client->loop->data; - if (nread < 0) { - if (nread != UV_EOF) { - fprintf(stderr, "error reading from client: %s\n", uv_err_name(nread)); - } else { - fprintf(stdout, "client has closed the connection\n"); - } - if (proxy->client_state == STATE_CONNECTED) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*) client, on_client_close); - } - return; - } - - int res = tls_process_from_client(proxy, buf->base, nread); - if (res < 0) { - if (proxy->client_state == STATE_CONNECTED) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*) client, on_client_close); - } - } -} - -static void read_from_upstream_cb(uv_stream_t *upstream, ssize_t nread, const uv_buf_t *buf) -{ - fprintf(stdout, "reading %zd bytes from upstream\n", nread); - if (nread == 0) { - return; - } - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)upstream->loop->data; - if (nread < 0) { - if (nread != UV_EOF) { - fprintf(stderr, "error reading from upstream: %s\n", uv_err_name(nread)); - } else { - fprintf(stdout, "upstream has closed the connection\n"); - } - clear_upstream_pending(proxy); - if (proxy->upstream_state == STATE_CONNECTED) { - proxy->upstream_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->upstream, on_upstream_close); - } - return; - } - int res = tls_process_from_upstream(proxy, buf->base, nread); - if (res < 0) { - fprintf(stderr, "error sending tls data to client\n"); - if (proxy->client_state == STATE_CONNECTED) { - proxy->client_state = STATE_CLOSING_IN_PROGRESS; - uv_close((uv_handle_t*)&proxy->client, on_client_close); - } - } -} - -static void push_to_upstream_pending(struct tls_proxy_ctx *proxy, const char *buf, size_t size) -{ - while (size > 0) { - struct buf *b = borrow_io_buffer(proxy); - b->size = size <= sizeof(b->buf) ? size : sizeof(b->buf); - memcpy(b->buf, buf, b->size); - array_push(proxy->upstream_pending, b); - size -= b->size; - buf += b->size; - } -} - -static void push_to_client_pending(struct tls_proxy_ctx *proxy, const char *buf, size_t size) -{ - while (size > 0) { - struct buf *b = borrow_io_buffer(proxy); - b->size = size <= sizeof(b->buf) ? size : sizeof(b->buf); - if (b->size > CLIENT_ANSWER_CHUNK_SIZE) { - b->size = CLIENT_ANSWER_CHUNK_SIZE; - } - memcpy(b->buf, buf, b->size); - array_push(proxy->client_pending, b); - size -= b->size; - buf += b->size; - } -} - -static int write_to_upstream_pending(struct tls_proxy_ctx *proxy) -{ - struct buf *buf = get_first_upstream_pending(proxy); - /* TODO avoid allocation */ - uv_write_t *req = (uv_write_t *) malloc(sizeof(uv_write_t)); - uv_buf_t wrbuf = uv_buf_init(buf->buf, buf->size); - req->data = buf->buf; - fprintf(stdout, "writing %zd bytes to upstream\n", buf->size); - return uv_write(req, (uv_stream_t *)&proxy->upstream, &wrbuf, 1, write_to_upstream_cb); -} - -static ssize_t proxy_gnutls_pull(gnutls_transport_ptr_t h, void *buf, size_t len) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)h; - struct tls_ctx *t = &proxy->tls; - - fprintf(stdout, "\t gnutls: pulling %zd bytes from client\n", len); - - if (t->nread <= t->consumed) { - errno = EAGAIN; - fprintf(stdout, "\t gnutls: return EAGAIN\n"); - return -1; - } - - ssize_t avail = t->nread - t->consumed; - ssize_t transfer = (avail <= len ? avail : len); - memcpy(buf, t->buf + t->consumed, transfer); - t->consumed += transfer; - return transfer; -} - -ssize_t proxy_gnutls_push(gnutls_transport_ptr_t h, const void *buf, size_t len) -{ - struct tls_proxy_ctx *proxy = (struct tls_proxy_ctx *)h; - struct tls_ctx *t = &proxy->tls; - fprintf(stdout, "\t gnutls: writing %zd bytes to client\n", len); - - ssize_t ret = -1; - const size_t req_size_aligned = ((sizeof(uv_write_t) / 16) + 1) * 16; - char *common_buf = malloc(req_size_aligned + len); - uv_write_t *req = (uv_write_t *) common_buf; - char *data = common_buf + req_size_aligned; - const uv_buf_t uv_buf[1] = { - { data, len } - }; - memcpy(data, buf, len); - req->data = data; - int res = uv_write(req, (uv_stream_t *)&proxy->client, uv_buf, 1, write_to_client_cb); - if (res == 0) { - ret = len; - } else { - free(common_buf); - errno = EIO; - } - return ret; -} - -static int write_to_client_pending(struct tls_proxy_ctx *proxy) -{ - if (proxy->client_pending.len == 0) { - return 0; - } - - struct buf *buf = get_first_client_pending(proxy); - uv_buf_t wrbuf = uv_buf_init(buf->buf, buf->size); - fprintf(stdout, "writing %zd bytes to client\n", buf->size); - - gnutls_session_t tls_session = proxy->tls.session; - assert(proxy->tls.handshake_state != TLS_HS_IN_PROGRESS); - assert(gnutls_record_check_corked(tls_session) == 0); - - char *data = buf->buf; - size_t len = buf->size; - - ssize_t count = 0; - ssize_t submitted = len; - ssize_t retries = 0; - do { - count = gnutls_record_send(tls_session, data, len); - if (count < 0) { - if (gnutls_error_is_fatal(count)) { - fprintf(stderr, "gnutls_record_send failed: %s (%zd)\n", - gnutls_strerror_name(count), count); - return -1; - } - if (++retries > TLS_MAX_SEND_RETRIES) { - fprintf(stderr, "gnutls_record_send: too many sequential non-fatal errors (%zd), last error is: %s (%zd)\n", - retries, gnutls_strerror_name(count), count); - return -1; - } - } else if (count != 0) { - data += count; - len -= count; - retries = 0; - } else { - if (++retries < TLS_MAX_SEND_RETRIES) { - continue; - } - fprintf(stderr, "gnutls_record_send: too many retries (%zd)\n", - retries); - fprintf(stderr, "tls_push_to_client didn't send all data(%zd of %zd)\n", - len, submitted); - return -1; - } - } while (len > 0); - - remove_first_client_pending(proxy); - release_io_buffer(proxy, buf); - - fprintf(stdout, "submitted %zd bytes to client\n", submitted); - assert (gnutls_safe_renegotiation_status(tls_session) != 0); - assert (gnutls_rehandshake(tls_session) == GNUTLS_E_SUCCESS); - /* Prevent write-to-client callback from sending next pending chunk. - * At the same time tls_process_from_client() must not call gnutls_handshake() - * as there can be application data in this direction. */ - proxy->tls.handshake_state = TLS_HS_EXPECTED; - fprintf(stdout, "rehandshake started\n"); - return submitted; -} - -static int tls_process_from_upstream(struct tls_proxy_ctx *proxy, const uint8_t *buf, ssize_t len) -{ - gnutls_session_t tls_session = proxy->tls.session; - - fprintf(stdout, "pushing %zd bytes to client\n", len); - - assert(gnutls_record_check_corked(tls_session) == 0); - ssize_t submitted = 0; - if (proxy->client_state != STATE_CONNECTED) { - return submitted; - } - - bool list_was_empty = (proxy->client_pending.len == 0); - push_to_client_pending(proxy, buf, len); - submitted = len; - if (proxy->tls.handshake_state == TLS_HS_DONE) { - if (list_was_empty && proxy->client_pending.len > 0) { - int ret = write_to_client_pending(proxy); - if (ret < 0) { - submitted = -1; - } - } - } - - return submitted; -} - -int tls_process_handshake(struct tls_proxy_ctx *proxy) -{ - struct tls_ctx *tls = &proxy->tls; - int ret = 1; - while (tls->handshake_state == TLS_HS_IN_PROGRESS) { - fprintf(stdout, "TLS handshake in progress...\n"); - int err = gnutls_handshake(tls->session); - if (err == GNUTLS_E_SUCCESS) { - tls->handshake_state = TLS_HS_DONE; - fprintf(stdout, "TLS handshake has completed\n"); - ret = 1; - if (proxy->client_pending.len != 0) { - write_to_client_pending(proxy); - } - } else if (gnutls_error_is_fatal(err)) { - fprintf(stderr, "gnutls_handshake failed: %s (%d)\n", - gnutls_strerror_name(err), err); - ret = -1; - break; - } else { - fprintf(stderr, "gnutls_handshake nonfatal error: %s (%d)\n", - gnutls_strerror_name(err), err); - ret = 0; - break; - } - } - return ret; -} - -int tls_process_from_client(struct tls_proxy_ctx *proxy, const uint8_t *buf, ssize_t nread) -{ - struct tls_ctx *tls = &proxy->tls; - - tls->buf = buf; - tls->nread = nread >= 0 ? nread : 0; - tls->consumed = 0; - - fprintf(stdout, "tls_process: reading %zd bytes from client\n", nread); - - int ret = tls_process_handshake(proxy); - if (ret <= 0) { - return ret; - } - - int submitted = 0; - while (true) { - ssize_t count = 0; - count = gnutls_record_recv(tls->session, tls->recv_buf, sizeof(tls->recv_buf)); - if (count == GNUTLS_E_AGAIN) { - break; /* No data available */ - } else if (count == GNUTLS_E_INTERRUPTED) { - continue; /* Try reading again */ - } else if (count == GNUTLS_E_REHANDSHAKE) { - tls->handshake_state = TLS_HS_IN_PROGRESS; - ret = tls_process_handshake(proxy); - if (ret <= 0) { - return ret; - } - continue; - } else if (count < 0) { - fprintf(stderr, "gnutls_record_recv failed: %s (%zd)\n", - gnutls_strerror_name(count), count); - return -1; - } else if (count == 0) { - break; - } - if (proxy->upstream_state == STATE_CONNECTED) { - bool upstream_pending_is_empty = (proxy->upstream_pending.len == 0); - push_to_upstream_pending(proxy, tls->recv_buf, count); - if (upstream_pending_is_empty) { - write_to_upstream_pending(proxy); - } - } else if (proxy->upstream_state == STATE_NOT_CONNECTED) { - /* TODO avoid allocation */ - uv_tcp_init(proxy->loop, &proxy->upstream); - uv_connect_t *conn = (uv_connect_t *) malloc(sizeof(uv_connect_t)); - proxy->upstream_state = STATE_CONNECT_IN_PROGRESS; - fprintf(stdout, "connecting to %s\n", - ip_straddr((struct sockaddr *)&proxy->upstream_addr)); - uv_tcp_connect(conn, &proxy->upstream, (struct sockaddr *)&proxy->upstream_addr, - on_connect_to_upstream); - push_to_upstream_pending(proxy, tls->recv_buf, count); - } else if (proxy->upstream_state == STATE_CONNECT_IN_PROGRESS) { - push_to_upstream_pending(proxy, tls->recv_buf, count); - } - submitted += count; - } - return submitted; -} - -struct tls_proxy_ctx *tls_proxy_allocate() -{ - return malloc(sizeof(struct tls_proxy_ctx)); -} - -int tls_proxy_init(struct tls_proxy_ctx *proxy, - const char *server_addr, int server_port, - const char *upstream_addr, int upstream_port, - const char *cert_file, const char *key_file) -{ - proxy->loop = uv_default_loop(); - uv_tcp_init(proxy->loop, &proxy->server); - int res = uv_ip4_addr(server_addr, server_port, (struct sockaddr_in *)&proxy->server_addr); - if (res != 0) { - fprintf(stderr, "uv_ip4_addr failed with string '%s'\n", server_addr); - return -1; - } - res = uv_ip4_addr(upstream_addr, upstream_port, (struct sockaddr_in *)&proxy->upstream_addr); - if (res != 0) { - fprintf(stderr, "uv_ip4_addr failed with string '%s'\n", upstream_addr); - return -1; - } - array_init(proxy->buffer_pool); - array_init(proxy->upstream_pending); - array_init(proxy->client_pending); - proxy->server_state = STATE_NOT_CONNECTED; - proxy->client_state = STATE_NOT_CONNECTED; - proxy->upstream_state = STATE_NOT_CONNECTED; - - proxy->loop->data = proxy; - - int err = 0; - if (gnutls_references == 0) { - err = gnutls_global_init(); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_global_init() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - return -1; - } - } - gnutls_references += 1; - - err = gnutls_certificate_allocate_credentials(&proxy->tls.credentials); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_certificate_allocate_credentials() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - return -1; - } - - err = gnutls_certificate_set_x509_system_trust(proxy->tls.credentials); - if (err <= 0) { - fprintf(stderr, "gnutls_certificate_set_x509_system_trust() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - return -1; - } - - if (cert_file && key_file) { - err = gnutls_certificate_set_x509_key_file(proxy->tls.credentials, - cert_file, key_file, GNUTLS_X509_FMT_PEM); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_certificate_set_x509_key_file() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - return -1; - } - } - - err = gnutls_priority_init(&proxy->tls.priority_cache, NULL, NULL); - if (err != GNUTLS_E_SUCCESS) { - fprintf(stderr, "gnutls_priority_init() failed: (%d) %s\n", - err, gnutls_strerror_name(err)); - return -1; - } - - - proxy->tls.handshake_state = TLS_HS_NOT_STARTED; - return 0; -} - -void tls_proxy_free(struct tls_proxy_ctx *proxy) -{ - if (!proxy) { - return; - } - clear_upstream_pending(proxy); - clear_client_pending(proxy); - clear_buffer_pool(proxy); - gnutls_certificate_free_credentials(proxy->tls.credentials); - gnutls_priority_deinit(proxy->tls.priority_cache); - /* TODO correctly close all the uv_tcp_t */ - free(proxy); - - gnutls_references -= 1; - if (gnutls_references == 0) { - gnutls_global_deinit(); - } -} - -int tls_proxy_start_listen(struct tls_proxy_ctx *proxy) -{ - uv_tcp_bind(&proxy->server, (const struct sockaddr*)&proxy->server_addr, 0); - int ret = uv_listen((uv_stream_t*)&proxy->server, 128, on_client_connection); - if (ret == 0) { - proxy->server_state = STATE_LISTENING; - } - return ret; -} - -int tls_proxy_run(struct tls_proxy_ctx *proxy) -{ - return uv_run(proxy->loop, UV_RUN_DEFAULT); -} diff --git a/tests/pytests/rehandshake/tls-proxy.h b/tests/pytests/rehandshake/tls-proxy.h deleted file mode 100644 index 1204edac..00000000 --- a/tests/pytests/rehandshake/tls-proxy.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -struct tls_proxy_ctx; - -struct tls_proxy_ctx *tls_proxy_allocate(); -void tls_proxy_free(struct tls_proxy_ctx *proxy); -int tls_proxy_init(struct tls_proxy_ctx *proxy, - const char *server_addr, int server_port, - const char *upstream_addr, int upstream_port, - const char *cert_file, const char *key_file); -int tls_proxy_start_listen(struct tls_proxy_ctx *proxy); -int tls_proxy_run(struct tls_proxy_ctx *proxy); - - diff --git a/tests/pytests/rehandshake/tlsproxy.c b/tests/pytests/rehandshake/tlsproxy.c deleted file mode 100644 index 0c074f1e..00000000 --- a/tests/pytests/rehandshake/tlsproxy.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "tls-proxy.h" -#include - -int main() -{ - struct tls_proxy_ctx *proxy = tls_proxy_allocate(); - if (!proxy) { - fprintf(stderr, "can't allocate tls_proxy structure\n"); - return 1; - } - int res = tls_proxy_init(proxy, - "127.0.0.1", 53921, /* Address to listen */ - "127.0.0.1", 53910, /* Upstream address */ - "../certs/tt.cert.pem", - "../certs/tt.key.pem"); - if (res) { - fprintf(stderr, "can't initialize tls_proxy structure\n"); - return res; - } - res = tls_proxy_start_listen(proxy); - if (res) { - fprintf(stderr, "error starting listen, error code: %i\n", res); - return res; - } - fprintf(stdout, "started...\n"); - res = tls_proxy_run(proxy); - tls_proxy_free(proxy); - return res; -} - diff --git a/tests/pytests/test_rehandshake.py b/tests/pytests/test_rehandshake.py index 5b7c0e80..d3091639 100644 --- a/tests/pytests/test_rehandshake.py +++ b/tests/pytests/test_rehandshake.py @@ -1,62 +1,38 @@ """TLS rehandshake test -Test utilizes rehandshake/tls-proxy, which forwards queries to configured -resolver, but when it sends the response back to the query source, it -performs a rehandshake after every 8 bytes sent. +Test is using TLS proxy with rehandshake. When queries are sent, they are +simply forwarded. When the responses are sent back, a rehandshake is performed +after every 8 bytes. It is expected the answer will be received by the source kresd instance and sent back to the client (this test). - -Make sure to run `make all` in `rehandshake/` to compile the proxy. """ -import os import re import time -import pytest - -from kresd import Forward, make_kresd, PYTESTS_DIR -import proxyutils - +from proxy import HINTS, kresd_tls_client, resolve_hint, TLSProxy -PROXY_PATH = os.path.join(PYTESTS_DIR, 'rehandshake', 'tlsproxy') - -@pytest.mark.skipif(not os.path.exists(PROXY_PATH), - reason="{} not found (did you compile it?)".format(PROXY_PATH)) def test_proxy_rehandshake(tmpdir): - # run forward target instance - workdir = os.path.join(str(tmpdir), 'kresd_fwd_target') - os.makedirs(workdir) - - with make_kresd(workdir, hints=proxyutils.HINTS, port=53910) as kresd_fwd_target: - sock = kresd_fwd_target.ip_tls_socket() - proxyutils.resolve_hint(sock, list(proxyutils.HINTS.keys())[0]) - - with proxyutils.proxy(PROXY_PATH): - # run test kresd instance - workdir2 = os.path.join(str(tmpdir), 'kresd') - os.makedirs(workdir2) - forward = Forward( - proto='tls', ip='127.0.0.1', port=53921, - hostname='transport-test-server.com', ca_file=proxyutils.PROXY_CA_FILE) - with make_kresd(workdir2, forward=forward) as kresd: - sock2 = kresd.ip_tcp_socket() - try: - for hint in proxyutils.HINTS: - proxyutils.resolve_hint(sock2, hint) - time.sleep(0.1) - finally: - # verify log - n_connecting_to = 0 - n_rehandshake = 0 - partial_log = kresd.partial_log() - print(partial_log) - for line in partial_log.splitlines(): - if re.search(r"connecting to: .*", line) is not None: - n_connecting_to += 1 - elif re.search(r"TLS rehandshake .* has started", line) is not None: - n_rehandshake += 1 - assert n_connecting_to == 0 # shouldn't be present in partial log - assert n_rehandshake > 0 + proxy = TLSProxy(rehandshake=True) + + with kresd_tls_client(str(tmpdir), proxy) as kresd: + sock2 = kresd.ip_tcp_socket() + try: + for hint in HINTS: + resolve_hint(sock2, hint) + time.sleep(0.1) + finally: + # verify log + n_connecting_to = 0 + n_rehandshake = 0 + partial_log = kresd.partial_log() + print(partial_log) + for line in partial_log.splitlines(): + if re.search(r"connecting to: .*", line) is not None: + n_connecting_to += 1 + elif re.search(r"TLS rehandshake .* has started", line) is not None: + n_rehandshake += 1 + assert n_connecting_to == 0 # shouldn't be present in partial log + assert n_rehandshake > 0 -- cgit v1.2.3