summaryrefslogtreecommitdiffstats
path: root/tests/pytests/proxy/tlsproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/pytests/proxy/tlsproxy.c')
-rw-r--r--tests/pytests/proxy/tlsproxy.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/tests/pytests/proxy/tlsproxy.c b/tests/pytests/proxy/tlsproxy.c
new file mode 100644
index 0000000..bcdffb0
--- /dev/null
+++ b/tests/pytests/proxy/tlsproxy.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+
+#include <stdio.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <gnutls/gnutls.h>
+#include "tls-proxy.h"
+
+static char default_local_addr[] = "127.0.0.1";
+static char default_upstream_addr[] = "127.0.0.1";
+static char default_cert_path[] = "../certs/tt.cert.pem";
+static char default_key_path[] = "../certs/tt.key.pem";
+
+void help(char *argv[], struct args *a)
+{
+ printf("Usage: %s [parameters] [rundir]\n", argv[0]);
+ printf("\nParameters:\n"
+ " -l, --local=[addr] Server address to bind to (default: %s).\n"
+ " -p, --lport=[port] Server port to bind to (default: %u).\n"
+ " -u, --upstream=[addr] Upstream address (default: %s).\n"
+ " -d, --uport=[port] Upstream port (default: %u).\n"
+ " -t, --cert=[path] Path to certificate file (default: %s).\n"
+ " -k, --key=[path] Path to key file (default: %s).\n"
+ " -c, --close=[N] Close connection to client after\n"
+ " every N ms (default: %" PRIu64 ").\n"
+ " -f, --fail=[N] Delay every Nth incoming connection by 10 sec,\n"
+ " 0 disables delaying (default: 0).\n"
+ " -r, --rehandshake Do TLS rehandshake after every 8 bytes\n"
+ " sent to the client (default: no).\n"
+ " -a, --acceptonly Accept incoming connections, but don't\n"
+ " connect to upstream (default: no).\n"
+ " -v, --tls13 Force use of TLSv1.3. If not turned on,\n"
+ " TLSv1.2 will be used (default: no).\n"
+ ,
+ a->local_addr, a->local_port,
+ a->upstream, a->upstream_port,
+ a->cert_file, a->key_file,
+ a->close_timeout);
+}
+
+void init_args(struct args *a)
+{
+ a->local_addr = default_local_addr;
+ a->local_port = 54000;
+ a->upstream = default_upstream_addr;
+ a->upstream_port = 53000;
+ a->cert_file = default_cert_path;
+ a->key_file = default_key_path;
+ a->rehandshake = false;
+ a->accept_only = false;
+ a->tls_13 = false;
+ a->close_connection = false;
+ a->close_timeout = 1000;
+ a->max_conn_sequence = 0; /* disabled */
+}
+
+int main(int argc, char **argv)
+{
+ long int li_value = 0;
+ int c = 0, li = 0;
+ struct option opts[] = {
+ {"local", required_argument, 0, 'l'},
+ {"lport", required_argument, 0, 'p'},
+ {"upstream", required_argument, 0, 'u'},
+ {"uport", required_argument, 0, 'd'},
+ {"cert", required_argument, 0, 't'},
+ {"key", required_argument, 0, 'k'},
+ {"close", required_argument, 0, 'c'},
+ {"fail", required_argument, 0, 'f'},
+ {"rehandshake", no_argument, 0, 'r'},
+ {"acceptonly", no_argument, 0, 'a'},
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ {"tls13", no_argument, 0, 'v'},
+#endif
+ {0, 0, 0, 0}
+ };
+ struct args args;
+ init_args(&args);
+ while ((c = getopt_long(argc, argv, "l:p:u:d:t:k:c:f:rav", opts, &li)) != -1) {
+ switch (c)
+ {
+ case 'l':
+ args.local_addr = optarg;
+ break;
+ case 'u':
+ args.upstream = optarg;
+ break;
+ case 't':
+ args.cert_file = optarg;
+ break;
+ case 'k':
+ args.key_file = optarg;
+ break;
+ case 'p':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT16_MAX) {
+ printf("error: '-p' requires a positive"
+ " number less or equal to 65535, not '%s'\n", optarg);
+ return -1;
+ }
+ args.local_port = (uint16_t)li_value;
+ break;
+ case 'd':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT16_MAX) {
+ printf("error: '-d' requires a positive"
+ " number less or equal to 65535, not '%s'\n", optarg);
+ return -1;
+ }
+ args.upstream_port = (uint16_t)li_value;
+ break;
+ case 'c':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0) {
+ printf("[system] error '-c' requires a positive"
+ " number, not '%s'\n", optarg);
+ return -1;
+ }
+ args.close_connection = true;
+ args.close_timeout = li_value;
+ break;
+ case 'f':
+ li_value = strtol(optarg, NULL, 10);
+ if (li_value <= 0 || li_value > UINT32_MAX) {
+ printf("error: '-f' requires a positive"
+ " number less or equal to %i, not '%s'\n",
+ UINT32_MAX, optarg);
+ return -1;
+ }
+ args.max_conn_sequence = (uint32_t)li_value;
+ break;
+ case 'r':
+ args.rehandshake = true;
+ break;
+ case 'a':
+ args.accept_only = true;
+ break;
+ case 'v':
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ args.tls_13 = true;
+#endif
+ break;
+ default:
+ init_args(&args);
+ help(argv, &args);
+ return -1;
+ }
+ }
+ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
+ fprintf(stderr, "failed to set up SIGPIPE handler to ignore(%s)\n",
+ strerror(errno));
+ }
+ 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, &args);
+ 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, "Listen on %s#%u\n"
+ "Upstream is expected on %s#%u\n"
+ "Certificate file %s\n"
+ "Key file %s\n"
+ "Rehandshake %s\n"
+ "Close %s\n"
+ "Refuse incoming connections every %ith%s\n"
+ "Only accept, don't forward %s\n"
+ "Force TLSv1.3 %s\n"
+ ,
+ args.local_addr, args.local_port,
+ args.upstream, args.upstream_port,
+ args.cert_file, args.key_file,
+ args.rehandshake ? "yes" : "no",
+ args.close_connection ? "yes" : "no",
+ args.max_conn_sequence, args.max_conn_sequence ? "" : " (disabled)",
+ args.accept_only ? "yes" : "no",
+#if GNUTLS_VERSION_NUMBER >= 0x030604
+ args.tls_13 ? "yes" : "no"
+#else
+ "Not supported"
+#endif
+ );
+ res = tls_proxy_run(proxy);
+ tls_proxy_free(proxy);
+ return res;
+}
+