From 18fdad5578bb70562b3fad569cbb121b01051887 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sat, 17 Aug 2024 09:08:11 +0100 Subject: [PATCH] Add PROXY v1 support --- ChangeLog.txt | 2 +- lib/mosquitto_internal.h | 1 + man/mosquitto.conf.5.xml | 44 ++--- src/CMakeLists.txt | 1 + src/Makefile | 1 + src/conf.c | 18 ++- src/mosquitto_broker_internal.h | 5 +- src/mux_epoll.c | 6 + src/mux_kqueue.c | 6 + src/mux_poll.c | 6 + src/net.c | 10 +- src/proxy_v1.c | 151 ++++++++++++++++++ test/broker/21-proxy-bad-version.py | 32 ++++ test/broker/21-proxy-v1-bad.py | 78 +++++++++ test/broker/21-proxy-v1-success.py | 49 ++++++ test/broker/21-proxy-v2-bad-config.py | 8 +- test/broker/21-proxy-v2-bad-header.py | 4 +- test/broker/21-proxy-v2-ipv4.py | 6 +- test/broker/21-proxy-v2-ipv6.py | 6 +- test/broker/21-proxy-v2-local.py | 4 +- test/broker/21-proxy-v2-long-tlv.py | 6 +- test/broker/21-proxy-v2-lost-connection.py | 4 +- test/broker/21-proxy-v2-ssl-cipher.py | 6 +- .../21-proxy-v2-ssl-common-name-failure.py | 6 +- .../21-proxy-v2-ssl-common-name-success.py | 6 +- .../21-proxy-v2-ssl-require-cert-failure.py | 6 +- .../21-proxy-v2-ssl-require-cert-success.py | 6 +- .../21-proxy-v2-ssl-require-tls-failure.py | 6 +- .../21-proxy-v2-ssl-require-tls-success.py | 6 +- test/broker/21-proxy-v2-unix.py | 6 +- test/broker/21-proxy-v2-websockets.py | 6 +- test/broker/Makefile | 3 + .../{proxy_v2_helper.py => proxy_helper.py} | 12 +- test/broker/test.py | 7 +- 34 files changed, 440 insertions(+), 84 deletions(-) create mode 100644 src/proxy_v1.c create mode 100755 test/broker/21-proxy-bad-version.py create mode 100755 test/broker/21-proxy-v1-bad.py create mode 100755 test/broker/21-proxy-v1-success.py rename test/broker/{proxy_v2_helper.py => proxy_helper.py} (72%) diff --git a/ChangeLog.txt b/ChangeLog.txt index a2484507ee..87429e60ed 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -74,7 +74,7 @@ Broker: choose TLS v1.1, but this is not recommended and will be removed in a future version. - Add -q option to allow logging to be disabled at the command line. -- Add suport for PROXY protocol v2. +- Add suport for PROXY protocol v1 and v2. Plugins / plugin interface: - Add persist-sqlite plugin. diff --git a/lib/mosquitto_internal.h b/lib/mosquitto_internal.h index 8ef72192fd..0dee44fb9f 100644 --- a/lib/mosquitto_internal.h +++ b/lib/mosquitto_internal.h @@ -149,6 +149,7 @@ enum mosquitto__transport { mosq_t_sctp = 3, mosq_t_http = 4, /* not valid for MQTT, just as a ws precursor */ mosq_t_proxy_v2 = 5, /* not valid for MQTT, just as a PROXY protocol v2 precursor */ + mosq_t_proxy_v1 = 6, /* not valid for MQTT, just as a PROXY protocol v1 precursor */ }; /* Alias direction - local <-> remote */ diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index 2170e64a41..49e985891d 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -1289,11 +1289,18 @@ accept_protocol_versions 3, 4 - [ true | false ] + [ 2 | 1 ] - Enable PROXY protocol v2 support for this listener. - Defaults to false. This requires the use of a load + Enable PROXY protocol support for this listener. + Versions 1 and 2 are supported, if you have the + choice then version 2 is recommended because it + gives you access to TLS information, and support + Unix sockets. + + + + This option requires the use of a load balancer/proxy such as HAProxy in front of Mosquitto, with the proxy configured to use the PROXY protocol. @@ -1317,28 +1324,25 @@ accept_protocol_versions 3, 4 - This option can be used with TLS termination on the - proxy. In this case, TLS information will be passed - to the broker as well. Use - to reject clients that do not use TLS - this is - strongly recommended. Enabling - on the - listener will result in the broker checking the TLS - information provided to ensure that the client has - provided a valid certificate. Enabling - as well - will result in the - commonName value from - the certificate being used as the client username - instead of any provided in the CONNECT packet. In - both cases, the listener must not have TLS - configured. + When using PROXY version 2, this option can be used + with TLS termination on the proxy. In this case, TLS + information will be passed to the broker as well. + Use + to reject clients that do not use TLS - this is strongly + recommended. Enabling + on the listener will result in the broker checking the TLS + information provided to ensure that the client has provided + a valid certificate. Enabling + as well will result in the commonName + value from the certificate being used as the client username instead + of any provided in the CONNECT packet. In both cases, the listener + must not have TLS configured. It is not possible to use the , , or options - in conjunction with . + in conjunction with . Not reloaded on reload signal. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dae22bd590..c6ba069261 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,7 @@ add_executable(mosquitto plugin_tick.c plugin_unsubscribe.c property_broker.c + proxy_v1.c proxy_v2.c ../lib/property_mosq.c ../lib/property_mosq.h psk_file.c diff --git a/src/Makefile b/src/Makefile index 1a32fc44b1..0c65d5c985 100644 --- a/src/Makefile +++ b/src/Makefile @@ -93,6 +93,7 @@ OBJS= mosquitto.o \ plugin_subscribe.o \ plugin_unsubscribe.o \ plugin_tick.o \ + proxy_v1.o \ proxy_v2.o \ psk_file.o \ read_handle.o \ diff --git a/src/conf.c b/src/conf.c index edc1b6dd96..aa1b9a66cb 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1600,9 +1600,13 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload, #else log__printf(NULL, MOSQ_LOG_WARNING, "Warning: $CONTROL support not available (enable_control_api)."); #endif - }else if(!strcmp(token, "enable_proxy_protocol_v2")){ + }else if(!strcmp(token, "enable_proxy_protocol")){ REQUIRE_LISTENER(token); - if(conf__parse_bool(&token, "enable_proxy_protocol_v2", &cur_listener->enable_proxy_protocol_v2, &saveptr)) return MOSQ_ERR_INVAL; + if(conf__parse_int(&token, "enable_proxy_protocol", &cur_listener->enable_proxy_protocol, &saveptr)) return MOSQ_ERR_INVAL; + if(cur_listener->enable_proxy_protocol < 1 || cur_listener->enable_proxy_protocol > 2){ + log__printf(NULL, MOSQ_LOG_ERR, "Error: enable_proxy_protocol must be 1 or 2."); + return MOSQ_ERR_INVAL; + } }else if(!strcmp(token, "global_max_clients")){ if(conf__parse_int(&token, "global_max_clients", &config->global_max_clients, &saveptr)) return MOSQ_ERR_INVAL; }else if(!strcmp(token, "global_max_connections")){ @@ -2517,19 +2521,19 @@ int config__read_file(struct mosquitto__config *config, bool reload, const char return rc; } -static int config__check_proxy_v2(struct mosquitto__config *config) +static int config__check_proxy(struct mosquitto__config *config) { for(int i=0; ilistener_count; i++){ struct mosquitto__listener *l = &config->listeners[i]; - if(l->enable_proxy_protocol_v2){ + if(l->enable_proxy_protocol == 2){ if(l->use_subject_as_username){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: use_subject_as_username cannot be used with enable_proxy_protocol_v2."); + log__printf(NULL, MOSQ_LOG_ERR, "Error: use_subject_as_username cannot be used with `enable_proxy_protocol 2`."); return MOSQ_ERR_INVAL; } if(l->certfile || l->keyfile){ - log__printf(NULL, MOSQ_LOG_ERR, "Error: certfile and keyfile cannot be used with enable_proxy_protocol_v2."); + log__printf(NULL, MOSQ_LOG_ERR, "Error: certfile and keyfile cannot be used with `enable_proxy_protocol 2`."); return MOSQ_ERR_INVAL; } } @@ -2563,7 +2567,7 @@ static int config__check(struct mosquitto__config *config) } } - return config__check_proxy_v2(config); + return config__check_proxy(config); } #ifdef WITH_BRIDGE diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index ef1a2e6613..01293c05c9 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -269,7 +269,7 @@ struct mosquitto__listener { bool disable_protocol_v3; bool disable_protocol_v4; bool disable_protocol_v5; - bool enable_proxy_protocol_v2; + int enable_proxy_protocol; bool proxy_protocol_v2_require_tls; }; @@ -965,9 +965,10 @@ int http__write(struct mosquitto *context); void do_disconnect(struct mosquitto *context, int reason); /* ============================================================ - * PROXY v2 related functions + * PROXY related functions * ============================================================ */ int proxy_v2__read(struct mosquitto *context); +int proxy_v1__read(struct mosquitto *context); /* ============================================================ * Will delay diff --git a/src/mux_epoll.c b/src/mux_epoll.c index 468f81db8c..326bdb7962 100644 --- a/src/mux_epoll.c +++ b/src/mux_epoll.c @@ -265,6 +265,9 @@ static void loop_handle_reads_writes(struct mosquitto *context, uint32_t events) case mosq_t_proxy_v2: rc = packet__write(context); break; + case mosq_t_proxy_v1: + rc = packet__write(context); + break; default: rc = MOSQ_ERR_INVAL; break; @@ -295,6 +298,9 @@ static void loop_handle_reads_writes(struct mosquitto *context, uint32_t events) case mosq_t_proxy_v2: rc = proxy_v2__read(context); break; + case mosq_t_proxy_v1: + rc = proxy_v1__read(context); + break; default: rc = MOSQ_ERR_INVAL; break; diff --git a/src/mux_kqueue.c b/src/mux_kqueue.c index 092a36ec34..302f6ac040 100644 --- a/src/mux_kqueue.c +++ b/src/mux_kqueue.c @@ -268,6 +268,9 @@ static void loop_handle_reads_writes(struct mosquitto *context, short event) case mosq_t_proxy_v2: rc = packet__write(context); break; + case mosq_t_proxy_v1: + rc = packet__write(context); + break; default: rc = MOSQ_ERR_INVAL; break; @@ -298,6 +301,9 @@ static void loop_handle_reads_writes(struct mosquitto *context, short event) case mosq_t_proxy_v2: rc = proxy_v2__read(context); break; + case mosq_t_proxy_v1: + rc = proxy_v1__read(context); + break; default: rc = MOSQ_ERR_INVAL; break; diff --git a/src/mux_poll.c b/src/mux_poll.c index 1cc7b270d9..953d1ac282 100644 --- a/src/mux_poll.c +++ b/src/mux_poll.c @@ -327,6 +327,9 @@ static void loop_handle_reads_writes(void) case mosq_t_proxy_v2: rc = packet__write(context); break; + case mosq_t_proxy_v1: + rc = packet__write(context); + break; default: rc = MOSQ_ERR_INVAL; break; @@ -369,6 +372,9 @@ static void loop_handle_reads_writes(void) case mosq_t_proxy_v2: rc = proxy_v2__read(context); break; + case mosq_t_proxy_v1: + rc = proxy_v1__read(context); + break; default: rc = MOSQ_ERR_INVAL; break; diff --git a/src/net.c b/src/net.c index e28db49359..633f220bb0 100644 --- a/src/net.c +++ b/src/net.c @@ -190,13 +190,17 @@ struct mosquitto *net__socket_accept(struct mosquitto__listener_sock *listensock } new_context->listener->client_count++; - if(new_context->listener->enable_proxy_protocol_v2){ + if(new_context->listener->enable_proxy_protocol){ if(context__init_sock(new_context, new_sock, false) != MOSQ_ERR_SUCCESS){ context__cleanup(new_context, true); COMPAT_CLOSE(new_sock); return NULL; } - new_context->transport = mosq_t_proxy_v2; + if(new_context->listener->enable_proxy_protocol == 2){ + new_context->transport = mosq_t_proxy_v2; + }else{ + new_context->transport = mosq_t_proxy_v1; + } new_context->proxy.cmd = -1; }else{ if(context__init_sock(new_context, new_sock, true) != MOSQ_ERR_SUCCESS){ @@ -251,7 +255,7 @@ struct mosquitto *net__socket_accept(struct mosquitto__listener_sock *listensock #endif if(db.config->connection_messages == true - && !new_context->listener->enable_proxy_protocol_v2){ + && !new_context->listener->enable_proxy_protocol){ log__printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s:%d on port %d.", new_context->address, new_context->remote_port, new_context->listener->port); diff --git a/src/proxy_v1.c b/src/proxy_v1.c new file mode 100644 index 0000000000..f544999619 --- /dev/null +++ b/src/proxy_v1.c @@ -0,0 +1,151 @@ +#ifdef WIN32 +# include +#else +# include +#endif +#include +#include "mosquitto_broker_internal.h" +#include "mosquitto_internal.h" +#include "net_mosq.h" + +#define PROXY_V1_PACKET_LIMIT 108 + +const uint8_t signature4[11] = {'P', 'R', 'O', 'X', 'Y', ' ', 'T', 'C', 'P', '4', ' '}; +const uint8_t signature6[11] = {'P', 'R', 'O', 'X', 'Y', ' ', 'T', 'C', 'P', '6', ' '}; +const uint8_t signatureU[14] = {'P', 'R', 'O', 'X', 'Y', ' ', 'U', 'N', 'K', 'N', 'O', 'W', 'N', ' '}; + +static void proxy_cleanup(struct mosquitto *context) +{ + mosquitto_FREE(context->proxy.buf); +} + + +static int update_transport(struct mosquitto *context) +{ + if(context->listener->protocol == mp_websockets){ + return http__context_init(context); + }else{ + context->transport = mosq_t_tcp; + } + return MOSQ_ERR_SUCCESS; +} + + +static int get_address_for_unknown(struct mosquitto *context) +{ + char address[1024]; + + proxy_cleanup(context); + + if(!net__socket_get_address(context->sock, address, sizeof(address), &context->remote_port)){ + context->address = mosquitto_strdup(address); + } + if(!context->address){ + return MOSQ_ERR_NOMEM; + } + return update_transport(context); +} + + +static int proxy_v1__decode(struct mosquitto *context) +{ + char *saddr_s, *daddr_s, *sport_s, *dport_s; + char *saveptr = NULL; + int sport, dport; + struct in6_addr addr; + + if(context->proxy.pos >= sizeof(signatureU) && !memcmp(context->proxy.buf, signatureU, sizeof(signatureU))){ + return get_address_for_unknown(context); + }else if(context->proxy.pos >= sizeof(signature4) && !memcmp(context->proxy.buf, signature4, sizeof(signature4))){ + context->proxy.fam = AF_INET; + }else if(context->proxy.pos >= sizeof(signature6) && !memcmp(context->proxy.buf, signature6, sizeof(signature6))){ + context->proxy.fam = AF_INET6; + }else{ + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + + saddr_s = strtok_r((char *)&context->proxy.buf[sizeof(signature4)], " ", &saveptr); + daddr_s = strtok_r(NULL, " ", &saveptr); + sport_s = strtok_r(NULL, " ", &saveptr); + dport_s = strtok_r(NULL, " ", &saveptr); + + if(!saddr_s || !daddr_s || !sport_s || !dport_s || !saveptr || saveptr[0] != '\0'){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + + /* Verify ports */ + sport = atoi(sport_s); + dport = atoi(dport_s); + if(sport < 1 || sport > 65535 || dport < 1 || dport > 65535){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + + /* Verify addresses */ + if(context->proxy.fam == AF_INET){ + if(inet_pton(AF_INET, saddr_s, &addr) != 1 + || inet_pton(AF_INET, daddr_s, &addr) != 1){ + + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + }else if(context->proxy.fam == AF_INET6){ + if(inet_pton(AF_INET6, saddr_s, &addr) != 1 + || inet_pton(AF_INET6, daddr_s, &addr) != 1){ + + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + } + + context->address = mosquitto_strdup(saddr_s); + if(!context->address){ + proxy_cleanup(context); + return MOSQ_ERR_NOMEM; + } + context->remote_port = (uint16_t )sport; + proxy_cleanup(context); + return update_transport(context); +} + + +int proxy_v1__read(struct mosquitto *context) +{ + if(context->proxy.buf == NULL){ + context->proxy.buf = mosquitto_calloc(1, PROXY_V1_PACKET_LIMIT); + if(!context->proxy.buf){ + return MOSQ_ERR_NOMEM; + } + context->proxy.pos = 0; + } + + while(context->proxy.pos < PROXY_V1_PACKET_LIMIT){ + if(net__read(context, &(context->proxy.buf[context->proxy.pos]), 1) != 1){ + proxy_cleanup(context); + return MOSQ_ERR_CONN_LOST; + } + context->proxy.pos++; + if(context->proxy.pos > 2){ /* FIXME: Figure out better limit */ + if(context->proxy.buf[context->proxy.pos-1] == '\n' + && context->proxy.buf[context->proxy.pos-2] == '\r'){ + + /* Line received, now decode */ + return proxy_v1__decode(context); + } + } + } + if(context->proxy.pos == PROXY_V1_PACKET_LIMIT){ + log__printf(NULL, MOSQ_LOG_NOTICE, "Connection rejected, corrupt PROXY header."); + proxy_cleanup(context); + return MOSQ_ERR_INVAL; + } + + return MOSQ_ERR_SUCCESS; +} diff --git a/test/broker/21-proxy-bad-version.py b/test/broker/21-proxy-bad-version.py new file mode 100755 index 0000000000..bbeae2e254 --- /dev/null +++ b/test/broker/21-proxy-bad-version.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * +import json +import shutil +import socket + +def write_config(filename, port, ver): + with open(filename, 'w') as f: + f.write("log_type all\n") + f.write("listener %d\n" % (port)) + f.write("allow_anonymous true\n") + f.write(f"enable_proxy_protocol {ver}\n") + +def do_test(ver, expect_fail_log): + port = mosq_test.get_port() + conf_file = os.path.basename(__file__).replace('.py', '.conf') + + rc = 1 + write_config(conf_file, port, ver) + try: + broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port, expect_fail=True, expect_fail_log=expect_fail_log) + rc = 0 + except subprocess.TimeoutExpired: + pass + + os.remove(conf_file) + if rc != 0: + raise ValueError(rc) + +do_test(0, "Error: enable_proxy_protocol must be 1 or 2.") +do_test(3, "Error: enable_proxy_protocol must be 1 or 2.") diff --git a/test/broker/21-proxy-v1-bad.py b/test/broker/21-proxy-v1-bad.py new file mode 100755 index 0000000000..f9157336a6 --- /dev/null +++ b/test/broker/21-proxy-v1-bad.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * +from proxy_helper import * +import json +import shutil +import socket + +def write_config(filename, port): + with open(filename, 'w') as f: + f.write("log_type all\n") + f.write("listener %d\n" % (port)) + f.write("allow_anonymous true\n") + f.write("enable_proxy_protocol 1\n") + +def do_test(data, expect_log): + port = mosq_test.get_port() + conf_file = os.path.basename(__file__).replace('.py', '.conf') + write_config(conf_file, port) + + connect_packet = mosq_test.gen_connect("proxy-test", keepalive=42, clean_session=False, proto_ver=5) + connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + + broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) + + rc = 1 + + try: + sock = do_proxy_v1_connect(port, data) + try: + d = sock.recv(1) + if len(d) == 0: + rc = 0 + except ConnectionResetError: + rc = 0 + sock.close() + except mosq_test.TestError: + pass + finally: + os.remove(conf_file) + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc != 0 or expect_log not in stde.decode('utf-8'): + print(stde.decode('utf-8')) + print(data) + exit(1) + + +# Basic +do_test(b"PROXY TCP3 192.0.2.5 127.0.0.1 6275 1234\r\n", "Connection rejected, corrupt PROXY header.") # Bad transport +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 6275 1234 \r\n", "Connection rejected, corrupt PROXY header.") # Too long + +# TCP4 +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 6275\r\n", "Connection rejected, corrupt PROXY header.") # Missing dport +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1\r\n", "Connection rejected, corrupt PROXY header.") # Missing sport +do_test(b"PROXY TCP4 192.0.2.5\r\n", "Connection rejected, corrupt PROXY header.") # Missing daddr +do_test(b"PROXY TCP4 \r\n", "Connection rejected, corrupt PROXY header.") # Missing saddr +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 6275 0\r\n", "Connection rejected, corrupt PROXY header.") # dport == 0 +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 6275 65536\r\n", "Connection rejected, corrupt PROXY header.") # dport == 65536 +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 0 1234\r\n", "Connection rejected, corrupt PROXY header.") # sport == 0 +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 65536 1234\r\n", "Connection rejected, corrupt PROXY header.") # sport == 65536 +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.256 6275 1234\r\n", "Connection rejected, corrupt PROXY header.") # daddr invalid +do_test(b"PROXY TCP4 192.0.2.256 127.0.0.1 6275 1234\r\n", "Connection rejected, corrupt PROXY header.") # saddr invalid + +# TCP6 +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1 6275\r\n", "Connection rejected, corrupt PROXY header.") # Missing dport +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1\r\n", "Connection rejected, corrupt PROXY header.") # Missing sport +do_test(b"PROXY TCP6 192.0.2.5\r\n", "Connection rejected, corrupt PROXY header.") # Missing daddr +do_test(b"PROXY TCP6 \r\n", "Connection rejected, corrupt PROXY header.") # Missing saddr +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1 6275 0\r\n", "Connection rejected, corrupt PROXY header.") # dport == 0 +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1 6275 65536\r\n", "Connection rejected, corrupt PROXY header.") # dport == 65536 +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1 0 1234\r\n", "Connection rejected, corrupt PROXY header.") # sport == 0 +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.1 65536 1234\r\n", "Connection rejected, corrupt PROXY header.") # sport == 65536 +do_test(b"PROXY TCP6 192.0.2.5 127.0.0.256 6275 1234\r\n", "Connection rejected, corrupt PROXY header.") # daddr invalid +do_test(b"PROXY TCP6 192.0.2.256 127.0.0.1 6275 1234\r\n", "Connection rejected, corrupt PROXY header.") # saddr invalid diff --git a/test/broker/21-proxy-v1-success.py b/test/broker/21-proxy-v1-success.py new file mode 100755 index 0000000000..62d11a3d0e --- /dev/null +++ b/test/broker/21-proxy-v1-success.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 + +from mosq_test_helper import * +from proxy_helper import * +import json +import shutil +import socket + +def write_config(filename, port): + with open(filename, 'w') as f: + f.write("log_type all\n") + f.write("listener %d\n" % (port)) + f.write("allow_anonymous true\n") + f.write("enable_proxy_protocol 1\n") + +def do_test(data, expect_log): + port = mosq_test.get_port() + conf_file = os.path.basename(__file__).replace('.py', '.conf') + write_config(conf_file, port) + + connect_packet = mosq_test.gen_connect("proxy-test", keepalive=42, clean_session=False, proto_ver=5) + connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) + + broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port) + + rc = 1 + + try: + sock = do_proxy_v1_connect(port, data) + mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") + mosq_test.do_ping(sock) + sock.close() + rc = 0 + except mosq_test.TestError: + pass + finally: + os.remove(conf_file) + broker.terminate() + if mosq_test.wait_for_subprocess(broker): + print("broker not terminated") + if rc == 0: rc=1 + (stdo, stde) = broker.communicate() + if rc != 0 or expect_log not in stde.decode('utf-8'): + print(stde.decode('utf-8')) + exit(1) + +do_test(b"PROXY TCP4 192.0.2.5 127.0.0.1 6275 1234\r\n", "New client connected from 192.0.2.5:6275") +do_test(b"PROXY TCP6 2001:db8:506:708:900::1 ::1 6275 1234\r\n", "New client connected from 2001:db8:506:708:900::1:6275 as proxy-test (p5, c0, k42)") +do_test(b"PROXY UNKNOWN \r\n", "New client connected from 127.0.0.1:") diff --git a/test/broker/21-proxy-v2-bad-config.py b/test/broker/21-proxy-v2-bad-config.py index da36cd0bcc..4fe2e6b01d 100755 --- a/test/broker/21-proxy-v2-bad-config.py +++ b/test/broker/21-proxy-v2-bad-config.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port, extra_options): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write(extra_options) def do_test(extra_options, expect_fail_log): @@ -30,5 +30,5 @@ def do_test(extra_options, expect_fail_log): if rc != 0: raise ValueError(rc) -do_test("use_subject_as_username true\n", "Error: use_subject_as_username cannot be used with enable_proxy_protocol_v2.") -do_test(f"certfile {ssl_dir}/server.crt\nkeyfile {ssl_dir}/server.key\n", "Error: certfile and keyfile cannot be used with enable_proxy_protocol_v2.") +do_test("use_subject_as_username true\n", "Error: use_subject_as_username cannot be used with `enable_proxy_protocol 2`.") +do_test(f"certfile {ssl_dir}/server.crt\nkeyfile {ssl_dir}/server.key\n", "Error: certfile and keyfile cannot be used with `enable_proxy_protocol 2`.") diff --git a/test/broker/21-proxy-v2-bad-header.py b/test/broker/21-proxy-v2-bad-header.py index cb90fc0e76..1ada7c9c7a 100755 --- a/test/broker/21-proxy-v2-bad-header.py +++ b/test/broker/21-proxy-v2-bad-header.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") connect_packet = mosq_test.gen_connect("proxy-test", keepalive=42, clean_session=False, proto_ver=5) connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) diff --git a/test/broker/21-proxy-v2-ipv4.py b/test/broker/21-proxy-v2-ipv4.py index debec2650c..ef936d0b13 100755 --- a/test/broker/21-proxy-v2-ipv4.py +++ b/test/broker/21-proxy-v2-ipv4.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") port = mosq_test.get_port() conf_file = os.path.basename(__file__).replace('.py', '.conf') @@ -28,7 +28,7 @@ def write_config(filename, port): try: data = b"\xC0\x00\x02\x05" + b"\x00\x00\x00\x00" + b"\x18\x83" + b"\x00\x00" - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-ipv6.py b/test/broker/21-proxy-v2-ipv6.py index 275401a24f..9a891f5659 100755 --- a/test/broker/21-proxy-v2-ipv6.py +++ b/test/broker/21-proxy-v2-ipv6.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") port = mosq_test.get_port() conf_file = os.path.basename(__file__).replace('.py', '.conf') @@ -30,7 +30,7 @@ def write_config(filename, port): data = b"\x20\x01\x0d\xb8\x05\x06\x07\x08\x09\x00\x00\x00\x00\x00\x00\x01" \ + b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ + b"\x18\x83" + b"\x00\x00" - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV6 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV6 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-local.py b/test/broker/21-proxy-v2-local.py index 8a3ca668da..f5d1b8b2cf 100755 --- a/test/broker/21-proxy-v2-local.py +++ b/test/broker/21-proxy-v2-local.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") def do_test(header): port = mosq_test.get_port() diff --git a/test/broker/21-proxy-v2-long-tlv.py b/test/broker/21-proxy-v2-long-tlv.py index 4f713b68c7..3a3bfdaefd 100755 --- a/test/broker/21-proxy-v2-long-tlv.py +++ b/test/broker/21-proxy-v2-long-tlv.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") def do_test(fam): port = mosq_test.get_port() @@ -29,7 +29,7 @@ def do_test(fam): try: data = b"a"*501 - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, fam | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, fam | PROXY_PROTO_TCP, data) try: data = sock.recv(10) if len(data) == 0: diff --git a/test/broker/21-proxy-v2-lost-connection.py b/test/broker/21-proxy-v2-lost-connection.py index da3a977162..7d8b9eba27 100755 --- a/test/broker/21-proxy-v2-lost-connection.py +++ b/test/broker/21-proxy-v2-lost-connection.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") connect_packet = mosq_test.gen_connect("proxy-test", keepalive=42, clean_session=False, proto_ver=5) connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5) diff --git a/test/broker/21-proxy-v2-ssl-cipher.py b/test/broker/21-proxy-v2-ssl-cipher.py index 0697553899..273262577d 100755 --- a/test/broker/21-proxy-v2-ssl-cipher.py +++ b/test/broker/21-proxy-v2-ssl-cipher.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") def do_test(data): expect_log = "Connection from 192.0.2.5:6275 negotiated TLSv1.3 cipher pqrstuv" @@ -27,7 +27,7 @@ def do_test(data): rc = 1 try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-ssl-common-name-failure.py b/test/broker/21-proxy-v2-ssl-common-name-failure.py index 6d4b5eb1fb..95dadf128d 100755 --- a/test/broker/21-proxy-v2-ssl-common-name-failure.py +++ b/test/broker/21-proxy-v2-ssl-common-name-failure.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("require_certificate true\n") f.write("use_identity_as_username true\n") @@ -28,7 +28,7 @@ def do_test(data, expect_log): rc = 1 try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) sock.send(connect_packet) try: mosq_test.expect_packet(sock, "connack", connack_packet) diff --git a/test/broker/21-proxy-v2-ssl-common-name-success.py b/test/broker/21-proxy-v2-ssl-common-name-success.py index 7dd228236d..02b27db71b 100755 --- a/test/broker/21-proxy-v2-ssl-common-name-success.py +++ b/test/broker/21-proxy-v2-ssl-common-name-success.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("require_certificate true\n") f.write("use_identity_as_username true\n") @@ -29,7 +29,7 @@ def do_test(data): rc = 1 try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-ssl-require-cert-failure.py b/test/broker/21-proxy-v2-ssl-require-cert-failure.py index 1f233238cb..4f47d28053 100755 --- a/test/broker/21-proxy-v2-ssl-require-cert-failure.py +++ b/test/broker/21-proxy-v2-ssl-require-cert-failure.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("require_certificate true\n") def do_test(data): @@ -25,7 +25,7 @@ def do_test(data): expect_log = "Connection from 192.0.2.5:6275 rejected, client did not provide a certificate." try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) try: data = sock.recv(10) if len(data) == 0: diff --git a/test/broker/21-proxy-v2-ssl-require-cert-success.py b/test/broker/21-proxy-v2-ssl-require-cert-success.py index 27e959f904..620cfd9822 100755 --- a/test/broker/21-proxy-v2-ssl-require-cert-success.py +++ b/test/broker/21-proxy-v2-ssl-require-cert-success.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("require_certificate true\n") def do_test(data): @@ -28,7 +28,7 @@ def do_test(data): expect_log = "New client connected from 192.0.2.5:6275 as proxy-test (p5, c0, k42)." try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-ssl-require-tls-failure.py b/test/broker/21-proxy-v2-ssl-require-tls-failure.py index e6f03f2b3d..b49bb592ed 100755 --- a/test/broker/21-proxy-v2-ssl-require-tls-failure.py +++ b/test/broker/21-proxy-v2-ssl-require-tls-failure.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("proxy_protocol_v2_require_tls true\n") def do_test(data): @@ -25,7 +25,7 @@ def do_test(data): expect_log = "Connection from 192.0.2.5:6275 rejected, client did not connect using TLS." try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) try: data = sock.recv(10) if len(data) == 0: diff --git a/test/broker/21-proxy-v2-ssl-require-tls-success.py b/test/broker/21-proxy-v2-ssl-require-tls-success.py index 2545437754..595b623251 100755 --- a/test/broker/21-proxy-v2-ssl-require-tls-success.py +++ b/test/broker/21-proxy-v2-ssl-require-tls-success.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("proxy_protocol_v2_require_tls true\n") def do_test(data): @@ -28,7 +28,7 @@ def do_test(data): expect_log = "New client connected from 192.0.2.5:6275 as proxy-test (p5, c0, k42)." try: - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-unix.py b/test/broker/21-proxy-v2-unix.py index 3ba6c25fba..76b960d798 100755 --- a/test/broker/21-proxy-v2-unix.py +++ b/test/broker/21-proxy-v2-unix.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") port = mosq_test.get_port() conf_file = os.path.basename(__file__).replace('.py', '.conf') @@ -28,7 +28,7 @@ def write_config(filename, port): try: data = b"/path" - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_UNIX | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_UNIX | PROXY_PROTO_TCP, data) mosq_test.do_send_receive(sock, connect_packet, connack_packet, "connack") mosq_test.do_ping(sock) sock.close() diff --git a/test/broker/21-proxy-v2-websockets.py b/test/broker/21-proxy-v2-websockets.py index b6e4f84e66..243a20fa61 100755 --- a/test/broker/21-proxy-v2-websockets.py +++ b/test/broker/21-proxy-v2-websockets.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from mosq_test_helper import * -from proxy_v2_helper import * +from proxy_helper import * import json import shutil import socket @@ -11,7 +11,7 @@ def write_config(filename, port): f.write("log_type all\n") f.write("listener %d\n" % (port)) f.write("allow_anonymous true\n") - f.write("enable_proxy_protocol_v2 true\n") + f.write("enable_proxy_protocol 2\n") f.write("protocol websockets\n") port = mosq_test.get_port() @@ -29,7 +29,7 @@ def write_config(filename, port): try: data = b"\xC0\x00\x02\x05" + b"\x00\x00\x00\x00" + b"\x18\x83" + b"\x00\x00" - sock = do_proxy_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) + sock = do_proxy_v2_connect(port, PROXY_VER, PROXY_CMD_PROXY, PROXY_FAM_IPV4 | PROXY_PROTO_TCP, data) websocket_req_good = b"GET /mqtt HTTP/1.1\r\n" \ + b"Host: localhost\r\n" \ + b"Upgrade: websocket\r\n" \ diff --git a/test/broker/Makefile b/test/broker/Makefile index 69eee16479..e2c9b38f51 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -320,6 +320,9 @@ endif ./20-sparkplug-aware.py 21: + ./21-proxy-bad-version.py + ./21-proxy-v1-bad.py + ./21-proxy-v1-success.py ./21-proxy-v2-bad-config.py ./21-proxy-v2-bad-header.py ./21-proxy-v2-local.py diff --git a/test/broker/proxy_v2_helper.py b/test/broker/proxy_helper.py similarity index 72% rename from test/broker/proxy_v2_helper.py rename to test/broker/proxy_helper.py index a8535737ec..2214e70eae 100755 --- a/test/broker/proxy_v2_helper.py +++ b/test/broker/proxy_helper.py @@ -11,13 +11,19 @@ PROXY_PROTO_TCP = 0x01 PROXY_PROTO_UDP = 0x02 -def do_proxy_connect(port, ver, cmd, fam, data): +def do_connect(port, data): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect(("localhost", port)) + sock.send(data) + return sock + +def do_proxy_v2_connect(port, ver, cmd, fam, data): proxy_header = b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a" l = len(data) proxy_header += bytes([ver | cmd, fam, (l&0xFF00)>>8, l&0xFF]) proxy_header += data - sock.send(proxy_header) - return sock + return do_connect(port, proxy_header) + +def do_proxy_v1_connect(port, data): + return do_connect(port, data) diff --git a/test/broker/test.py b/test/broker/test.py index 8615da2842..5ee04dd6d7 100755 --- a/test/broker/test.py +++ b/test/broker/test.py @@ -5,7 +5,7 @@ tests = [ #(ports required, 'path'), - (1, './01-bad-initial-packets.py'), + (1, './01-bad-initial-packets.py'), (1, './01-connect-575314.py'), (1, './01-connect-accept-protocol.py'), (1, './01-connect-allow-anonymous.py'), @@ -194,7 +194,7 @@ (2, './10-listener-mount-point.py'), (1, './11-message-expiry.py'), - (1, './11-persistence-autosave-changes.py'), + (1, './11-persistence-autosave-changes.py'), (1, './11-persistent-subscription.py'), (1, './11-persistent-subscription-v5.py'), (1, './11-persistent-subscription-no-local.py'), @@ -265,6 +265,9 @@ (1, './20-sparkplug-compliance.py'), (1, './20-sparkplug-aware.py'), + (1, './21-proxy-bad-version.py'), + (1, './21-proxy-v1-bad.py'), + (1, './21-proxy-v1-success.py'), (1, './21-proxy-v2-bad-config.py'), (1, './21-proxy-v2-bad-header.py'), (1, './21-proxy-v2-local.py'),