diff options
| author | Garrett D'Amore <garrett@damore.org> | 2024-11-09 20:10:32 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2024-11-09 20:22:50 -0800 |
| commit | cbe9a27ef7485977fbc7c713376b096b6723da3d (patch) | |
| tree | baba50d93018ac6ce6873be46284f5f893da6e39 /src/supplemental | |
| parent | 0058b766b91f08b34dcef3c7bb55b216099f3f66 (diff) | |
| download | nng-cbe9a27ef7485977fbc7c713376b096b6723da3d.tar.gz nng-cbe9a27ef7485977fbc7c713376b096b6723da3d.tar.bz2 nng-cbe9a27ef7485977fbc7c713376b096b6723da3d.zip | |
websocket: Do not allow a listener or dialer to change TLS while running
This also covers a few test cases that we were missing.
Diffstat (limited to 'src/supplemental')
| -rw-r--r-- | src/supplemental/tls/tls_common.c | 19 | ||||
| -rw-r--r-- | src/supplemental/websocket/wssfile_test.c | 58 |
2 files changed, 77 insertions, 0 deletions
diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c index 49d1a292..b197af91 100644 --- a/src/supplemental/tls/tls_common.c +++ b/src/supplemental/tls/tls_common.c @@ -102,6 +102,7 @@ typedef struct { nng_stream_dialer ops; nng_stream_dialer *d; // underlying TCP dialer nng_tls_config *cfg; + bool started; nni_mtx lk; // protects the config } tls_dialer; @@ -186,6 +187,9 @@ tls_dialer_dial(void *arg, nng_aio *aio) tls_free(conn); return; } + nni_mtx_lock(&d->lk); + d->started = true; + nni_mtx_unlock(&d->lk); nng_stream_dialer_dial(d->d, &conn->conn_aio); } @@ -198,9 +202,15 @@ tls_dialer_set_tls(void *arg, nng_tls_config *cfg) if (cfg == NULL) { return (NNG_EINVAL); } + nng_tls_config_hold(cfg); nni_mtx_lock(&d->lk); + if (d->started) { + nni_mtx_unlock(&d->lk); + nng_tls_config_free(cfg); + return (NNG_EBUSY); + } old = d->cfg; d->cfg = cfg; nni_mtx_unlock(&d->lk); @@ -287,6 +297,7 @@ typedef struct { nng_stream_listener ops; nng_stream_listener *l; nng_tls_config *cfg; + bool started; nni_mtx lk; } tls_listener; @@ -314,6 +325,9 @@ static int tls_listener_listen(void *arg) { tls_listener *l = arg; + nni_mtx_lock(&l->lk); + l->started = true; + nni_mtx_unlock(&l->lk); return (nng_stream_listener_listen(l->l)); } @@ -352,6 +366,11 @@ tls_listener_set_tls(void *arg, nng_tls_config *cfg) nng_tls_config_hold(cfg); nni_mtx_lock(&l->lk); + if (l->started) { + nni_mtx_unlock(&l->lk); + nng_tls_config_free(cfg); + return (NNG_EBUSY); + } old = l->cfg; l->cfg = cfg; nni_mtx_unlock(&l->lk); diff --git a/src/supplemental/websocket/wssfile_test.c b/src/supplemental/websocket/wssfile_test.c index 584f8481..972f040f 100644 --- a/src/supplemental/websocket/wssfile_test.c +++ b/src/supplemental/websocket/wssfile_test.c @@ -9,6 +9,7 @@ // #include "core/nng_impl.h" +#include "nng/nng.h" #include "nng/supplemental/tls/tls.h" #include <nuts.h> @@ -214,6 +215,62 @@ test_cert_file_not_present(void) nng_tls_config_free(c); } +static void +test_tls_config(void) +{ + uint16_t port = nuts_next_port(); + nng_socket s1; + nng_socket s2; + nng_listener l; + nng_dialer d; + char addr[40]; + nng_tls_config *cfg; + + (void) snprintf(addr, sizeof(addr), "wss4://:%u/test", port); + + NUTS_PASS(nng_pair_open(&s1)); + NUTS_PASS(nng_pair_open(&s2)); + NUTS_PASS(nng_listener_create(&l, s1, addr)); + NUTS_PASS(nng_listener_get_tls(l, &cfg)); + nng_tls_config_hold(cfg); + NUTS_TRUE(cfg != NULL); + + init_listener_wss_file(l); + NUTS_PASS(nng_listener_start(l, 0)); + + // make sure we cannot change the auth mode while running + + NUTS_FAIL(nng_listener_set_tls(l, cfg), NNG_EBUSY); + nng_tls_config_free(cfg); + + NUTS_PASS(nng_listener_get_tls(l, &cfg)); + + NUTS_FAIL( + nng_tls_config_auth_mode(cfg, NNG_TLS_AUTH_MODE_NONE), NNG_EBUSY); + + nng_msleep(100); + + snprintf(addr, sizeof(addr), "wss://127.0.0.1:%u/test", port); + + // We find that sometimes this fails due to NNG_EPEERAUTH, but it + // can also fail due to NNG_ECLOSED. This seems to be timing + // dependent, based on receive vs. send timing most likely. + // Applications shouldn't really depend that much on this. + int rv; + + NUTS_PASS(nng_dialer_create(&d, s2, addr)); + rv = nng_dialer_start(d, 0); + NUTS_PASS(nng_dialer_get_tls(d, &cfg)); + NUTS_FAIL(nng_dialer_set_tls(d, cfg), NNG_EBUSY); + + NUTS_TRUE(rv != 0); + NUTS_TRUE((rv == NNG_EPEERAUTH) || (rv == NNG_ECLOSED) || + (rv == NNG_ECRYPTO)); + + NUTS_PASS(nng_close(s1)); + NUTS_PASS(nng_close(s2)); +} + #endif NUTS_TESTS = { @@ -222,6 +279,7 @@ NUTS_TESTS = { { "wss file no verify", test_no_verify }, { "wss file verify works", test_verify_works }, { "wss file ca cert missing", test_cert_file_not_present }, + { "wss tls config", test_tls_config }, #endif { NULL, NULL }, }; |
