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 * 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 * 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 * 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 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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