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 .start_hook = migrate_hook_start_tls_psk_match,
379 .end_hook = migrate_hook_end_tls_psk,
380 .start = {
381 .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
382 },
383 };
384
385 test_postcopy_common(&args);
386 }
387
test_postcopy_recovery_tls_psk(void)388 static void test_postcopy_recovery_tls_psk(void)
389 {
390 MigrateCommon args = {
391 .start_hook = migrate_hook_start_tls_psk_match,
392 .end_hook = migrate_hook_end_tls_psk,
393 };
394
395 test_postcopy_recovery_common(&args);
396 }
397
test_multifd_postcopy_recovery_tls_psk(void)398 static void test_multifd_postcopy_recovery_tls_psk(void)
399 {
400 MigrateCommon args = {
401 .start_hook = migrate_hook_start_tls_psk_match,
402 .end_hook = migrate_hook_end_tls_psk,
403 .start = {
404 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
405 },
406 };
407
408 test_postcopy_recovery_common(&args);
409 }
410
411 /* This contains preempt+recovery+tls test altogether */
test_postcopy_preempt_all(void)412 static void test_postcopy_preempt_all(void)
413 {
414 MigrateCommon args = {
415 .start_hook = migrate_hook_start_tls_psk_match,
416 .end_hook = migrate_hook_end_tls_psk,
417 .start = {
418 .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
419 },
420 };
421
422 test_postcopy_recovery_common(&args);
423 }
424
test_multifd_postcopy_preempt_recovery_tls_psk(void)425 static void test_multifd_postcopy_preempt_recovery_tls_psk(void)
426 {
427 MigrateCommon args = {
428 .start_hook = migrate_hook_start_tls_psk_match,
429 .end_hook = migrate_hook_end_tls_psk,
430 .start = {
431 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
432 .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
433 },
434 };
435
436 test_postcopy_recovery_common(&args);
437 }
438
test_precopy_unix_tls_psk(void)439 static void test_precopy_unix_tls_psk(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_psk_match,
446 .end_hook = migrate_hook_end_tls_psk,
447 };
448
449 test_precopy_common(&args);
450 }
451
452 #ifdef CONFIG_TASN1
test_precopy_unix_tls_x509_default_host(void)453 static void test_precopy_unix_tls_x509_default_host(void)
454 {
455 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
456 MigrateCommon args = {
457 .start = {
458 .hide_stderr = true,
459 },
460 .connect_uri = uri,
461 .listen_uri = uri,
462 .start_hook = migrate_hook_start_tls_x509_default_host,
463 .end_hook = migrate_hook_end_tls_x509,
464 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
465 };
466
467 test_precopy_common(&args);
468 }
469
test_precopy_unix_tls_x509_override_host(void)470 static void test_precopy_unix_tls_x509_override_host(void)
471 {
472 g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
473 MigrateCommon args = {
474 .connect_uri = uri,
475 .listen_uri = uri,
476 .start_hook = migrate_hook_start_tls_x509_override_host,
477 .end_hook = migrate_hook_end_tls_x509,
478 };
479
480 test_precopy_common(&args);
481 }
482 #endif /* CONFIG_TASN1 */
483
test_precopy_tcp_tls_psk_match(void)484 static void test_precopy_tcp_tls_psk_match(void)
485 {
486 MigrateCommon args = {
487 .listen_uri = "tcp:127.0.0.1:0",
488 .start_hook = migrate_hook_start_tls_psk_match,
489 .end_hook = migrate_hook_end_tls_psk,
490 };
491
492 test_precopy_common(&args);
493 }
494
test_precopy_tcp_tls_psk_mismatch(void)495 static void test_precopy_tcp_tls_psk_mismatch(void)
496 {
497 MigrateCommon args = {
498 .start = {
499 .hide_stderr = true,
500 },
501 .listen_uri = "tcp:127.0.0.1:0",
502 .start_hook = migrate_hook_start_tls_psk_mismatch,
503 .end_hook = migrate_hook_end_tls_psk,
504 .result = MIG_TEST_FAIL,
505 };
506
507 test_precopy_common(&args);
508 }
509
510 #ifdef CONFIG_TASN1
test_precopy_tcp_tls_x509_default_host(void)511 static void test_precopy_tcp_tls_x509_default_host(void)
512 {
513 MigrateCommon args = {
514 .listen_uri = "tcp:127.0.0.1:0",
515 .start_hook = migrate_hook_start_tls_x509_default_host,
516 .end_hook = migrate_hook_end_tls_x509,
517 };
518
519 test_precopy_common(&args);
520 }
521
test_precopy_tcp_tls_x509_override_host(void)522 static void test_precopy_tcp_tls_x509_override_host(void)
523 {
524 MigrateCommon args = {
525 .listen_uri = "tcp:127.0.0.1:0",
526 .start_hook = migrate_hook_start_tls_x509_override_host,
527 .end_hook = migrate_hook_end_tls_x509,
528 };
529
530 test_precopy_common(&args);
531 }
532
test_precopy_tcp_tls_x509_mismatch_host(void)533 static void test_precopy_tcp_tls_x509_mismatch_host(void)
534 {
535 MigrateCommon args = {
536 .start = {
537 .hide_stderr = true,
538 },
539 .listen_uri = "tcp:127.0.0.1:0",
540 .start_hook = migrate_hook_start_tls_x509_mismatch_host,
541 .end_hook = migrate_hook_end_tls_x509,
542 .result = MIG_TEST_FAIL_DEST_QUIT_ERR,
543 };
544
545 test_precopy_common(&args);
546 }
547
test_precopy_tcp_tls_x509_friendly_client(void)548 static void test_precopy_tcp_tls_x509_friendly_client(void)
549 {
550 MigrateCommon args = {
551 .listen_uri = "tcp:127.0.0.1:0",
552 .start_hook = migrate_hook_start_tls_x509_friendly_client,
553 .end_hook = migrate_hook_end_tls_x509,
554 };
555
556 test_precopy_common(&args);
557 }
558
test_precopy_tcp_tls_x509_hostile_client(void)559 static void test_precopy_tcp_tls_x509_hostile_client(void)
560 {
561 MigrateCommon args = {
562 .start = {
563 .hide_stderr = true,
564 },
565 .listen_uri = "tcp:127.0.0.1:0",
566 .start_hook = migrate_hook_start_tls_x509_hostile_client,
567 .end_hook = migrate_hook_end_tls_x509,
568 .result = MIG_TEST_FAIL,
569 };
570
571 test_precopy_common(&args);
572 }
573
test_precopy_tcp_tls_x509_allow_anon_client(void)574 static void test_precopy_tcp_tls_x509_allow_anon_client(void)
575 {
576 MigrateCommon args = {
577 .listen_uri = "tcp:127.0.0.1:0",
578 .start_hook = migrate_hook_start_tls_x509_allow_anon_client,
579 .end_hook = migrate_hook_end_tls_x509,
580 };
581
582 test_precopy_common(&args);
583 }
584
test_precopy_tcp_tls_x509_reject_anon_client(void)585 static void test_precopy_tcp_tls_x509_reject_anon_client(void)
586 {
587 MigrateCommon args = {
588 .start = {
589 .hide_stderr = true,
590 },
591 .listen_uri = "tcp:127.0.0.1:0",
592 .start_hook = migrate_hook_start_tls_x509_reject_anon_client,
593 .end_hook = migrate_hook_end_tls_x509,
594 .result = MIG_TEST_FAIL,
595 };
596
597 test_precopy_common(&args);
598 }
599 #endif /* CONFIG_TASN1 */
600
601 static void *
migrate_hook_start_multifd_tcp_tls_psk_match(QTestState * from,QTestState * to)602 migrate_hook_start_multifd_tcp_tls_psk_match(QTestState *from,
603 QTestState *to)
604 {
605 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
606 return migrate_hook_start_tls_psk_match(from, to);
607 }
608
609 static void *
migrate_hook_start_multifd_tcp_tls_psk_mismatch(QTestState * from,QTestState * to)610 migrate_hook_start_multifd_tcp_tls_psk_mismatch(QTestState *from,
611 QTestState *to)
612 {
613 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
614 return migrate_hook_start_tls_psk_mismatch(from, to);
615 }
616
617 #ifdef CONFIG_TASN1
618 static void *
migrate_hook_start_multifd_tls_x509_default_host(QTestState * from,QTestState * to)619 migrate_hook_start_multifd_tls_x509_default_host(QTestState *from,
620 QTestState *to)
621 {
622 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
623 return migrate_hook_start_tls_x509_default_host(from, to);
624 }
625
626 static void *
migrate_hook_start_multifd_tls_x509_override_host(QTestState * from,QTestState * to)627 migrate_hook_start_multifd_tls_x509_override_host(QTestState *from,
628 QTestState *to)
629 {
630 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
631 return migrate_hook_start_tls_x509_override_host(from, to);
632 }
633
634 static void *
migrate_hook_start_multifd_tls_x509_mismatch_host(QTestState * from,QTestState * to)635 migrate_hook_start_multifd_tls_x509_mismatch_host(QTestState *from,
636 QTestState *to)
637 {
638 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
639 return migrate_hook_start_tls_x509_mismatch_host(from, to);
640 }
641
642 static void *
migrate_hook_start_multifd_tls_x509_allow_anon_client(QTestState * from,QTestState * to)643 migrate_hook_start_multifd_tls_x509_allow_anon_client(QTestState *from,
644 QTestState *to)
645 {
646 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
647 return migrate_hook_start_tls_x509_allow_anon_client(from, to);
648 }
649
650 static void *
migrate_hook_start_multifd_tls_x509_reject_anon_client(QTestState * from,QTestState * to)651 migrate_hook_start_multifd_tls_x509_reject_anon_client(QTestState *from,
652 QTestState *to)
653 {
654 migrate_hook_start_precopy_tcp_multifd_common(from, to, "none");
655 return migrate_hook_start_tls_x509_reject_anon_client(from, to);
656 }
657 #endif /* CONFIG_TASN1 */
658
test_multifd_tcp_tls_psk_match(void)659 static void test_multifd_tcp_tls_psk_match(void)
660 {
661 MigrateCommon args = {
662 .listen_uri = "defer",
663 .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
664 .end_hook = migrate_hook_end_tls_psk,
665 .start = {
666 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
667 },
668 };
669 test_precopy_common(&args);
670 }
671
test_multifd_tcp_tls_psk_mismatch(void)672 static void test_multifd_tcp_tls_psk_mismatch(void)
673 {
674 MigrateCommon args = {
675 .start = {
676 .hide_stderr = true,
677 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
678 },
679 .listen_uri = "defer",
680 .start_hook = migrate_hook_start_multifd_tcp_tls_psk_mismatch,
681 .end_hook = migrate_hook_end_tls_psk,
682 .result = MIG_TEST_FAIL,
683 };
684 test_precopy_common(&args);
685 }
686
test_multifd_postcopy_tcp_tls_psk_match(void)687 static void test_multifd_postcopy_tcp_tls_psk_match(void)
688 {
689 MigrateCommon args = {
690 .start = {
691 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
692 .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true,
693 },
694 .listen_uri = "defer",
695 .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
696 .end_hook = migrate_hook_end_tls_psk,
697 };
698
699 test_precopy_common(&args);
700 }
701
702 #ifdef CONFIG_TASN1
test_multifd_tcp_tls_x509_default_host(void)703 static void test_multifd_tcp_tls_x509_default_host(void)
704 {
705 MigrateCommon args = {
706 .listen_uri = "defer",
707 .start_hook = migrate_hook_start_multifd_tls_x509_default_host,
708 .end_hook = migrate_hook_end_tls_x509,
709 .start = {
710 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
711 },
712 };
713 test_precopy_common(&args);
714 }
715
test_multifd_tcp_tls_x509_override_host(void)716 static void test_multifd_tcp_tls_x509_override_host(void)
717 {
718 MigrateCommon args = {
719 .listen_uri = "defer",
720 .start_hook = migrate_hook_start_multifd_tls_x509_override_host,
721 .end_hook = migrate_hook_end_tls_x509,
722 .start = {
723 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
724 },
725 };
726 test_precopy_common(&args);
727 }
728
test_multifd_tcp_tls_x509_mismatch_host(void)729 static void test_multifd_tcp_tls_x509_mismatch_host(void)
730 {
731 /*
732 * This has different behaviour to the non-multifd case.
733 *
734 * In non-multifd case when client aborts due to mismatched
735 * cert host, the server has already started trying to load
736 * migration state, and so it exits with I/O failure.
737 *
738 * In multifd case when client aborts due to mismatched
739 * cert host, the server is still waiting for the other
740 * multifd connections to arrive so hasn't started trying
741 * to load migration state, and thus just aborts the migration
742 * without exiting.
743 */
744 MigrateCommon args = {
745 .start = {
746 .hide_stderr = true,
747 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
748 },
749 .listen_uri = "defer",
750 .start_hook = migrate_hook_start_multifd_tls_x509_mismatch_host,
751 .end_hook = migrate_hook_end_tls_x509,
752 .result = MIG_TEST_FAIL,
753 };
754 test_precopy_common(&args);
755 }
756
test_multifd_tcp_tls_x509_allow_anon_client(void)757 static void test_multifd_tcp_tls_x509_allow_anon_client(void)
758 {
759 MigrateCommon args = {
760 .listen_uri = "defer",
761 .start_hook = migrate_hook_start_multifd_tls_x509_allow_anon_client,
762 .end_hook = migrate_hook_end_tls_x509,
763 .start = {
764 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
765 },
766 };
767 test_precopy_common(&args);
768 }
769
test_multifd_tcp_tls_x509_reject_anon_client(void)770 static void test_multifd_tcp_tls_x509_reject_anon_client(void)
771 {
772 MigrateCommon args = {
773 .start = {
774 .hide_stderr = true,
775 .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
776 },
777 .listen_uri = "defer",
778 .start_hook = migrate_hook_start_multifd_tls_x509_reject_anon_client,
779 .end_hook = migrate_hook_end_tls_x509,
780 .result = MIG_TEST_FAIL,
781 };
782 test_precopy_common(&args);
783 }
784 #endif /* CONFIG_TASN1 */
785
migration_test_add_tls_smoke(MigrationTestEnv * env)786 static void migration_test_add_tls_smoke(MigrationTestEnv *env)
787 {
788 migration_test_add("/migration/precopy/tcp/tls/psk/match",
789 test_precopy_tcp_tls_psk_match);
790 }
791
migration_test_add_tls(MigrationTestEnv * env)792 void migration_test_add_tls(MigrationTestEnv *env)
793 {
794 tmpfs = env->tmpfs;
795
796 migration_test_add_tls_smoke(env);
797
798 if (!env->full_set) {
799 return;
800 }
801
802 migration_test_add("/migration/precopy/unix/tls/psk",
803 test_precopy_unix_tls_psk);
804
805 if (env->has_uffd) {
806 /*
807 * NOTE: psk test is enough for postcopy, as other types of TLS
808 * channels are tested under precopy. Here what we want to test is the
809 * general postcopy path that has TLS channel enabled.
810 */
811 migration_test_add("/migration/postcopy/tls/psk",
812 test_postcopy_tls_psk);
813 migration_test_add("/migration/postcopy/recovery/tls/psk",
814 test_postcopy_recovery_tls_psk);
815 migration_test_add("/migration/postcopy/preempt/tls/psk",
816 test_postcopy_preempt_tls_psk);
817 migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
818 test_postcopy_preempt_all);
819 migration_test_add("/migration/multifd+postcopy/recovery/tls/psk",
820 test_multifd_postcopy_recovery_tls_psk);
821 migration_test_add(
822 "/migration/multifd+postcopy/preempt/recovery/tls/psk",
823 test_multifd_postcopy_preempt_recovery_tls_psk);
824 }
825 #ifdef CONFIG_TASN1
826 migration_test_add("/migration/precopy/unix/tls/x509/default-host",
827 test_precopy_unix_tls_x509_default_host);
828 migration_test_add("/migration/precopy/unix/tls/x509/override-host",
829 test_precopy_unix_tls_x509_override_host);
830 #endif /* CONFIG_TASN1 */
831
832 migration_test_add("/migration/precopy/tcp/tls/psk/mismatch",
833 test_precopy_tcp_tls_psk_mismatch);
834 #ifdef CONFIG_TASN1
835 migration_test_add("/migration/precopy/tcp/tls/x509/default-host",
836 test_precopy_tcp_tls_x509_default_host);
837 migration_test_add("/migration/precopy/tcp/tls/x509/override-host",
838 test_precopy_tcp_tls_x509_override_host);
839 migration_test_add("/migration/precopy/tcp/tls/x509/mismatch-host",
840 test_precopy_tcp_tls_x509_mismatch_host);
841 migration_test_add("/migration/precopy/tcp/tls/x509/friendly-client",
842 test_precopy_tcp_tls_x509_friendly_client);
843 migration_test_add("/migration/precopy/tcp/tls/x509/hostile-client",
844 test_precopy_tcp_tls_x509_hostile_client);
845 migration_test_add("/migration/precopy/tcp/tls/x509/allow-anon-client",
846 test_precopy_tcp_tls_x509_allow_anon_client);
847 migration_test_add("/migration/precopy/tcp/tls/x509/reject-anon-client",
848 test_precopy_tcp_tls_x509_reject_anon_client);
849 #endif /* CONFIG_TASN1 */
850
851 migration_test_add("/migration/multifd/tcp/tls/psk/match",
852 test_multifd_tcp_tls_psk_match);
853 migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
854 test_multifd_tcp_tls_psk_mismatch);
855 if (env->has_uffd) {
856 migration_test_add("/migration/multifd+postcopy/tcp/tls/psk/match",
857 test_multifd_postcopy_tcp_tls_psk_match);
858 }
859 #ifdef CONFIG_TASN1
860 migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
861 test_multifd_tcp_tls_x509_default_host);
862 migration_test_add("/migration/multifd/tcp/tls/x509/override-host",
863 test_multifd_tcp_tls_x509_override_host);
864 migration_test_add("/migration/multifd/tcp/tls/x509/mismatch-host",
865 test_multifd_tcp_tls_x509_mismatch_host);
866 migration_test_add("/migration/multifd/tcp/tls/x509/allow-anon-client",
867 test_multifd_tcp_tls_x509_allow_anon_client);
868 migration_test_add("/migration/multifd/tcp/tls/x509/reject-anon-client",
869 test_multifd_tcp_tls_x509_reject_anon_client);
870 #endif /* CONFIG_TASN1 */
871 }
872