1 1.1 christos /* $NetBSD: proxyheader_test.c,v 1.2 2025/01/26 16:25:50 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.1 christos * SPDX-License-Identifier: MPL-2.0 7 1.1 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.1 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos #include <sched.h> /* IWYU pragma: keep */ 17 1.1 christos #include <setjmp.h> 18 1.1 christos #include <stdarg.h> 19 1.1 christos #include <stdio.h> 20 1.1 christos #include <stdlib.h> 21 1.1 christos 22 1.1 christos #define UNIT_TESTING 23 1.1 christos #include <cmocka.h> 24 1.1 christos 25 1.1 christos #include <isc/buffer.h> 26 1.1 christos #include <isc/mem.h> 27 1.1 christos #include <isc/os.h> 28 1.1 christos #include <isc/proxy2.h> 29 1.1 christos #include <isc/random.h> 30 1.1 christos 31 1.1 christos #include "proxyheader_test_data.h" 32 1.1 christos 33 1.1 christos #include <tests/isc.h> 34 1.1 christos 35 1.1 christos typedef struct dummy_handler_cbarg { 36 1.1 christos isc_proxy2_command_t cmd; 37 1.1 christos int socktype; 38 1.1 christos isc_sockaddr_t src_addr; 39 1.1 christos isc_sockaddr_t dst_addr; 40 1.1 christos size_t no_more_calls; 41 1.1 christos size_t tlvs; 42 1.1 christos size_t tls_subtlvs; 43 1.1 christos uint8_t tls_client_flags; 44 1.1 christos bool client_cert_verified; 45 1.1 christos isc_region_t tlv_data; 46 1.1 christos isc_region_t extra; 47 1.1 christos isc_region_t tls_version; 48 1.1 christos isc_region_t tls_common_name; 49 1.1 christos } dummy_handler_cbarg_t; 50 1.1 christos 51 1.1 christos static bool 52 1.1 christos dummy_subtlv_iter_cb(const uint8_t client, const bool client_cert_verified, 53 1.1 christos const isc_proxy2_tlv_subtype_tls_t tls_subtlv_type, 54 1.1 christos const isc_region_t *restrict data, void *cbarg) { 55 1.1 christos dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg; 56 1.1 christos 57 1.1 christos UNUSED(client); 58 1.1 christos UNUSED(client_cert_verified); 59 1.1 christos 60 1.1 christos arg->tls_subtlvs++; 61 1.1 christos 62 1.1 christos switch (tls_subtlv_type) { 63 1.1 christos case ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION: 64 1.1 christos arg->tls_version = *data; 65 1.1 christos break; 66 1.1 christos case ISC_PROXY2_TLV_SUBTYPE_TLS_CN: 67 1.1 christos arg->tls_common_name = *data; 68 1.1 christos break; 69 1.1 christos default: 70 1.1 christos break; 71 1.1 christos }; 72 1.1 christos 73 1.1 christos return true; 74 1.1 christos } 75 1.1 christos 76 1.1 christos static bool 77 1.1 christos dummy_tlv_iter_cb(const isc_proxy2_tlv_type_t tlv_type, 78 1.1 christos const isc_region_t *restrict data, void *cbarg) { 79 1.1 christos dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg; 80 1.1 christos 81 1.1 christos if (arg != NULL) { 82 1.1 christos arg->tlvs++; 83 1.1 christos } 84 1.1 christos 85 1.1 christos if (tlv_type == ISC_PROXY2_TLV_TYPE_TLS) { 86 1.1 christos isc_result_t result = isc_proxy2_subtlv_tls_header_data( 87 1.1 christos data, &arg->tls_client_flags, 88 1.1 christos &arg->client_cert_verified); 89 1.1 christos 90 1.1 christos assert_true(result == ISC_R_SUCCESS); 91 1.1 christos 92 1.1 christos result = isc_proxy2_subtlv_tls_iterate( 93 1.1 christos data, dummy_subtlv_iter_cb, cbarg); 94 1.1 christos 95 1.1 christos assert_true(result == ISC_R_SUCCESS); 96 1.1 christos } 97 1.1 christos return true; 98 1.1 christos } 99 1.1 christos 100 1.1 christos static void 101 1.1 christos proxy2_handler_dummy(const isc_result_t result, const isc_proxy2_command_t cmd, 102 1.1 christos const int socktype, 103 1.1 christos const isc_sockaddr_t *restrict src_addr, 104 1.1 christos const isc_sockaddr_t *restrict dst_addr, 105 1.1 christos const isc_region_t *restrict tlv_blob, 106 1.1 christos const isc_region_t *restrict extra, void *cbarg) { 107 1.1 christos dummy_handler_cbarg_t *arg = (dummy_handler_cbarg_t *)cbarg; 108 1.1 christos 109 1.1 christos UNUSED(extra); 110 1.1 christos 111 1.1 christos if (result == ISC_R_NOMORE && arg != NULL) { 112 1.1 christos arg->no_more_calls++; 113 1.1 christos return; 114 1.1 christos } else if (result != ISC_R_SUCCESS) { 115 1.1 christos return; 116 1.1 christos } 117 1.1 christos 118 1.1 christos if (cmd == ISC_PROXY2_CMD_PROXY && socktype != 0 /* unspec */) { 119 1.1 christos INSIST(src_addr != NULL); 120 1.1 christos INSIST(dst_addr != NULL); 121 1.1 christos } else if (cmd == ISC_PROXY2_CMD_LOCAL) { 122 1.1 christos INSIST(tlv_blob == NULL); 123 1.1 christos INSIST(src_addr == NULL); 124 1.1 christos INSIST(dst_addr == NULL); 125 1.1 christos } 126 1.1 christos 127 1.1 christos if (arg != NULL) { 128 1.1 christos arg->cmd = cmd; 129 1.1 christos arg->socktype = socktype; 130 1.1 christos if (src_addr != NULL) { 131 1.1 christos INSIST(dst_addr != NULL); 132 1.1 christos arg->src_addr = *src_addr; 133 1.1 christos arg->dst_addr = *dst_addr; 134 1.1 christos } 135 1.1 christos } 136 1.1 christos 137 1.1 christos if (tlv_blob) { 138 1.1 christos assert_true(isc_proxy2_tlv_data_verify(tlv_blob) == 139 1.1 christos ISC_R_SUCCESS); 140 1.1 christos if (cbarg != NULL) { 141 1.1 christos isc_proxy2_tlv_iterate(tlv_blob, dummy_tlv_iter_cb, 142 1.1 christos cbarg); 143 1.1 christos } 144 1.1 christos } 145 1.1 christos } 146 1.1 christos 147 1.1 christos static int 148 1.1 christos setup_test_proxy(void **state) { 149 1.1 christos isc_proxy2_handler_t **handler = (isc_proxy2_handler_t **)state; 150 1.1 christos *handler = isc_proxy2_handler_new(mctx, 0, proxy2_handler_dummy, NULL); 151 1.1 christos return 0; 152 1.1 christos } 153 1.1 christos 154 1.1 christos static int 155 1.1 christos teardown_test_proxy(void **state) { 156 1.1 christos isc_proxy2_handler_free((isc_proxy2_handler_t **)state); 157 1.1 christos 158 1.1 christos return 0; 159 1.1 christos } 160 1.1 christos 161 1.1 christos static void 162 1.1 christos test_header_data(isc_proxy2_handler_t *handler, const void *data, 163 1.1 christos const size_t size, const bool tear_apart, 164 1.1 christos const bool tear_randomly) { 165 1.1 christos isc_region_t region = { 0 }; 166 1.1 christos isc_result_t result; 167 1.1 christos 168 1.1 christos if (tear_apart) { 169 1.1 christos isc_buffer_t databuf = { 0 }; 170 1.1 christos isc_buffer_init(&databuf, (void *)data, size); 171 1.1 christos isc_buffer_add(&databuf, size); 172 1.1 christos 173 1.1 christos for (; isc_buffer_remaininglength(&databuf) > 0;) { 174 1.1 christos isc_region_t remaining = { 0 }; 175 1.1 christos size_t sz = 1; 176 1.1 christos 177 1.1 christos if (tear_randomly) { 178 1.1 christos sz = 1 + isc_random_uniform( 179 1.1 christos isc_buffer_remaininglength( 180 1.1 christos &databuf)); 181 1.1 christos } 182 1.1 christos 183 1.1 christos isc_buffer_remainingregion(&databuf, &remaining); 184 1.1 christos remaining.length = sz; 185 1.1 christos 186 1.1 christos result = isc_proxy2_handler_push(handler, &remaining); 187 1.1 christos assert_true(isc_proxy2_handler_result(handler) == 188 1.1 christos result); 189 1.1 christos 190 1.1 christos isc_buffer_forward(&databuf, sz); 191 1.1 christos if (result == ISC_R_SUCCESS) { 192 1.1 christos break; 193 1.1 christos } 194 1.1 christos } 195 1.1 christos 196 1.1 christos } else { 197 1.1 christos result = isc_proxy2_handler_push_data(handler, data, size); 198 1.1 christos assert_true(isc_proxy2_handler_result(handler) == result); 199 1.1 christos } 200 1.1 christos 201 1.1 christos assert_true(isc_proxy2_handler_result(handler) == ISC_R_SUCCESS); 202 1.1 christos isc_proxy2_handler_header(handler, ®ion); 203 1.1 christos assert_true(region.length == size); 204 1.1 christos assert_true(memcmp(region.base, data, region.length) == 0); 205 1.1 christos } 206 1.1 christos 207 1.1 christos static void 208 1.1 christos verify_proxy_v2_header(isc_proxy2_handler_t *handler, 209 1.1 christos dummy_handler_cbarg_t *cbarg) { 210 1.1 christos char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 }; 211 1.1 christos isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 }; 212 1.1 christos isc_result_t result; 213 1.1 christos int socktype = -1; 214 1.1 christos 215 1.1 christos assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY); 216 1.1 christos assert_true(cbarg->socktype == SOCK_STREAM); 217 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET); 218 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET); 219 1.1 christos 220 1.1 christos isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf)); 221 1.1 christos assert_true(strcmp(sabuf, "127.0.0.66#11883") == 0); 222 1.1 christos isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf)); 223 1.1 christos assert_true(strcmp(sabuf, "127.0.0.1#56784") == 0); 224 1.1 christos 225 1.1 christos if (handler != NULL) { 226 1.1 christos result = isc_proxy2_handler_addresses(handler, &socktype, 227 1.1 christos &src_addr, &dst_addr); 228 1.1 christos assert_true(result == ISC_R_SUCCESS); 229 1.1 christos assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr)); 230 1.1 christos assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr)); 231 1.1 christos assert_true(socktype == cbarg->socktype); 232 1.1 christos } 233 1.1 christos 234 1.1 christos assert_true(cbarg->tlvs == 0); 235 1.1 christos assert_true(cbarg->tls_subtlvs == 0); 236 1.1 christos assert_true(cbarg->tls_client_flags == 0); 237 1.1 christos assert_true(cbarg->client_cert_verified == false); 238 1.1 christos } 239 1.1 christos 240 1.1 christos static void 241 1.1 christos verify_proxy_v2_header_with_TLS(isc_proxy2_handler_t *handler, 242 1.1 christos dummy_handler_cbarg_t *cbarg) { 243 1.1 christos char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 }; 244 1.1 christos isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 }; 245 1.1 christos isc_result_t result; 246 1.1 christos int socktype = -1; 247 1.1 christos 248 1.1 christos assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY); 249 1.1 christos assert_true(cbarg->socktype == SOCK_STREAM); 250 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET); 251 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET); 252 1.1 christos 253 1.1 christos isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf)); 254 1.1 christos assert_true(strcmp(sabuf, "127.0.0.67#11883") == 0); 255 1.1 christos isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf)); 256 1.1 christos assert_true(strcmp(sabuf, "127.0.0.1#39754") == 0); 257 1.1 christos 258 1.1 christos if (handler != NULL) { 259 1.1 christos result = isc_proxy2_handler_addresses(handler, &socktype, 260 1.1 christos &src_addr, &dst_addr); 261 1.1 christos assert_true(result == ISC_R_SUCCESS); 262 1.1 christos assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr)); 263 1.1 christos assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr)); 264 1.1 christos assert_true(socktype == cbarg->socktype); 265 1.1 christos } 266 1.1 christos 267 1.1 christos assert_true(cbarg->tlvs == 1); 268 1.1 christos assert_true(cbarg->tls_subtlvs == 1); 269 1.1 christos assert_true(cbarg->tls_client_flags == ISC_PROXY2_CLIENT_TLS); 270 1.1 christos assert_true(cbarg->client_cert_verified == true); 271 1.1 christos 272 1.1 christos /* "TLSv1.2" (w/o trailing '\0') */ 273 1.1 christos assert_true(cbarg->tls_version.length == 7); 274 1.1 christos assert_true(memcmp(cbarg->tls_version.base, "TLSv1.2", 7) == 0); 275 1.1 christos } 276 1.1 christos 277 1.1 christos static void 278 1.1 christos verify_proxy_v2_header_with_TLS_CN(isc_proxy2_handler_t *handler, 279 1.1 christos dummy_handler_cbarg_t *cbarg) { 280 1.1 christos char sabuf[ISC_SOCKADDR_FORMATSIZE] = { 0 }; 281 1.1 christos isc_sockaddr_t src_addr = { 0 }, dst_addr = { 0 }; 282 1.1 christos isc_result_t result; 283 1.1 christos int socktype = -1; 284 1.1 christos 285 1.1 christos assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY); 286 1.1 christos assert_true(cbarg->socktype == SOCK_STREAM); 287 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->dst_addr) == AF_INET); 288 1.1 christos assert_true(isc_sockaddr_pf(&cbarg->src_addr) == AF_INET); 289 1.1 christos 290 1.1 christos isc_sockaddr_format(&cbarg->dst_addr, sabuf, sizeof(sabuf)); 291 1.1 christos assert_true(strcmp(sabuf, "127.0.0.67#11883") == 0); 292 1.1 christos isc_sockaddr_format(&cbarg->src_addr, sabuf, sizeof(sabuf)); 293 1.1 christos assert_true(strcmp(sabuf, "127.0.0.1#40402") == 0); 294 1.1 christos 295 1.1 christos if (handler != NULL) { 296 1.1 christos result = isc_proxy2_handler_addresses(handler, &socktype, 297 1.1 christos &src_addr, &dst_addr); 298 1.1 christos assert_true(result == ISC_R_SUCCESS); 299 1.1 christos assert_true(isc_sockaddr_equal(&src_addr, &cbarg->src_addr)); 300 1.1 christos assert_true(isc_sockaddr_equal(&dst_addr, &cbarg->dst_addr)); 301 1.1 christos assert_true(socktype == cbarg->socktype); 302 1.1 christos } 303 1.1 christos 304 1.1 christos assert_true(cbarg->tlvs == 1); 305 1.1 christos assert_true(cbarg->tls_subtlvs == 2); /* version and common name */ 306 1.1 christos assert_true(cbarg->tls_client_flags == 307 1.1 christos (ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_SESS | 308 1.1 christos ISC_PROXY2_CLIENT_CERT_CONN)); 309 1.1 christos assert_true(cbarg->client_cert_verified == true); 310 1.1 christos 311 1.1 christos /* "TLSv1.2" (w/o trailing '\0') */ 312 1.1 christos assert_true(cbarg->tls_version.length == 7); 313 1.1 christos assert_true(memcmp(cbarg->tls_version.base, "TLSv1.2", 7) == 0); 314 1.1 christos 315 1.1 christos /* "mqttuser1" (w/o trailing '\0') */ 316 1.1 christos assert_true(cbarg->tls_common_name.length == 9); 317 1.1 christos assert_true(memcmp(cbarg->tls_common_name.base, "mqttuser1", 9) == 0); 318 1.1 christos } 319 1.1 christos 320 1.1 christos static void 321 1.1 christos verify_proxy_v2_header_with_AF_UNIX(isc_proxy2_handler_t *handler, 322 1.1 christos dummy_handler_cbarg_t *cbarg) { 323 1.1 christos assert_true(cbarg->cmd == ISC_PROXY2_CMD_PROXY); 324 1.1 christos assert_true(cbarg->socktype == 0); 325 1.1 christos 326 1.1 christos if (handler != NULL) { 327 1.1 christos int socktype = -1; 328 1.1 christos isc_result_t result; 329 1.1 christos 330 1.1 christos result = isc_proxy2_handler_addresses(handler, &socktype, NULL, 331 1.1 christos NULL); 332 1.1 christos 333 1.1 christos assert_int_equal(result, ISC_R_SUCCESS); 334 1.1 christos 335 1.1 christos assert_int_equal(socktype, 0); 336 1.1 christos } 337 1.1 christos } 338 1.1 christos 339 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_generic_test) { 340 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 341 1.1 christos dummy_handler_cbarg_t cbarg = { 0 }; 342 1.1 christos 343 1.1 christos isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg); 344 1.1 christos 345 1.1 christos test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header), 346 1.1 christos false, false); 347 1.1 christos verify_proxy_v2_header(handler, &cbarg); 348 1.1 christos 349 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 350 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS, 351 1.1 christos sizeof(proxy_v2_header_with_TLS), false, false); 352 1.1 christos verify_proxy_v2_header_with_TLS(handler, &cbarg); 353 1.1 christos 354 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 355 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN, 356 1.1 christos sizeof(proxy_v2_header_with_TLS_CN), false, false); 357 1.1 christos verify_proxy_v2_header_with_TLS_CN(handler, &cbarg); 358 1.1 christos 359 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 360 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX, 361 1.1 christos sizeof(proxy_v2_header_with_AF_UNIX), false, false); 362 1.1 christos verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg); 363 1.1 christos } 364 1.1 christos 365 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_generic_byte_by_byte_test) { 366 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 367 1.1 christos dummy_handler_cbarg_t cbarg = { 0 }; 368 1.1 christos 369 1.1 christos isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg); 370 1.1 christos 371 1.1 christos test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header), 372 1.1 christos true, false); 373 1.1 christos verify_proxy_v2_header(handler, &cbarg); 374 1.1 christos assert_true(cbarg.no_more_calls == sizeof(proxy_v2_header) - 1); 375 1.1 christos 376 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 377 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS, 378 1.1 christos sizeof(proxy_v2_header_with_TLS), true, false); 379 1.1 christos verify_proxy_v2_header_with_TLS(handler, &cbarg); 380 1.1 christos assert_true(cbarg.no_more_calls == 381 1.1 christos sizeof(proxy_v2_header_with_TLS) - 1); 382 1.1 christos 383 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 384 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN, 385 1.1 christos sizeof(proxy_v2_header_with_TLS_CN), true, false); 386 1.1 christos verify_proxy_v2_header_with_TLS_CN(handler, &cbarg); 387 1.1 christos assert_true(cbarg.no_more_calls == 388 1.1 christos sizeof(proxy_v2_header_with_TLS_CN) - 1); 389 1.1 christos 390 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 391 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX, 392 1.1 christos sizeof(proxy_v2_header_with_AF_UNIX), true, false); 393 1.1 christos verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg); 394 1.1 christos assert_true(cbarg.no_more_calls == 395 1.1 christos sizeof(proxy_v2_header_with_AF_UNIX) - 1); 396 1.1 christos } 397 1.1 christos 398 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_generic_torn_apart_randomly_test) { 399 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 400 1.1 christos dummy_handler_cbarg_t cbarg = { 0 }; 401 1.1 christos 402 1.1 christos isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg); 403 1.1 christos 404 1.1 christos test_header_data(handler, proxy_v2_header, sizeof(proxy_v2_header), 405 1.1 christos true, true); 406 1.1 christos verify_proxy_v2_header(handler, &cbarg); 407 1.1 christos 408 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 409 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS, 410 1.1 christos sizeof(proxy_v2_header_with_TLS), true, true); 411 1.1 christos verify_proxy_v2_header_with_TLS(handler, &cbarg); 412 1.1 christos 413 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 414 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_TLS_CN, 415 1.1 christos sizeof(proxy_v2_header_with_TLS_CN), true, true); 416 1.1 christos verify_proxy_v2_header_with_TLS_CN(handler, &cbarg); 417 1.1 christos 418 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 419 1.1 christos test_header_data(handler, (void *)proxy_v2_header_with_AF_UNIX, 420 1.1 christos sizeof(proxy_v2_header_with_AF_UNIX), true, true); 421 1.1 christos verify_proxy_v2_header_with_AF_UNIX(handler, &cbarg); 422 1.1 christos } 423 1.1 christos 424 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_direct_test) { 425 1.1 christos isc_result_t result; 426 1.1 christos isc_region_t region = { 0 }; 427 1.1 christos dummy_handler_cbarg_t cbarg = { 0 }; 428 1.1 christos 429 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 430 1.1 christos region.base = (uint8_t *)proxy_v2_header; 431 1.1 christos region.length = sizeof(proxy_v2_header); 432 1.1 christos result = isc_proxy2_header_handle_directly( 433 1.1 christos ®ion, proxy2_handler_dummy, &cbarg); 434 1.1 christos assert_true(result == ISC_R_SUCCESS); 435 1.1 christos assert_true(cbarg.no_more_calls == 0); 436 1.1 christos verify_proxy_v2_header(NULL, &cbarg); 437 1.1 christos 438 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 439 1.1 christos region.base = (uint8_t *)proxy_v2_header_with_TLS; 440 1.1 christos region.length = sizeof(proxy_v2_header_with_TLS); 441 1.1 christos result = isc_proxy2_header_handle_directly( 442 1.1 christos ®ion, proxy2_handler_dummy, &cbarg); 443 1.1 christos assert_true(result == ISC_R_SUCCESS); 444 1.1 christos assert_true(cbarg.no_more_calls == 0); 445 1.1 christos isc_proxy2_tlv_iterate(&cbarg.tlv_data, dummy_tlv_iter_cb, &cbarg); 446 1.1 christos verify_proxy_v2_header_with_TLS(NULL, &cbarg); 447 1.1 christos 448 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 449 1.1 christos region.base = (uint8_t *)proxy_v2_header_with_TLS_CN; 450 1.1 christos region.length = sizeof(proxy_v2_header_with_TLS_CN); 451 1.1 christos result = isc_proxy2_header_handle_directly( 452 1.1 christos ®ion, proxy2_handler_dummy, &cbarg); 453 1.1 christos assert_true(result == ISC_R_SUCCESS); 454 1.1 christos assert_true(cbarg.no_more_calls == 0); 455 1.1 christos isc_proxy2_tlv_iterate(&cbarg.tlv_data, dummy_tlv_iter_cb, &cbarg); 456 1.1 christos verify_proxy_v2_header_with_TLS_CN(NULL, &cbarg); 457 1.1 christos 458 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 459 1.1 christos region.base = (uint8_t *)proxy_v2_header_with_AF_UNIX; 460 1.1 christos region.length = sizeof(proxy_v2_header_with_AF_UNIX); 461 1.1 christos result = isc_proxy2_header_handle_directly( 462 1.1 christos ®ion, proxy2_handler_dummy, &cbarg); 463 1.1 christos assert_true(result == ISC_R_SUCCESS); 464 1.1 christos assert_true(cbarg.no_more_calls == 0); 465 1.1 christos verify_proxy_v2_header_with_AF_UNIX(NULL, &cbarg); 466 1.1 christos } 467 1.1 christos 468 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_detect_bad_signature_test) { 469 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 470 1.1 christos 471 1.1 christos for (size_t i = 0; i < ISC_PROXY2_HEADER_SIGNATURE_SIZE; i++) { 472 1.1 christos isc_result_t result; 473 1.1 christos uint8_t sig[ISC_PROXY2_HEADER_SIGNATURE_SIZE]; 474 1.1 christos memmove(sig, ISC_PROXY2_HEADER_SIGNATURE, 475 1.1 christos ISC_PROXY2_HEADER_SIGNATURE_SIZE); 476 1.1 christos 477 1.1 christos sig[i] = 0x0C; /* it is not present in the valid signature */ 478 1.1 christos 479 1.1 christos /* 480 1.1 christos * We are expected to detect bad signature as early as possible, 481 1.1 christos * so we are passing only a part of the header. 482 1.1 christos */ 483 1.1 christos result = isc_proxy2_handler_push_data(handler, sig, i + 1); 484 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 485 1.1 christos } 486 1.1 christos } 487 1.1 christos 488 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_extra_data_test) { 489 1.1 christos isc_result_t result; 490 1.1 christos isc_buffer_t databuf; 491 1.1 christos isc_region_t region = { 0 }; 492 1.1 christos size_t sz; 493 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 494 1.1 christos uint8_t header[] = { 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 495 1.1 christos 0x55, 0x49, 0x54, 0x0a, 0x21, 0x11, 0x00, 0x1e, 496 1.1 christos 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, 0x00, 0x43, 497 1.1 christos 0x9b, 0x4a, 0x2e, 0x6b, 0x20, 0x00, 0x0f, 0x01, 498 1.1 christos 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x07, 0x54, 499 1.1 christos 0x4c, 0x53, 0x76, 0x31, 0x2e, 0x32 }; 500 1.1 christos uint8_t extra_data[] = { 0x10, 0x1a, 0x00, 0x04, 0x4d, 0x51, 0x54, 501 1.1 christos 0x54, 0x04, 0x02, 0x00, 0x3c, 0x00, 0x0e, 502 1.1 christos 0x4d, 0x51, 0x54, 0x54, 0x5f, 0x46, 0x58, 503 1.1 christos 0x5f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74 }; 504 1.1 christos uint8_t data[sizeof(header) + sizeof(extra_data)]; 505 1.1 christos 506 1.1 christos isc_buffer_init(&databuf, (void *)data, sizeof(data)); 507 1.1 christos 508 1.1 christos isc_buffer_putmem(&databuf, header, sizeof(header)); 509 1.1 christos isc_buffer_putmem(&databuf, extra_data, sizeof(extra_data)); 510 1.1 christos 511 1.1 christos isc_buffer_remainingregion(&databuf, ®ion); 512 1.1 christos 513 1.1 christos result = isc_proxy2_handler_push(handler, ®ion); 514 1.1 christos assert_true(result == ISC_R_SUCCESS); 515 1.1 christos 516 1.1 christos region = (isc_region_t){ 0 }; 517 1.1 christos sz = isc_proxy2_handler_header(handler, ®ion); 518 1.1 christos assert_true(sz == sizeof(header)); 519 1.1 christos assert_true(sz == region.length); 520 1.1 christos assert_true(memcmp(header, region.base, sz) == 0); 521 1.1 christos 522 1.1 christos region = (isc_region_t){ 0 }; 523 1.1 christos sz = isc_proxy2_handler_extra(handler, ®ion); 524 1.1 christos assert_true(sz == sizeof(extra_data)); 525 1.1 christos assert_true(sz == region.length); 526 1.1 christos assert_true(memcmp(extra_data, region.base, sz) == 0); 527 1.1 christos } 528 1.1 christos 529 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_max_size_test) { 530 1.1 christos isc_result_t result; 531 1.1 christos isc_proxy2_handler_t handler; 532 1.1 christos 533 1.1 christos UNUSED(state); 534 1.1 christos 535 1.1 christos isc_proxy2_handler_init(&handler, mctx, sizeof(proxy_v2_header), 536 1.1 christos proxy2_handler_dummy, NULL); 537 1.1 christos 538 1.1 christos result = isc_proxy2_handler_push_data(&handler, proxy_v2_header, 539 1.1 christos sizeof(proxy_v2_header)); 540 1.1 christos 541 1.1 christos assert_true(result == ISC_R_SUCCESS); 542 1.1 christos 543 1.1 christos isc_proxy2_handler_uninit(&handler); 544 1.1 christos 545 1.1 christos isc_proxy2_handler_init(&handler, mctx, sizeof(proxy_v2_header) - 1, 546 1.1 christos proxy2_handler_dummy, NULL); 547 1.1 christos 548 1.1 christos result = isc_proxy2_handler_push_data(&handler, proxy_v2_header, 549 1.1 christos sizeof(proxy_v2_header)); 550 1.1 christos 551 1.1 christos assert_true(result == ISC_R_RANGE); 552 1.1 christos 553 1.1 christos isc_proxy2_handler_uninit(&handler); 554 1.1 christos } 555 1.1 christos 556 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_make_header_test) { 557 1.1 christos isc_result_t result; 558 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 559 1.1 christos isc_buffer_t databuf; 560 1.1 christos uint8_t data[ISC_PROXY2_MAX_SIZE]; 561 1.1 christos isc_buffer_t sslbuf; 562 1.1 christos uint8_t ssldata[ISC_PROXY2_MAX_SIZE]; 563 1.1 christos isc_region_t region = { 0 }; 564 1.1 christos uint8_t extra[256] = { 0 }; 565 1.1 christos const char *tls_version = "TLSv1.3"; 566 1.1 christos const char *tls_cn = "name.test"; 567 1.1 christos dummy_handler_cbarg_t cbarg = { 0 }; 568 1.1 christos struct in_addr localhost4 = { 0 }; 569 1.1 christos isc_sockaddr_t src_addrv4 = { 0 }, dst_addrv4 = { 0 }, 570 1.1 christos src_addrv6 = { 0 }, dst_addrv6 = { 0 }; 571 1.1 christos const uint16_t src_port = 1236; 572 1.1 christos const uint16_t dst_port = 9582; 573 1.1 christos 574 1.1 christos localhost4.s_addr = htonl(INADDR_LOOPBACK); 575 1.1 christos 576 1.1 christos isc_sockaddr_fromin(&src_addrv4, &localhost4, src_port); 577 1.1 christos isc_sockaddr_fromin(&dst_addrv4, &localhost4, dst_port); 578 1.1 christos isc_sockaddr_fromin6(&src_addrv6, &in6addr_loopback, src_port); 579 1.1 christos isc_sockaddr_fromin6(&dst_addrv6, &in6addr_loopback, dst_port); 580 1.1 christos isc_proxy2_handler_setcb(handler, proxy2_handler_dummy, &cbarg); 581 1.1 christos 582 1.1 christos isc_buffer_init(&databuf, (void *)data, sizeof(data)); 583 1.1 christos isc_buffer_init(&sslbuf, (void *)ssldata, sizeof(ssldata)); 584 1.1 christos 585 1.1 christos /* unspec */ 586 1.1 christos result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_LOCAL, 0, NULL, 587 1.1 christos NULL, NULL); 588 1.1 christos assert_true(result == ISC_R_SUCCESS); 589 1.1 christos 590 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 591 1.1 christos assert_true(region.length == ISC_PROXY2_HEADER_SIZE); 592 1.1 christos 593 1.1 christos region = (isc_region_t){ .base = extra, .length = sizeof(extra) }; 594 1.1 christos result = isc_proxy2_header_append_tlv( 595 1.1 christos &databuf, ISC_PROXY2_TLV_TYPE_NOOP, ®ion); 596 1.1 christos assert_true(result == ISC_R_SUCCESS); 597 1.1 christos 598 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 599 1.1 christos assert_true(region.length == ISC_PROXY2_HEADER_SIZE + sizeof(extra) + 600 1.1 christos ISC_PROXY2_TLV_HEADER_SIZE); 601 1.1 christos 602 1.1 christos result = isc_proxy2_handler_push(handler, ®ion); 603 1.1 christos assert_true(result == ISC_R_SUCCESS); 604 1.1 christos assert_true(cbarg.tlvs == 0); /* in unspec mode we ignore TLVs */ 605 1.1 christos 606 1.1 christos /* AF_INET, SOCK_STREAM */ 607 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 608 1.1 christos isc_buffer_clear(&databuf); 609 1.1 christos 610 1.1 christos result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_PROXY, 611 1.1 christos SOCK_STREAM, &src_addrv4, &dst_addrv4, 612 1.1 christos NULL); 613 1.1 christos assert_true(result == ISC_R_SUCCESS); 614 1.1 christos 615 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 616 1.1 christos assert_true(region.length == ISC_PROXY2_MIN_AF_INET_SIZE); 617 1.1 christos 618 1.1 christos region = (isc_region_t){ .base = extra, .length = sizeof(extra) }; 619 1.1 christos result = isc_proxy2_header_append_tlv( 620 1.1 christos &databuf, ISC_PROXY2_TLV_TYPE_NOOP, ®ion); 621 1.1 christos assert_true(result == ISC_R_SUCCESS); 622 1.1 christos 623 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 624 1.1 christos assert_true(region.length == ISC_PROXY2_MIN_AF_INET_SIZE + 625 1.1 christos sizeof(extra) + 626 1.1 christos ISC_PROXY2_TLV_HEADER_SIZE); 627 1.1 christos 628 1.1 christos result = isc_proxy2_handler_push(handler, ®ion); 629 1.1 christos assert_true(result == ISC_R_SUCCESS); 630 1.1 christos assert_true(cbarg.tlvs == 1); /* ISC_PROXY2_TLV_TYPE_NOOP */ 631 1.1 christos 632 1.1 christos assert_true(cbarg.socktype == SOCK_STREAM); 633 1.1 christos assert_true(isc_sockaddr_pf(&cbarg.src_addr) == AF_INET); 634 1.1 christos assert_true(isc_sockaddr_pf(&cbarg.dst_addr) == AF_INET); 635 1.1 christos 636 1.1 christos assert_true(isc_sockaddr_equal(&cbarg.src_addr, &src_addrv4)); 637 1.1 christos assert_true(isc_sockaddr_equal(&cbarg.dst_addr, &dst_addrv4)); 638 1.1 christos 639 1.1 christos /* AF_INET6, SOCK_STREAM (+ TLS version and CN) */ 640 1.1 christos cbarg = (dummy_handler_cbarg_t){ 0 }; 641 1.1 christos isc_buffer_clear(&databuf); 642 1.1 christos 643 1.1 christos result = isc_proxy2_make_header(&databuf, ISC_PROXY2_CMD_PROXY, 644 1.1 christos SOCK_STREAM, &src_addrv6, &dst_addrv6, 645 1.1 christos NULL); 646 1.1 christos assert_true(result == ISC_R_SUCCESS); 647 1.1 christos 648 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 649 1.1 christos assert_true(region.length == ISC_PROXY2_MIN_AF_INET6_SIZE); 650 1.1 christos 651 1.1 christos region = (isc_region_t){ .base = extra, .length = sizeof(extra) }; 652 1.1 christos result = isc_proxy2_header_append_tlv( 653 1.1 christos &databuf, ISC_PROXY2_TLV_TYPE_NOOP, ®ion); 654 1.1 christos assert_true(result == ISC_R_SUCCESS); 655 1.1 christos 656 1.1 christos result = isc_proxy2_make_tls_subheader( 657 1.1 christos &sslbuf, ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_CONN, 658 1.1 christos true, NULL); 659 1.1 christos assert_true(result == ISC_R_SUCCESS); 660 1.1 christos result = isc_proxy2_append_tlv_string( 661 1.1 christos &sslbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version); 662 1.1 christos assert_true(result == ISC_R_SUCCESS); 663 1.1 christos result = isc_proxy2_append_tlv_string( 664 1.1 christos &sslbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn); 665 1.1 christos assert_true(result == ISC_R_SUCCESS); 666 1.1 christos 667 1.1 christos isc_buffer_usedregion(&sslbuf, ®ion); 668 1.1 christos result = isc_proxy2_header_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 669 1.1 christos ®ion); 670 1.1 christos assert_true(result == ISC_R_SUCCESS); 671 1.1 christos 672 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 673 1.1 christos size_t expected = ISC_PROXY2_MIN_AF_INET6_SIZE + sizeof(extra) + 674 1.1 christos (4 * ISC_PROXY2_TLV_HEADER_SIZE) + 675 1.1 christos ISC_PROXY2_TLS_SUBHEADER_MIN_SIZE + 676 1.1 christos strlen(tls_version) + strlen(tls_cn); 677 1.1 christos assert_true(region.length == expected); 678 1.1 christos 679 1.1 christos result = isc_proxy2_handler_push(handler, ®ion); 680 1.1 christos assert_true(result == ISC_R_SUCCESS); 681 1.1 christos 682 1.1 christos assert_true(cbarg.socktype == SOCK_STREAM); 683 1.1 christos assert_true(isc_sockaddr_pf(&cbarg.src_addr) == AF_INET6); 684 1.1 christos assert_true(isc_sockaddr_pf(&cbarg.dst_addr) == AF_INET6); 685 1.1 christos 686 1.1 christos assert_true(isc_sockaddr_equal(&cbarg.src_addr, &src_addrv6)); 687 1.1 christos assert_true(isc_sockaddr_equal(&cbarg.dst_addr, &dst_addrv6)); 688 1.1 christos 689 1.1 christos region = (isc_region_t){ 0 }; 690 1.1 christos (void)isc_proxy2_handler_tlvs(handler, ®ion); 691 1.1 christos assert_true(isc_proxy2_tlv_data_verify(®ion) == ISC_R_SUCCESS); 692 1.1 christos /* ISC_PROXY2_TLV_TYPE_NOOP+ISC_PROXY2_TLV_TYPE_TLS */ 693 1.1 christos assert_true(cbarg.tlvs == 2); 694 1.1 christos /* ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION+ISC_PROXY2_TLV_SUBTYPE_TLS_CN */ 695 1.1 christos assert_true(cbarg.tls_subtlvs == 2); 696 1.1 christos 697 1.1 christos assert_true(cbarg.tls_version.length == strlen(tls_version)); 698 1.1 christos assert_true(memcmp(cbarg.tls_version.base, tls_version, 699 1.1 christos strlen(tls_version)) == 0); 700 1.1 christos 701 1.1 christos assert_true(cbarg.tls_common_name.length == strlen(tls_cn)); 702 1.1 christos assert_true(memcmp(cbarg.tls_common_name.base, tls_cn, 703 1.1 christos strlen(tls_cn)) == 0); 704 1.1 christos } 705 1.1 christos 706 1.1 christos static bool 707 1.1 christos rebuild_subtlv_iter_cb(const uint8_t client, const bool client_cert_verified, 708 1.1 christos const isc_proxy2_tlv_subtype_tls_t tls_subtlv_type, 709 1.1 christos const isc_region_t *restrict data, void *cbarg) { 710 1.1 christos isc_result_t result; 711 1.1 christos isc_buffer_t *outbuf = (isc_buffer_t *)cbarg; 712 1.1 christos 713 1.1 christos UNUSED(client); 714 1.1 christos UNUSED(client_cert_verified); 715 1.1 christos 716 1.1 christos result = isc_proxy2_append_tlv(outbuf, tls_subtlv_type, data); 717 1.1 christos assert_true(result == ISC_R_SUCCESS); 718 1.1 christos 719 1.1 christos return true; 720 1.1 christos } 721 1.1 christos 722 1.1 christos static bool 723 1.1 christos rebuild_tlv_iter_cb(const isc_proxy2_tlv_type_t tlv_type, 724 1.1 christos const isc_region_t *restrict data, void *cbarg) { 725 1.1 christos isc_result_t result; 726 1.1 christos isc_buffer_t *outbuf = (isc_buffer_t *)cbarg; 727 1.1 christos 728 1.1 christos if (tlv_type == ISC_PROXY2_TLV_TYPE_TLS) { 729 1.1 christos uint8_t client_flags = 0; 730 1.1 christos bool client_cert_verified = false; 731 1.1 christos isc_buffer_t databuf = { 0 }; 732 1.1 christos isc_region_t region = { 0 }; 733 1.1 christos uint8_t storage[ISC_PROXY2_MAX_SIZE]; 734 1.1 christos 735 1.1 christos isc_buffer_init(&databuf, (void *)storage, sizeof(storage)); 736 1.1 christos 737 1.1 christos /* get flags values */ 738 1.1 christos result = isc_proxy2_subtlv_tls_header_data( 739 1.1 christos data, &client_flags, &client_cert_verified); 740 1.1 christos assert_true(result == ISC_R_SUCCESS); 741 1.1 christos 742 1.1 christos /* create header */ 743 1.1 christos result = isc_proxy2_make_tls_subheader( 744 1.1 christos &databuf, client_flags, client_cert_verified, NULL); 745 1.1 christos assert_true(result == ISC_R_SUCCESS); 746 1.1 christos 747 1.1 christos /* process and append values */ 748 1.1 christos result = isc_proxy2_subtlv_tls_iterate( 749 1.1 christos data, rebuild_subtlv_iter_cb, &databuf); 750 1.1 christos assert_true(result == ISC_R_SUCCESS); 751 1.1 christos 752 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 753 1.1 christos result = isc_proxy2_header_append_tlv(outbuf, tlv_type, 754 1.1 christos ®ion); 755 1.1 christos assert_true(result == ISC_R_SUCCESS); 756 1.1 christos } else { 757 1.1 christos result = isc_proxy2_header_append_tlv(outbuf, tlv_type, data); 758 1.1 christos assert_true(result == ISC_R_SUCCESS); 759 1.1 christos } 760 1.1 christos 761 1.1 christos return true; 762 1.1 christos } 763 1.1 christos 764 1.1 christos static void 765 1.1 christos proxy2_handler_rebuild_cb(const isc_result_t header_result, 766 1.1 christos const isc_proxy2_command_t cmd, const int socktype, 767 1.1 christos const isc_sockaddr_t *restrict src_addr, 768 1.1 christos const isc_sockaddr_t *restrict dst_addr, 769 1.1 christos const isc_region_t *restrict tlv_blob, 770 1.1 christos const isc_region_t *restrict extra, void *cbarg) { 771 1.1 christos isc_result_t result; 772 1.1 christos isc_buffer_t *outbuf = (isc_buffer_t *)cbarg; 773 1.1 christos 774 1.1 christos if (header_result != ISC_R_SUCCESS) { 775 1.1 christos return; 776 1.1 christos } 777 1.1 christos 778 1.1 christos result = isc_proxy2_make_header(outbuf, cmd, socktype, src_addr, 779 1.1 christos dst_addr, NULL); 780 1.1 christos assert_true(result == ISC_R_SUCCESS); 781 1.1 christos 782 1.1 christos if (tlv_blob != NULL) { 783 1.1 christos isc_proxy2_tlv_iterate(tlv_blob, rebuild_tlv_iter_cb, outbuf); 784 1.1 christos } 785 1.1 christos 786 1.1 christos if (extra != NULL) { 787 1.1 christos result = isc_proxy2_tlv_data_verify(tlv_blob); 788 1.1 christos assert_true(result == ISC_R_SUCCESS); 789 1.1 christos isc_buffer_putmem(outbuf, extra->base, extra->length); 790 1.1 christos } 791 1.1 christos } 792 1.1 christos 793 1.1 christos static void 794 1.1 christos proxy2_handler_rebuild(isc_buffer_t *restrict outbuf, const void *data, 795 1.1 christos const size_t size) { 796 1.1 christos isc_proxy2_handler_t handler = { 0 }; 797 1.1 christos 798 1.1 christos isc_proxy2_handler_init(&handler, mctx, 0, proxy2_handler_rebuild_cb, 799 1.1 christos outbuf); 800 1.1 christos 801 1.1 christos isc_proxy2_handler_push_data(&handler, data, size); 802 1.1 christos 803 1.1 christos isc_proxy2_handler_uninit(&handler); 804 1.1 christos } 805 1.1 christos 806 1.1 christos static void 807 1.1 christos try_rebuild_header(const void *data, size_t size) { 808 1.1 christos isc_buffer_t databuf = { 0 }; 809 1.1 christos isc_region_t region = { 0 }; 810 1.1 christos uint8_t storage[ISC_PROXY2_MAX_SIZE]; 811 1.1 christos 812 1.1 christos isc_buffer_init(&databuf, (void *)storage, sizeof(storage)); 813 1.1 christos 814 1.1 christos proxy2_handler_rebuild(&databuf, data, size); 815 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 816 1.1 christos assert_true(region.length == size); 817 1.1 christos assert_true(memcmp(region.base, data, size) == 0); 818 1.1 christos } 819 1.1 christos 820 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_rebuild_header_test) { 821 1.1 christos try_rebuild_header(proxy_v2_header, sizeof(proxy_v2_header)); 822 1.1 christos try_rebuild_header(proxy_v2_header_with_TLS, 823 1.1 christos sizeof(proxy_v2_header_with_TLS)); 824 1.1 christos try_rebuild_header(proxy_v2_header_with_TLS_CN, 825 1.1 christos sizeof(proxy_v2_header_with_TLS_CN)); 826 1.1 christos } 827 1.1 christos 828 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_bad_header_signature_test) { 829 1.1 christos size_t i; 830 1.1 christos isc_result_t result; 831 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 832 1.1 christos 833 1.1 christos for (i = 0; i < ISC_PROXY2_HEADER_SIGNATURE_SIZE; i++) { 834 1.1 christos uint8_t sig[ISC_PROXY2_HEADER_SIGNATURE_SIZE]; 835 1.1 christos memmove(sig, ISC_PROXY2_HEADER_SIGNATURE, 836 1.1 christos ISC_PROXY2_HEADER_SIGNATURE_SIZE); 837 1.1 christos sig[i] = 0x0C; /* 0x0C cannot be found in the signature */ 838 1.1 christos result = isc_proxy2_handler_push_data(handler, sig, 839 1.1 christos sizeof(sig)); 840 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 841 1.1 christos isc_proxy2_handler_clear(handler); 842 1.1 christos } 843 1.1 christos 844 1.1 christos result = isc_proxy2_handler_push_data(handler, 845 1.1 christos ISC_PROXY2_HEADER_SIGNATURE, 846 1.1 christos ISC_PROXY2_HEADER_SIGNATURE_SIZE); 847 1.1 christos assert_true(result == ISC_R_NOMORE); 848 1.1 christos } 849 1.1 christos 850 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_bad_proto_version_command_test) { 851 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 852 1.1 christos isc_result_t result; 853 1.1 christos uint8_t *pver_cmd = NULL; 854 1.1 christos uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 }; 855 1.1 christos 856 1.1 christos memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header)); 857 1.1 christos 858 1.1 christos pver_cmd = &botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE]; 859 1.1 christos 860 1.1 christos assert_true(*pver_cmd == 0x21); 861 1.1 christos 862 1.1 christos *pver_cmd = 0x31; /* unexpected version (3) followed by PROXY command */ 863 1.1 christos 864 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 865 1.1 christos sizeof(botched_header)); 866 1.1 christos assert_true(result == ISC_R_NOTIMPLEMENTED); 867 1.1 christos 868 1.1 christos *pver_cmd = 0x22; /* version two followed by unexpected command (2) */ 869 1.1 christos 870 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 871 1.1 christos sizeof(botched_header)); 872 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 873 1.1 christos } 874 1.1 christos 875 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_bad_family_socktype_test) { 876 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 877 1.1 christos isc_result_t result; 878 1.1 christos uint8_t *pfam = NULL; 879 1.1 christos uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 }; 880 1.1 christos 881 1.1 christos memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header)); 882 1.1 christos 883 1.1 christos pfam = &botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE + 1]; 884 1.1 christos 885 1.1 christos assert_true(*pfam == 0x11); 886 1.1 christos 887 1.1 christos *pfam = 0x41; /* unexpected family (4) followed by SOCK_STREAM (1)*/ 888 1.1 christos 889 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 890 1.1 christos sizeof(botched_header)); 891 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 892 1.1 christos 893 1.1 christos *pfam = 0x13; /* AF_INET (1) followed by unexpected sock type (3) */ 894 1.1 christos 895 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 896 1.1 christos sizeof(botched_header)); 897 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 898 1.1 christos } 899 1.1 christos 900 1.1 christos static inline void 901 1.1 christos update_header_length(uint8_t *botched_header, uint16_t newlen) { 902 1.1 christos newlen = htons(newlen); 903 1.1 christos memmove(&botched_header[ISC_PROXY2_HEADER_SIGNATURE_SIZE + 2], &newlen, 904 1.1 christos sizeof(newlen)); 905 1.1 christos } 906 1.1 christos 907 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_bad_unexpected_not_enough_length_test) { 908 1.1 christos isc_proxy2_handler_t *handler = (isc_proxy2_handler_t *)*state; 909 1.1 christos isc_result_t result; 910 1.1 christos uint8_t botched_header[sizeof(proxy_v2_header)] = { 0 }; 911 1.1 christos 912 1.1 christos memmove(botched_header, proxy_v2_header, sizeof(proxy_v2_header)); 913 1.1 christos 914 1.1 christos update_header_length(botched_header, 0); 915 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 916 1.1 christos sizeof(botched_header)); 917 1.1 christos assert_true(result == ISC_R_RANGE); 918 1.1 christos 919 1.1 christos update_header_length(botched_header, 4); /* not enough */ 920 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 921 1.1 christos sizeof(botched_header)); 922 1.1 christos assert_true(result == ISC_R_RANGE); 923 1.1 christos 924 1.1 christos update_header_length(botched_header, UINT16_MAX); /* no more */ 925 1.1 christos result = isc_proxy2_handler_push_data(handler, botched_header, 926 1.1 christos sizeof(botched_header)); 927 1.1 christos assert_true(result == ISC_R_NOMORE); 928 1.1 christos isc_proxy2_handler_clear(handler); 929 1.1 christos } 930 1.1 christos 931 1.1 christos ISC_RUN_TEST_IMPL(proxyheader_tlv_data_test) { 932 1.1 christos isc_result_t result; 933 1.1 christos isc_buffer_t databuf = { 0 }; 934 1.1 christos isc_buffer_t tlsbuf = { 0 }; 935 1.1 christos uint8_t data[ISC_PROXY2_MAX_SIZE] = { 0 }; 936 1.1 christos uint8_t tlsdata[ISC_PROXY2_MAX_SIZE] = { 0 }; 937 1.1 christos uint8_t zerodata[0xff] = { 0 }; 938 1.1 christos isc_region_t region = { 0 }; 939 1.1 christos const char *alpn = "dot"; 940 1.1 christos const char *tls_version = "TLSv1.3"; 941 1.1 christos const char *tls_cn = "name.test"; 942 1.1 christos 943 1.1 christos isc_buffer_init(&databuf, (void *)data, sizeof(data)); 944 1.1 christos isc_buffer_init(&tlsbuf, (void *)tlsdata, sizeof(tlsdata)); 945 1.1 christos 946 1.1 christos /* zero filled data is not fine */ 947 1.1 christos region.base = zerodata; 948 1.1 christos region.length = sizeof(zerodata); 949 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 950 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 951 1.1 christos 952 1.1 christos /* crc32c must be 4 bytes long */ 953 1.1 christos isc_buffer_clear(&databuf); 954 1.1 christos region.base = (uint8_t *)zerodata; 955 1.1 christos region.length = sizeof(zerodata); 956 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_CRC32C, 957 1.1 christos ®ion); 958 1.1 christos assert_true(result == ISC_R_SUCCESS); 959 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 960 1.1 christos 961 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 962 1.1 christos assert_true(result == ISC_R_RANGE); 963 1.1 christos 964 1.1 christos isc_buffer_clear(&databuf); 965 1.1 christos region.base = (uint8_t *)zerodata; 966 1.1 christos region.length = 4; 967 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_CRC32C, 968 1.1 christos ®ion); 969 1.1 christos assert_true(result == ISC_R_SUCCESS); 970 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 971 1.1 christos 972 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 973 1.1 christos assert_true(result == ISC_R_SUCCESS); 974 1.1 christos 975 1.1 christos /* unique id must be <= 128 bytes long */ 976 1.1 christos isc_buffer_clear(&databuf); 977 1.1 christos region.base = (uint8_t *)zerodata; 978 1.1 christos region.length = sizeof(zerodata); 979 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_UNIQUE_ID, 980 1.1 christos ®ion); 981 1.1 christos assert_true(result == ISC_R_SUCCESS); 982 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 983 1.1 christos 984 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 985 1.1 christos assert_true(result == ISC_R_RANGE); 986 1.1 christos 987 1.1 christos isc_buffer_clear(&databuf); 988 1.1 christos region.base = (uint8_t *)zerodata; 989 1.1 christos region.length = 128; 990 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_UNIQUE_ID, 991 1.1 christos ®ion); 992 1.1 christos assert_true(result == ISC_R_SUCCESS); 993 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 994 1.1 christos 995 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 996 1.1 christos assert_true(result == ISC_R_SUCCESS); 997 1.1 christos 998 1.1 christos /* two noops is fine */ 999 1.1 christos isc_buffer_clear(&databuf); 1000 1.1 christos region = (isc_region_t){ 0 }; 1001 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP, 1002 1.1 christos ®ion); 1003 1.1 christos assert_true(result == ISC_R_SUCCESS); 1004 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP, 1005 1.1 christos ®ion); 1006 1.1 christos assert_true(result == ISC_R_SUCCESS); 1007 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1008 1.1 christos 1009 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1010 1.1 christos assert_true(result == ISC_R_SUCCESS); 1011 1.1 christos 1012 1.1 christos /* one ALPN tag is fine */ 1013 1.1 christos isc_buffer_clear(&databuf); 1014 1.1 christos result = isc_proxy2_append_tlv_string(&databuf, 1015 1.1 christos ISC_PROXY2_TLV_TYPE_ALPN, alpn); 1016 1.1 christos assert_true(result == ISC_R_SUCCESS); 1017 1.1 christos 1018 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1019 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1020 1.1 christos assert_true(result == ISC_R_SUCCESS); 1021 1.1 christos 1022 1.1 christos /* two ALPN tags is not fine */ 1023 1.1 christos result = isc_proxy2_append_tlv_string(&databuf, 1024 1.1 christos ISC_PROXY2_TLV_TYPE_ALPN, alpn); 1025 1.1 christos assert_true(result == ISC_R_SUCCESS); 1026 1.1 christos 1027 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1028 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1029 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1030 1.1 christos 1031 1.1 christos /* empty TLS subheader is tolerable */ 1032 1.1 christos isc_buffer_clear(&databuf); 1033 1.1 christos isc_buffer_clear(&tlsbuf); 1034 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, 0, false, NULL); 1035 1.1 christos assert_true(result == ISC_R_SUCCESS); 1036 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1037 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1038 1.1 christos ®ion); 1039 1.1 christos assert_true(result == ISC_R_SUCCESS); 1040 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1041 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1042 1.1 christos assert_true(result == ISC_R_SUCCESS); 1043 1.1 christos 1044 1.1 christos /* empty TLS subheader with no TLS version while one is expected */ 1045 1.1 christos isc_buffer_clear(&databuf); 1046 1.1 christos isc_buffer_clear(&tlsbuf); 1047 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS, 1048 1.1 christos false, NULL); 1049 1.1 christos assert_true(result == ISC_R_SUCCESS); 1050 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1051 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1052 1.1 christos ®ion); 1053 1.1 christos assert_true(result == ISC_R_SUCCESS); 1054 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1055 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1056 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1057 1.1 christos 1058 1.1 christos /* TLS subheader with TLS version */ 1059 1.1 christos isc_buffer_clear(&databuf); 1060 1.1 christos isc_buffer_clear(&tlsbuf); 1061 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS, 1062 1.1 christos false, NULL); 1063 1.1 christos assert_true(result == ISC_R_SUCCESS); 1064 1.1 christos region.length = sizeof(tls_version); 1065 1.1 christos result = isc_proxy2_append_tlv_string( 1066 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version); 1067 1.1 christos assert_true(result == ISC_R_SUCCESS); 1068 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1069 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1070 1.1 christos ®ion); 1071 1.1 christos assert_true(result == ISC_R_SUCCESS); 1072 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1073 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1074 1.1 christos assert_true(result == ISC_R_SUCCESS); 1075 1.1 christos 1076 1.1 christos /* TLS subheader with multiple TLS versions is not fine */ 1077 1.1 christos isc_buffer_clear(&databuf); 1078 1.1 christos isc_buffer_clear(&tlsbuf); 1079 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS, 1080 1.1 christos false, NULL); 1081 1.1 christos assert_true(result == ISC_R_SUCCESS); 1082 1.1 christos result = isc_proxy2_append_tlv_string( 1083 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version); 1084 1.1 christos assert_true(result == ISC_R_SUCCESS); 1085 1.1 christos result = isc_proxy2_append_tlv( 1086 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, ®ion); 1087 1.1 christos assert_true(result == ISC_R_SUCCESS); 1088 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1089 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1090 1.1 christos ®ion); 1091 1.1 christos assert_true(result == ISC_R_SUCCESS); 1092 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1093 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1094 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1095 1.1 christos 1096 1.1 christos /* TLS subheader with unexpected TLS version */ 1097 1.1 christos isc_buffer_clear(&databuf); 1098 1.1 christos isc_buffer_clear(&tlsbuf); 1099 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, 0, false, NULL); 1100 1.1 christos assert_true(result == ISC_R_SUCCESS); 1101 1.1 christos result = isc_proxy2_append_tlv_string( 1102 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version); 1103 1.1 christos assert_true(result == ISC_R_SUCCESS); 1104 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1105 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1106 1.1 christos ®ion); 1107 1.1 christos assert_true(result == ISC_R_SUCCESS); 1108 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1109 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1110 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1111 1.1 christos 1112 1.1 christos /* TLS subheader with no CN while expected */ 1113 1.1 christos isc_buffer_clear(&databuf); 1114 1.1 christos isc_buffer_clear(&tlsbuf); 1115 1.1 christos result = isc_proxy2_make_tls_subheader( 1116 1.1 christos &tlsbuf, ISC_PROXY2_CLIENT_TLS | ISC_PROXY2_CLIENT_CERT_CONN, 1117 1.1 christos false, NULL); 1118 1.1 christos assert_true(result == ISC_R_SUCCESS); 1119 1.1 christos result = isc_proxy2_append_tlv_string( 1120 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_VERSION, tls_version); 1121 1.1 christos assert_true(result == ISC_R_SUCCESS); 1122 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1123 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1124 1.1 christos ®ion); 1125 1.1 christos assert_true(result == ISC_R_SUCCESS); 1126 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1127 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1128 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1129 1.1 christos 1130 1.1 christos /* TLS subheader with unexpected CN */ 1131 1.1 christos isc_buffer_clear(&databuf); 1132 1.1 christos isc_buffer_clear(&tlsbuf); 1133 1.1 christos result = isc_proxy2_make_tls_subheader(&tlsbuf, ISC_PROXY2_CLIENT_TLS, 1134 1.1 christos false, NULL); 1135 1.1 christos assert_true(result == ISC_R_SUCCESS); 1136 1.1 christos result = isc_proxy2_append_tlv_string( 1137 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn); 1138 1.1 christos assert_true(result == ISC_R_SUCCESS); 1139 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1140 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1141 1.1 christos ®ion); 1142 1.1 christos assert_true(result == ISC_R_SUCCESS); 1143 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1144 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1145 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1146 1.1 christos 1147 1.1 christos /* TLS subheader with CN unexpected (because TLS flag is not set) */ 1148 1.1 christos isc_buffer_clear(&databuf); 1149 1.1 christos isc_buffer_clear(&tlsbuf); 1150 1.1 christos result = isc_proxy2_make_tls_subheader( 1151 1.1 christos &tlsbuf, 1152 1.1 christos ISC_PROXY2_CLIENT_CERT_CONN | ISC_PROXY2_CLIENT_CERT_SESS, 1153 1.1 christos false, NULL); 1154 1.1 christos assert_true(result == ISC_R_SUCCESS); 1155 1.1 christos result = isc_proxy2_append_tlv_string( 1156 1.1 christos &tlsbuf, ISC_PROXY2_TLV_SUBTYPE_TLS_CN, tls_cn); 1157 1.1 christos assert_true(result == ISC_R_SUCCESS); 1158 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1159 1.1 christos assert_true(result == ISC_R_SUCCESS); 1160 1.1 christos isc_buffer_usedregion(&tlsbuf, ®ion); 1161 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS, 1162 1.1 christos ®ion); 1163 1.1 christos assert_true(result == ISC_R_SUCCESS); 1164 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1165 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1166 1.1 christos assert_true(result == ISC_R_UNEXPECTED); 1167 1.1 christos 1168 1.1 christos /* botched TLV header */ 1169 1.1 christos isc_buffer_clear(&databuf); 1170 1.1 christos region.base = (uint8_t *)zerodata; 1171 1.1 christos region.length = sizeof(zerodata); 1172 1.1 christos result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_NOOP, 1173 1.1 christos ®ion); 1174 1.1 christos isc_buffer_subtract(&databuf, region.length / 2); 1175 1.1 christos isc_buffer_usedregion(&databuf, ®ion); 1176 1.1 christos result = isc_proxy2_tlv_data_verify(®ion); 1177 1.1 christos assert_true(result == ISC_R_RANGE); 1178 1.1 christos } 1179 1.1 christos 1180 1.1 christos ISC_TEST_LIST_START 1181 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_test, setup_test_proxy, 1182 1.1 christos teardown_test_proxy) 1183 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_byte_by_byte_test, setup_test_proxy, 1184 1.1 christos teardown_test_proxy) 1185 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_generic_torn_apart_randomly_test, 1186 1.1 christos setup_test_proxy, teardown_test_proxy) 1187 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_direct_test, setup_test_proxy, 1188 1.1 christos teardown_test_proxy) 1189 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_detect_bad_signature_test, setup_test_proxy, 1190 1.1 christos teardown_test_proxy) 1191 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_extra_data_test, setup_test_proxy, 1192 1.1 christos teardown_test_proxy) 1193 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_max_size_test, setup_test_proxy, 1194 1.1 christos teardown_test_proxy) 1195 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_make_header_test, setup_test_proxy, 1196 1.1 christos teardown_test_proxy) 1197 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_rebuild_header_test, setup_test_proxy, 1198 1.1 christos teardown_test_proxy) 1199 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_header_signature_test, setup_test_proxy, 1200 1.1 christos teardown_test_proxy) 1201 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_proto_version_command_test, 1202 1.1 christos setup_test_proxy, teardown_test_proxy) 1203 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_family_socktype_test, setup_test_proxy, 1204 1.1 christos teardown_test_proxy) 1205 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_bad_unexpected_not_enough_length_test, 1206 1.1 christos setup_test_proxy, teardown_test_proxy) 1207 1.1 christos ISC_TEST_ENTRY_CUSTOM(proxyheader_tlv_data_test, setup_test_proxy, 1208 1.1 christos teardown_test_proxy) 1209 1.1 christos ISC_TEST_LIST_END 1210 1.1 christos 1211 1.1 christos ISC_TEST_MAIN 1212