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