Home | History | Annotate | Line # | Download | only in isc
      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, &region);
    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 		&region, 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 		&region, 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 		&region, 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 		&region, 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, &region);
    512  1.1  christos 
    513  1.1  christos 	result = isc_proxy2_handler_push(handler, &region);
    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, &region);
    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, &region);
    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, &region);
    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, &region);
    596  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    597  1.1  christos 
    598  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    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, &region);
    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, &region);
    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, &region);
    621  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    622  1.1  christos 
    623  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    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, &region);
    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, &region);
    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, &region);
    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, &region);
    668  1.1  christos 	result = isc_proxy2_header_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
    669  1.1  christos 					      &region);
    670  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    671  1.1  christos 
    672  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    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, &region);
    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, &region);
    691  1.1  christos 	assert_true(isc_proxy2_tlv_data_verify(&region) == 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, &region);
    753  1.1  christos 		result = isc_proxy2_header_append_tlv(outbuf, tlv_type,
    754  1.1  christos 						      &region);
    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, &region);
    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(&region);
    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 				       &region);
    958  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    959  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    960  1.1  christos 
    961  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
    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 				       &region);
    969  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    970  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    971  1.1  christos 
    972  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
    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 				       &region);
    981  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    982  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    983  1.1  christos 
    984  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
    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 				       &region);
    992  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
    993  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
    994  1.1  christos 
    995  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
    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 				       &region);
   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 				       &region);
   1006  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1007  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1008  1.1  christos 
   1009  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1019  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1028  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1037  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1038  1.1  christos 				       &region);
   1039  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1040  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1041  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1051  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1052  1.1  christos 				       &region);
   1053  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1054  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1055  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1069  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1070  1.1  christos 				       &region);
   1071  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1072  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1073  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1087  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1088  1.1  christos 	isc_buffer_usedregion(&tlsbuf, &region);
   1089  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1090  1.1  christos 				       &region);
   1091  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1092  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1093  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1105  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1106  1.1  christos 				       &region);
   1107  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1108  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1109  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1123  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1124  1.1  christos 				       &region);
   1125  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1126  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1127  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1140  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1141  1.1  christos 				       &region);
   1142  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1143  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1144  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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, &region);
   1159  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1160  1.1  christos 	isc_buffer_usedregion(&tlsbuf, &region);
   1161  1.1  christos 	result = isc_proxy2_append_tlv(&databuf, ISC_PROXY2_TLV_TYPE_TLS,
   1162  1.1  christos 				       &region);
   1163  1.1  christos 	assert_true(result == ISC_R_SUCCESS);
   1164  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1165  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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 				       &region);
   1174  1.1  christos 	isc_buffer_subtract(&databuf, region.length / 2);
   1175  1.1  christos 	isc_buffer_usedregion(&databuf, &region);
   1176  1.1  christos 	result = isc_proxy2_tlv_data_verify(&region);
   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