1 /*
2 * QTest testcases for TLS migration
3 *
4 * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
5 * based on the vhost-user-test.c that is:
6 * Copyright (c) 2014 Virtual Open Systems Sarl.
7 *
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
10 *
11 */
12
13 #include "qemu/osdep.h"
14 #include "crypto/tlscredspsk.h"
15 #include "libqtest.h"
16 #include "migration/framework.h"
17 #include "migration/migration-qmp.h"
18 #include "migration/migration-util.h"
19
20 #include "tests/unit/crypto-tls-psk-helpers.h"
21 #ifdef CONFIG_TASN1
22 # include "tests/unit/crypto-tls-x509-helpers.h"
23 #endif /* CONFIG_TASN1 */
24
25
26 struct TestMigrateTLSPSKData {
27 char *workdir;
28 char *workdiralt;
29 char *pskfile;
30 char *pskfilealt;
31 };
32
33 static char *tmpfs;
34
35 static void *
migrate_hook_start_tls_psk_common(QTestState * from,QTestState * to,bool mismatch)36 migrate_hook_start_tls_psk_common(QTestState *from,
37 QTestState *to,
38 bool mismatch)
39 {
40 struct TestMigrateTLSPSKData *data =
41 g_new0(struct TestMigrateTLSPSKData, 1);
42
43 data->workdir = g_strdup_printf("%s/tlscredspsk0", tmpfs);
44 data->pskfile = g_strdup_printf("%s/%s", data->workdir,
45 QCRYPTO_TLS_CREDS_PSKFILE);
46 g_mkdir_with_parents(data->workdir, 0700);
47 test_tls_psk_init(data->pskfile);
48
49 if (mismatch) {
50 data->workdiralt = g_strdup_printf("%s/tlscredspskalt0", tmpfs);
51 data->pskfilealt = g_strdup_printf("%s/%s", data->workdiralt,
52 QCRYPTO_TLS_CREDS_PSKFILE);
53 g_mkdir_with_parents(data->workdiralt, 0700);
54 test_tls_psk_init_alt(data->pskfilealt);
55 }
56
57 qtest_qmp_assert_success(from,
58 "{ 'execute': 'object-add',"
59 " 'arguments': { 'qom-type': 'tls-creds-psk',"
60 " 'id': 'tlscredspsk0',"
61 " 'endpoint': 'client',"
62 " 'dir': %s,"
63 " 'username': 'qemu'} }",
64 data->workdir);
65
66 qtest_qmp_assert_success(to,
67 "{ 'execute': 'object-add',"
68 " 'arguments': { 'qom-type': 'tls-creds-psk',"
69 " 'id': 'tlscredspsk0',"
70 " 'endpoint': 'server',"
71 " 'dir': %s } }",
72 mismatch ? data->workdiralt : data->workdir);
73
74 migrate_set_parameter_str(from, "tls-creds", "tlscredspsk0");
75 migrate_set_parameter_str(to, "tls-creds", "tlscredspsk0");
76
77 return data;
78 }
79
80 static void *
migrate_hook_start_tls_psk_match(QTestState * from,QTestState * to)81 migrate_hook_start_tls_psk_match(QTestState *from,
82 QTestState *to)
83 {
84 return migrate_hook_start_tls_psk_common(from, to, false);
85 }
86
87 static void *
migrate_hook_start_tls_psk_mismatch(QTestState * from,QTestState * to)88 migrate_hook_start_tls_psk_mismatch(QTestState *from,
89 QTestState *to)
90 {
91 return migrate_hook_start_tls_psk_common(from, to, true);
92 }
93
94 static void
migrate_hook_end_tls_psk(QTestState * from,QTestState * to,void * opaque)95 migrate_hook_end_tls_psk(QTestState *from,
96 QTestState *to,
97 void *opaque)
98 {
99 struct TestMigrateTLSPSKData *data = opaque;
100
101 test_tls_psk_cleanup(data->pskfile);
102 if (data->pskfilealt) {
103 test_tls_psk_cleanup(data->pskfilealt);
104 }
105 rmdir(data->workdir);
106 if (data->workdiralt) {
107 rmdir(data->workdiralt);
108 }
109
110 g_free(data->workdiralt);
111 g_free(data->pskfilealt);
112 g_free(data->workdir);
113 g_free(data->pskfile);
114 g_free(data);
115 }
116
117 #ifdef CONFIG_TASN1
118 typedef struct {
119 char *workdir;
120 char *keyfile;
121 char *cacert;
122 char *servercert;
123 char *serverkey;
124 char *clientcert;
125 char *clientkey;
126 } TestMigrateTLSX509Data;
127
128 typedef struct {
129 bool verifyclient;
130 bool clientcert;
131 bool hostileclient;
132 bool authzclient;
133 const char *certhostname;
134 const char *certipaddr;
135 } TestMigrateTLSX509;
136
137 static void *
migrate_hook_start_tls_x509_common(QTestState * from,QTestState * to,TestMigrateTLSX509 * args)138 migrate_hook_start_tls_x509_common(QTestState *from,
139 QTestState *to,
140 TestMigrateTLSX509 *args)
141 {
142 TestMigrateTLSX509Data *data = g_new0(TestMigrateTLSX509Data, 1);
143
144 data->workdir = g_strdup_printf("%s/tlscredsx5090", tmpfs);
145 data->keyfile = g_strdup_printf("%s/key.pem", data->workdir);
146
147 data->cacert = g_strdup_printf("%s/ca-cert.pem", data->workdir);
148 data->serverkey = g_strdup_printf("%s/server-key.pem", data->workdir);
149 data->servercert = g_strdup_printf("%s/server-cert.pem", data->workdir);
150 if (args->clientcert) {
151 data->clientkey = g_strdup_printf("%s/client-key.pem", data->workdir);
152 data->clientcert = g_strdup_printf("%s/client-cert.pem", data->workdir);
153 }
154
155 g_mkdir_with_parents(data->workdir, 0700);
156
157 test_tls_init(data->keyfile);
158 #ifndef _WIN32
159 g_assert(link(data->keyfile, data->serverkey) == 0);
160 #else
161 g_assert(CreateHardLink(data->serverkey, data->keyfile, NULL) != 0);
162 #endif
163 if (args->clientcert) {
164 #ifndef _WIN32
165 g_assert(link(data->keyfile, data->clientkey) == 0);
166 #else
167 g_assert(CreateHardLink(data->clientkey, data->keyfile, NULL) != 0);
168 #endif
169 }
170
171 TLS_ROOT_REQ_SIMPLE(cacertreq, data->cacert);
172 if (args->clientcert) {
173 TLS_CERT_REQ_SIMPLE_CLIENT(servercertreq, cacertreq,
174 args->hostileclient ?
175 QCRYPTO_TLS_TEST_CLIENT_HOSTILE_NAME :
176 QCRYPTO_TLS_TEST_CLIENT_NAME,
177 data->clientcert);
178 test_tls_deinit_cert(&servercertreq);
179 }
180
181 TLS_CERT_REQ_SIMPLE_SERVER(clientcertreq, cacertreq,
182 data->servercert,
183 args->certhostname,
184 args->certipaddr);
185 test_tls_deinit_cert(&clientcertreq);
186 test_tls_deinit_cert(&cacertreq);
187
188 qtest_qmp_assert_success(from,
189 "{ 'execute': 'object-add',"
190 " 'arguments': { 'qom-type': 'tls-creds-x509',"
191 " 'id': 'tlscredsx509client0',"
192 " 'endpoint': 'client',"
193 " 'dir': %s,"
194 " 'sanity-check': true,"
195 " 'verify-peer': true} }",
196 data->workdir);
197 migrate_set_parameter_str(from, "tls-creds", "tlscredsx509client0");
198 if (args->certhostname) {
199 migrate_set_parameter_str(from, "tls-hostname", args->certhostname);
200 }
201
202 qtest_qmp_assert_success(to,
203 "{ 'execute': 'object-add',"
204 " 'arguments': { 'qom-type': 'tls-creds-x509',"
205 " 'id': 'tlscredsx509server0',"
206 " 'endpoint': 'server',"
207 " 'dir': %s,"
208 " 'sanity-check': true,"
209 " 'verify-peer': %i} }",
210 data->workdir, args->verifyclient);
211 migrate_set_parameter_str(to, "tls-creds", "tlscredsx509server0");
212
213 if (args->authzclient) {
214 qtest_qmp_assert_success(to,
215 "{ 'execute': 'object-add',"
216 " 'arguments': { 'qom-type': 'authz-simple',"
217 " 'id': 'tlsauthz0',"
218 " 'identity': %s} }",
219 "CN=" QCRYPTO_TLS_TEST_CLIENT_NAME);
220 migrate_set_parameter_str(to, "tls-authz", "tlsauthz0");
221 }
222
223 return data;
224 }
225
226 /*
227 * The normal case: match server's cert hostname against
228 * whatever host we were telling QEMU to connect to (if any)
229 */
230 static void *
migrate_hook_start_tls_x509_default_host(QTestState * from,QTestState * to)231 migrate_hook_start_tls_x509_default_host(QTestState *from,
232 QTestState *to)
233 {
234 TestMigrateTLSX509 args = {
235 .verifyclient = true,
236 .clientcert = true,
237 .certipaddr = "127.0.0.1"
238 };
239 return migrate_hook_start_tls_x509_common(from, to, &args);
240 }
241
242 /*
243 * The unusual case: the server's cert is different from
244 * the address we're telling QEMU to connect to (if any),
245 * so we must give QEMU an explicit hostname to validate
246 */
247 static void *
migrate_hook_start_tls_x509_override_host(QTestState * from,QTestState * to)248 migrate_hook_start_tls_x509_override_host(QTestState *from,
249 QTestState *to)
250 {
251 TestMigrateTLSX509 args = {
252 .verifyclient = true,
253 .clientcert = true,
254 .certhostname = "qemu.org",
255 };
256 return migrate_hook_start_tls_x509_common(from, to, &args);
257 }
258
259 /*
260 * The unusual case: the server's cert is different from
261 * the address we're telling QEMU to connect to, and so we
262 * expect the client to reject the server
263 */
264 static void *
migrate_hook_start_tls_x509_mismatch_host(QTestState * from,QTestState * to)265 migrate_hook_start_tls_x509_mismatch_host(QTestState *from,
266 QTestState *to)
267 {
268 TestMigrateTLSX509 args = {
269 .verifyclient = true,
270 .clientcert = true,
271 .certipaddr = "10.0.0.1",
272 };
273 return migrate_hook_start_tls_x509_common(from, to, &args);
274 }
275
276 static void *
migrate_hook_start_tls_x509_friendly_client(QTestState * from,QTestState * to)277 migrate_hook_start_tls_x509_friendly_client(QTestState *from,
278 QTestState *to)
279 {
280 TestMigrateTLSX509 args = {
281 .verifyclient = true,
282 .clientcert = true,
283 .authzclient = true,
284 .certipaddr = "127.0.0.1",
285 };
286 return migrate_hook_start_tls_x509_common(from, to, &args);
287 }
288
289 static void *
migrate_hook_start_tls_x509_hostile_client(QTestState * from,QTestState * to)290 migrate_hook_start_tls_x509_hostile_client(QTestState *from,
291 QTestState *to)
292 {
293 TestMigrateTLSX509 args = {
294 .verifyclient = true,
295 .clientcert = true,
296 .hostileclient = true,
297 .authzclient = true,
298 .certipaddr = "127.0.0.1",
299 };
300 return migrate_hook_start_tls_x509_common(from, to, &args);
301 }
302
303 /*
304 * The case with no client certificate presented,
305 * and no server verification
306 */
307 static void *
migrate_hook_start_tls_x509_allow_anon_client(QTestState * from,QTestState * to)308 migrate_hook_start_tls_x509_allow_anon_client(QTestState *from,
309 QTestState *to)
310 {
311 TestMigrateTLSX509 args = {
312 .certipaddr = "127.0.0.1",
313 };
314 return migrate_hook_start_tls_x509_common(from, to, &args);
315 }
316
317 /*
318 * The case with no client certificate presented,
319 * and server verification rejecting
320 */
321 static void *
migrate_hook_start_tls_x509_reject_anon_client(QTestState * from,QTestState * to)322 migrate_hook_start_tls_x509_reject_anon_client(QTestState *from,
323 QTestState *to)
324 {
325 TestMigrateTLSX509 args = {
326 .verifyclient = true,
327 .certipaddr = "127.0.0.1",
328 };
329 return migrate_hook_start_tls_x509_common(from, to, &args);
330 }
331
332 static void
migrate_hook_end_tls_x509(QTestState * from,QTestState * to,void * opaque)333 migrate_hook_end_tls_x509(QTestState *from,
334 QTestState *to,
335 void *opaque)
336 {
337 TestMigrateTLSX509Data *data = opaque;
338
339 test_tls_cleanup(data->keyfile);
340 g_free(data->keyfile);
341
342 unlink(data->cacert);
343 g_free(data->cacert);
344 unlink(data->servercert);
345 g_free(data->servercert);
346 unlink(data->serverkey);
347 g_free(data->serverkey);
348
349 if (data->clientcert) {
350 unlink(data->clientcert);
351 g_free(data->clientcert);
352 }
353 if (data->clientkey) {
354 unlink(data->clientkey);
355 g_free(data->clientkey);
356 }
357
358 rmdir(data->workdir);
359 g_free(data->workdir);
360
361 g_free(data);
362 }
363 #endif /* CONFIG_TASN1 */
364
test_postcopy_tls_psk(void)365 static void test_postcopy_tls_psk(void)
366 {
367 MigrateCommon args = {
368 .start_hook = migrate_hook_start_tls_psk_match,
369 .end_hook = migrate_hook_end_tls_psk,
370 };
371
372 test_postcopy_common(&args);
373 }
374
test_postcopy_preempt_tls_psk(void)375 static void test_postcopy_preempt_tls_psk(void)
376 {
377 MigrateCommon args = {
378 .postcopy_preempt = true,
379 .start_hook = migrate_hook_start_tls_psk_match,
380 .end_hook = migrate_hook_end_tls_psk,
381 };
382
383 test_postcopy_common(&args);
384 }
385
test_postcopy_recovery_tls_psk(void)386 static void test_postcopy_recovery_tls_psk(void)
387 {
388 MigrateCommon args = {
389 .start_hook = migrate_hook_start_tls_psk_match,
390 .end_hook = migrate_hook_end_tls_psk,
391 };
392
393 test_postcopy_recovery_common(&args);
394 }
395
396 /* This contains preempt+recovery+tls test altogether */
test_postcopy_preempt_all(void)397 static void test_postcopy_preempt_all(void)
398 {
399 MigrateCommon args = {
400 .postcopy_preempt = true,
401 .start_hook = migrate_hook_start_tls_psk_match,
402 .end_hook = migrate_hook_end_tls_psk,
403 };
404
405 test_postcopy_recovery_common(&args);
406 }
407
test_precopy_unix_tls_psk(void)408 static void test_precopy_unix_tls_psk(void)
409 {
410 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
411 MigrateCommon args = {
412 .connect_uri = uri,
413 .listen_uri = uri,
414 .start_hook = migrate_hook_start_tls_psk_match,
415 .end_hook = migrate_hook_end_tls_psk,
416 };
417
418 test_precopy_common(&args);
419 }
420
421 #ifdef CONFIG_TASN1
test_precopy_unix_tls_x509_default_host(void)422 static void test_precopy_unix_tls_x509_default_host(void)
423 {
424 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
425 MigrateCommon args = {
426 .start = {
427 .hide_stderr = true,
428 },
429 .connect_uri = uri,
430 .listen_uri = uri,
431 .start_hook = migrate_hook_start_tls_x509_default_host,
432 .end_hook = migrate_hook_end_tls_x509,
433 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
434 };
435
436 test_precopy_common(&args);
437 }
438
test_precopy_unix_tls_x509_override_host(void)439 static void test_precopy_unix_tls_x509_override_host(void)
440 {
441 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
442 MigrateCommon args = {
443 .connect_uri = uri,
444 .listen_uri = uri,
445 .start_hook = migrate_hook_start_tls_x509_override_host,
446 .end_hook = migrate_hook_end_tls_x509,
447 };
448
449 test_precopy_common(&args);
450 }
451 #endif /* CONFIG_TASN1 */
452
test_precopy_tcp_tls_psk_match(void)453 static void test_precopy_tcp_tls_psk_match(void)
454 {
455 MigrateCommon args = {
456 .listen_uri = "tcp:127.0.0.1:0",
457 .start_hook = migrate_hook_start_tls_psk_match,
458 .end_hook = migrate_hook_end_tls_psk,
459 };
460
461 test_precopy_common(&args);
462 }
463
test_precopy_tcp_tls_psk_mismatch(void)464 static void test_precopy_tcp_tls_psk_mismatch(void)
465 {
466 MigrateCommon args = {
467 .start = {
468 .hide_stderr = true,
469 },
470 .listen_uri = "tcp:127.0.0.1:0",
471 .start_hook = migrate_hook_start_tls_psk_mismatch,
472 .end_hook = migrate_hook_end_tls_psk,
473 .result = MIG_TEST_FAIL,
474 };
475
476 test_precopy_common(&args);
477 }
478
479 #ifdef CONFIG_TASN1
test_precopy_tcp_tls_x509_default_host(void)480 static void test_precopy_tcp_tls_x509_default_host(void)
481 {
482 MigrateCommon args = {
483 .listen_uri = "tcp:127.0.0.1:0",
484 .start_hook = migrate_hook_start_tls_x509_default_host,
485 .end_hook = migrate_hook_end_tls_x509,
486 };
487
488 test_precopy_common(&args);
489 }
490
test_precopy_tcp_tls_x509_override_host(void)491 static void test_precopy_tcp_tls_x509_override_host(void)
492 {
493 MigrateCommon args = {
494 .listen_uri = "tcp:127.0.0.1:0",
495 .start_hook = migrate_hook_start_tls_x509_override_host,
496 .end_hook = migrate_hook_end_tls_x509,
497 };
498
499 test_precopy_common(&args);
500 }
501
test_precopy_tcp_tls_x509_mismatch_host(void)502 static void test_precopy_tcp_tls_x509_mismatch_host(void)
503 {
504 MigrateCommon args = {
505 .start = {
506 .hide_stderr = true,
507 },
508 .listen_uri = "tcp:127.0.0.1:0",
509 .start_hook = migrate_hook_start_tls_x509_mismatch_host,
510 .end_hook = migrate_hook_end_tls_x509,
511 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
512 };
513
514 test_precopy_common(&args);
515 }
516
test_precopy_tcp_tls_x509_friendly_client(void)517 static void test_precopy_tcp_tls_x509_friendly_client(void)
518 {
519 MigrateCommon args = {
520 .listen_uri = "tcp:127.0.0.1:0",
521 .start_hook = migrate_hook_start_tls_x509_friendly_client,
522 .end_hook = migrate_hook_end_tls_x509,
523 };
524
525 test_precopy_common(&args);
526 }
527
test_precopy_tcp_tls_x509_hostile_client(void)528 static void test_precopy_tcp_tls_x509_hostile_client(void)
529 {
530 MigrateCommon args = {
531 .start = {
532 .hide_stderr = true,
533 },
534 .listen_uri = "tcp:127.0.0.1:0",
535 .start_hook = migrate_hook_start_tls_x509_hostile_client,
536 .end_hook = migrate_hook_end_tls_x509,
537 .result = MIG_TEST_FAIL,
538 };
539
540 test_precopy_common(&args);
541 }
542
test_precopy_tcp_tls_x509_allow_anon_client(void)543 static void test_precopy_tcp_tls_x509_allow_anon_client(void)
544 {
545 MigrateCommon args = {
546 .listen_uri = "tcp:127.0.0.1:0",
547 .start_hook = migrate_hook_start_tls_x509_allow_anon_client,
548 .end_hook = migrate_hook_end_tls_x509,
549 };
550
551 test_precopy_common(&args);
552 }
553
test_precopy_tcp_tls_x509_reject_anon_client(void)554 static void test_precopy_tcp_tls_x509_reject_anon_client(void)
555 {
556 MigrateCommon args = {
557 .start = {
558 .hide_stderr = true,
559 },
560 .listen_uri = "tcp:127.0.0.1:0",
561 .start_hook = migrate_hook_start_tls_x509_reject_anon_client,
562 .end_hook = migrate_hook_end_tls_x509,
563 .result = MIG_TEST_FAIL,
564 };
565
566 test_precopy_common(&args);
567 }
568 #endif /* CONFIG_TASN1 */
569
570 static void *
migrate_hook_start_multifd_tcp_tls_psk_match(QTestState * from,QTestState * to)571 migrate_hook_start_multifd_tcp_tls_psk_match(QTestState *from,
572 QTestState *to)
573 {
574 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
575 return migrate_hook_start_tls_psk_match(from, to);
576 }
577
578 static void *
migrate_hook_start_multifd_tcp_tls_psk_mismatch(QTestState * from,QTestState * to)579 migrate_hook_start_multifd_tcp_tls_psk_mismatch(QTestState *from,
580 QTestState *to)
581 {
582 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
583 return migrate_hook_start_tls_psk_mismatch(from, to);
584 }
585
586 #ifdef CONFIG_TASN1
587 static void *
migrate_hook_start_multifd_tls_x509_default_host(QTestState * from,QTestState * to)588 migrate_hook_start_multifd_tls_x509_default_host(QTestState *from,
589 QTestState *to)
590 {
591 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
592 return migrate_hook_start_tls_x509_default_host(from, to);
593 }
594
595 static void *
migrate_hook_start_multifd_tls_x509_override_host(QTestState * from,QTestState * to)596 migrate_hook_start_multifd_tls_x509_override_host(QTestState *from,
597 QTestState *to)
598 {
599 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
600 return migrate_hook_start_tls_x509_override_host(from, to);
601 }
602
603 static void *
migrate_hook_start_multifd_tls_x509_mismatch_host(QTestState * from,QTestState * to)604 migrate_hook_start_multifd_tls_x509_mismatch_host(QTestState *from,
605 QTestState *to)
606 {
607 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
608 return migrate_hook_start_tls_x509_mismatch_host(from, to);
609 }
610
611 static void *
migrate_hook_start_multifd_tls_x509_allow_anon_client(QTestState * from,QTestState * to)612 migrate_hook_start_multifd_tls_x509_allow_anon_client(QTestState *from,
613 QTestState *to)
614 {
615 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
616 return migrate_hook_start_tls_x509_allow_anon_client(from, to);
617 }
618
619 static void *
migrate_hook_start_multifd_tls_x509_reject_anon_client(QTestState * from,QTestState * to)620 migrate_hook_start_multifd_tls_x509_reject_anon_client(QTestState *from,
621 QTestState *to)
622 {
623 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
624 return migrate_hook_start_tls_x509_reject_anon_client(from, to);
625 }
626 #endif /* CONFIG_TASN1 */
627
test_multifd_tcp_tls_psk_match(void)628 static void test_multifd_tcp_tls_psk_match(void)
629 {
630 MigrateCommon args = {
631 .listen_uri = "defer",
632 .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
633 .end_hook = migrate_hook_end_tls_psk,
634 };
635 test_precopy_common(&args);
636 }
637
test_multifd_tcp_tls_psk_mismatch(void)638 static void test_multifd_tcp_tls_psk_mismatch(void)
639 {
640 MigrateCommon args = {
641 .start = {
642 .hide_stderr = true,
643 },
644 .listen_uri = "defer",
645 .start_hook = migrate_hook_start_multifd_tcp_tls_psk_mismatch,
646 .end_hook = migrate_hook_end_tls_psk,
647 .result = MIG_TEST_FAIL,
648 };
649 test_precopy_common(&args);
650 }
651
652 #ifdef CONFIG_TASN1
test_multifd_tcp_tls_x509_default_host(void)653 static void test_multifd_tcp_tls_x509_default_host(void)
654 {
655 MigrateCommon args = {
656 .listen_uri = "defer",
657 .start_hook = migrate_hook_start_multifd_tls_x509_default_host,
658 .end_hook = migrate_hook_end_tls_x509,
659 };
660 test_precopy_common(&args);
661 }
662
test_multifd_tcp_tls_x509_override_host(void)663 static void test_multifd_tcp_tls_x509_override_host(void)
664 {
665 MigrateCommon args = {
666 .listen_uri = "defer",
667 .start_hook = migrate_hook_start_multifd_tls_x509_override_host,
668 .end_hook = migrate_hook_end_tls_x509,
669 };
670 test_precopy_common(&args);
671 }
672
test_multifd_tcp_tls_x509_mismatch_host(void)673 static void test_multifd_tcp_tls_x509_mismatch_host(void)
674 {
675 /*
676 * This has different behaviour to the non-multifd case.
677 *
678 * In non-multifd case when client aborts due to mismatched
679 * cert host, the server has already started trying to load
680 * migration state, and so it exits with I/O failure.
681 *
682 * In multifd case when client aborts due to mismatched
683 * cert host, the server is still waiting for the other
684 * multifd connections to arrive so hasn't started trying
685 * to load migration state, and thus just aborts the migration
686 * without exiting.
687 */
688 MigrateCommon args = {
689 .start = {
690 .hide_stderr = true,
691 },
692 .listen_uri = "defer",
693 .start_hook = migrate_hook_start_multifd_tls_x509_mismatch_host,
694 .end_hook = migrate_hook_end_tls_x509,
695 .result = MIG_TEST_FAIL,
696 };
697 test_precopy_common(&args);
698 }
699
test_multifd_tcp_tls_x509_allow_anon_client(void)700 static void test_multifd_tcp_tls_x509_allow_anon_client(void)
701 {
702 MigrateCommon args = {
703 .listen_uri = "defer",
704 .start_hook = migrate_hook_start_multifd_tls_x509_allow_anon_client,
705 .end_hook = migrate_hook_end_tls_x509,
706 };
707 test_precopy_common(&args);
708 }
709
test_multifd_tcp_tls_x509_reject_anon_client(void)710 static void test_multifd_tcp_tls_x509_reject_anon_client(void)
711 {
712 MigrateCommon args = {
713 .start = {
714 .hide_stderr = true,
715 },
716 .listen_uri = "defer",
717 .start_hook = migrate_hook_start_multifd_tls_x509_reject_anon_client,
718 .end_hook = migrate_hook_end_tls_x509,
719 .result = MIG_TEST_FAIL,
720 };
721 test_precopy_common(&args);
722 }
723 #endif /* CONFIG_TASN1 */
724
migration_test_add_tls_smoke(MigrationTestEnv * env)725 static void migration_test_add_tls_smoke(MigrationTestEnv *env)
726 {
727 migration_test_add("/migration/precopy/tcp/tls/psk/match",
728 test_precopy_tcp_tls_psk_match);
729 }
730
migration_test_add_tls(MigrationTestEnv * env)731 void migration_test_add_tls(MigrationTestEnv *env)
732 {
733 tmpfs = env->tmpfs;
734
735 migration_test_add_tls_smoke(env);
736
737 if (!env->full_set) {
738 return;
739 }
740
741 migration_test_add("/migration/precopy/unix/tls/psk",
742 test_precopy_unix_tls_psk);
743
744 if (env->has_uffd) {
745 /*
746 * NOTE: psk test is enough for postcopy, as other types of TLS
747 * channels are tested under precopy. Here what we want to test is the
748 * general postcopy path that has TLS channel enabled.
749 */
750 migration_test_add("/migration/postcopy/tls/psk",
751 test_postcopy_tls_psk);
752 migration_test_add("/migration/postcopy/recovery/tls/psk",
753 test_postcopy_recovery_tls_psk);
754 migration_test_add("/migration/postcopy/preempt/tls/psk",
755 test_postcopy_preempt_tls_psk);
756 migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
757 test_postcopy_preempt_all);
758 }
759 #ifdef CONFIG_TASN1
760 migration_test_add("/migration/precopy/unix/tls/x509/default-host",
761 test_precopy_unix_tls_x509_default_host);
762 migration_test_add("/migration/precopy/unix/tls/x509/override-host",
763 test_precopy_unix_tls_x509_override_host);
764 #endif /* CONFIG_TASN1 */
765
766 migration_test_add("/migration/precopy/tcp/tls/psk/mismatch",
767 test_precopy_tcp_tls_psk_mismatch);
768 #ifdef CONFIG_TASN1
769 migration_test_add("/migration/precopy/tcp/tls/x509/default-host",
770 test_precopy_tcp_tls_x509_default_host);
771 migration_test_add("/migration/precopy/tcp/tls/x509/override-host",
772 test_precopy_tcp_tls_x509_override_host);
773 migration_test_add("/migration/precopy/tcp/tls/x509/mismatch-host",
774 test_precopy_tcp_tls_x509_mismatch_host);
775 migration_test_add("/migration/precopy/tcp/tls/x509/friendly-client",
776 test_precopy_tcp_tls_x509_friendly_client);
777 migration_test_add("/migration/precopy/tcp/tls/x509/hostile-client",
778 test_precopy_tcp_tls_x509_hostile_client);
779 migration_test_add("/migration/precopy/tcp/tls/x509/allow-anon-client",
780 test_precopy_tcp_tls_x509_allow_anon_client);
781 migration_test_add("/migration/precopy/tcp/tls/x509/reject-anon-client",
782 test_precopy_tcp_tls_x509_reject_anon_client);
783 #endif /* CONFIG_TASN1 */
784
785 migration_test_add("/migration/multifd/tcp/tls/psk/match",
786 test_multifd_tcp_tls_psk_match);
787 migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
788 test_multifd_tcp_tls_psk_mismatch);
789 #ifdef CONFIG_TASN1
790 migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
791 test_multifd_tcp_tls_x509_default_host);
792 migration_test_add("/migration/multifd/tcp/tls/x509/override-host",
793 test_multifd_tcp_tls_x509_override_host);
794 migration_test_add("/migration/multifd/tcp/tls/x509/mismatch-host",
795 test_multifd_tcp_tls_x509_mismatch_host);
796 migration_test_add("/migration/multifd/tcp/tls/x509/allow-anon-client",
797 test_multifd_tcp_tls_x509_allow_anon_client);
798 migration_test_add("/migration/multifd/tcp/tls/x509/reject-anon-client",
799 test_multifd_tcp_tls_x509_reject_anon_client);
800 #endif /* CONFIG_TASN1 */
801 }
802