Return to test_child_delete.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / tests / suites |
1.1 misho 1: /* 2: * Copyright (C) 2016 Tobias Brunner 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "test_suite.h" 17: 18: #include <daemon.h> 19: #include <tests/utils/exchange_test_helper.h> 20: #include <tests/utils/exchange_test_asserts.h> 21: #include <tests/utils/job_asserts.h> 22: #include <tests/utils/sa_asserts.h> 23: 24: /** 25: * Regular CHILD_SA deletion either initiated by the original initiator or 26: * responder of the IKE_SA. 27: */ 28: START_TEST(test_regular) 29: { 30: ike_sa_t *a, *b; 31: 32: if (_i) 33: { /* responder deletes the CHILD_SA (SPI 2) */ 34: exchange_test_helper->establish_sa(exchange_test_helper, 35: &b, &a, NULL); 36: } 37: else 38: { /* initiator deletes the CHILD_SA (SPI 1) */ 39: exchange_test_helper->establish_sa(exchange_test_helper, 40: &a, &b, NULL); 41: } 42: assert_hook_not_called(child_updown); 43: call_ikesa(a, delete_child_sa, PROTO_ESP, _i+1, FALSE); 44: assert_child_sa_state(a, _i+1, CHILD_DELETING); 45: assert_hook(); 46: 47: /* INFORMATIONAL { D } --> */ 48: assert_hook_updown(child_updown, FALSE); 49: assert_single_payload(IN, PLV2_DELETE); 50: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 51: assert_child_sa_count(b, 0); 52: assert_hook(); 53: 54: /* <-- INFORMATIONAL { D } */ 55: assert_hook_updown(child_updown, FALSE); 56: assert_single_payload(IN, PLV2_DELETE); 57: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 58: assert_child_sa_count(a, 0); 59: assert_hook(); 60: 61: call_ikesa(a, destroy); 62: call_ikesa(b, destroy); 63: } 64: END_TEST 65: 66: /** 67: * Both peers initiate the CHILD_SA deletion concurrently and should handle 68: * the collision properly. 69: */ 70: START_TEST(test_collision) 71: { 72: ike_sa_t *a, *b; 73: 74: exchange_test_helper->establish_sa(exchange_test_helper, 75: &a, &b, NULL); 76: /* both peers delete the CHILD_SA concurrently */ 77: assert_hook_not_called(child_updown); 78: call_ikesa(a, delete_child_sa, PROTO_ESP, 1, FALSE); 79: assert_child_sa_state(a, 1, CHILD_DELETING); 80: call_ikesa(b, delete_child_sa, PROTO_ESP, 2, FALSE); 81: assert_child_sa_state(b, 2, CHILD_DELETING); 82: assert_hook(); 83: 84: /* RFC 7296 says: 85: * 86: * Normally, the response in the INFORMATIONAL exchange will contain 87: * Delete payloads for the paired SAs going in the other direction. 88: * There is one exception. If, by chance, both ends of a set of SAs 89: * independently decide to close them, each may send a Delete payload 90: * and the two requests may cross in the network. If a node receives a 91: * delete request for SAs for which it has already issued a delete 92: * request, it MUST delete the outgoing SAs while processing the request 93: * and the incoming SAs while processing the response. In that case, 94: * the responses MUST NOT include Delete payloads for the deleted SAs, 95: * since that would result in duplicate deletion and could in theory 96: * delete the wrong SA. 97: * 98: * We don't handle SAs separately so we expect both are still installed, 99: * but the INFORMATIONAL response should not contain a DELETE payload. 100: */ 101: 102: /* INFORMATIONAL { D } --> */ 103: assert_hook_not_called(child_updown); 104: assert_single_payload(IN, PLV2_DELETE); 105: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 106: assert_child_sa_state(b, 2, CHILD_DELETING); 107: /* <-- INFORMATIONAL { D } */ 108: assert_single_payload(IN, PLV2_DELETE); 109: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 110: assert_child_sa_state(a, 1, CHILD_DELETING); 111: assert_hook(); 112: 113: /* <-- INFORMATIONAL { } */ 114: assert_hook_updown(child_updown, FALSE); 115: assert_message_empty(IN); 116: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 117: assert_child_sa_count(a, 0); 118: assert_hook(); 119: /* INFORMATIONAL { } --> */ 120: assert_hook_updown(child_updown, FALSE); 121: assert_message_empty(IN); 122: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 123: assert_child_sa_count(b, 0); 124: assert_hook(); 125: 126: call_ikesa(a, destroy); 127: call_ikesa(b, destroy); 128: } 129: END_TEST 130: 131: /** 132: * This is like the collision above but one of the DELETEs is dropped or delayed 133: * so the other peer is not aware that there is a collision. 134: */ 135: START_TEST(test_collision_drop) 136: { 137: ike_sa_t *a, *b; 138: message_t *msg; 139: 140: exchange_test_helper->establish_sa(exchange_test_helper, 141: &a, &b, NULL); 142: /* both peers delete the CHILD_SA concurrently */ 143: assert_hook_not_called(child_updown); 144: call_ikesa(a, delete_child_sa, PROTO_ESP, 1, FALSE); 145: assert_child_sa_state(a, 1, CHILD_DELETING); 146: call_ikesa(b, delete_child_sa, PROTO_ESP, 2, FALSE); 147: assert_child_sa_state(b, 2, CHILD_DELETING); 148: assert_hook(); 149: 150: /* INFORMATIONAL { D } --> */ 151: assert_hook_not_called(child_updown); 152: assert_single_payload(IN, PLV2_DELETE); 153: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 154: assert_child_sa_state(b, 2, CHILD_DELETING); 155: assert_hook(); 156: 157: /* drop/delay the responder's message */ 158: msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender); 159: 160: /* <-- INFORMATIONAL { } */ 161: assert_hook_updown(child_updown, FALSE); 162: assert_message_empty(IN); 163: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 164: assert_child_sa_count(a, 0); 165: assert_hook(); 166: 167: /* <-- INFORMATIONAL { D } (delayed/retransmitted) */ 168: assert_hook_not_called(child_updown); 169: assert_single_payload(IN, PLV2_DELETE); 170: exchange_test_helper->process_message(exchange_test_helper, a, msg); 171: assert_hook(); 172: 173: /* INFORMATIONAL { } --> */ 174: assert_hook_updown(child_updown, FALSE); 175: assert_message_empty(IN); 176: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 177: assert_child_sa_count(b, 0); 178: assert_hook(); 179: 180: call_ikesa(a, destroy); 181: call_ikesa(b, destroy); 182: } 183: END_TEST 184: 185: /** 186: * One of the hosts initiates a rekey of the IKE_SA of the CHILD_SA the other 187: * peer is concurrently trying to delete. 188: * 189: * delete ----\ /---- rekey IKE 190: * \-----/----> detect collision 191: * detect collision <---------/ /---- delete 192: * TEMP_FAIL ----\ / 193: * \----/-----> 194: * <--------/ 195: */ 196: START_TEST(test_collision_ike_rekey) 197: { 198: ike_sa_t *a, *b; 199: uint32_t spi_a = _i+1; 200: 201: if (_i) 202: { /* responder deletes the CHILD_SA (SPI 2) */ 203: exchange_test_helper->establish_sa(exchange_test_helper, 204: &b, &a, NULL); 205: } 206: else 207: { /* initiator deletes the CHILD_SA (SPI 1) */ 208: exchange_test_helper->establish_sa(exchange_test_helper, 209: &a, &b, NULL); 210: } 211: call_ikesa(a, delete_child_sa, PROTO_ESP, spi_a, FALSE); 212: assert_child_sa_state(a, spi_a, CHILD_DELETING); 213: call_ikesa(b, rekey); 214: assert_ike_sa_state(b, IKE_REKEYING); 215: 216: /* this should never get called as there is no successful rekeying */ 217: assert_hook_not_called(ike_rekey); 218: 219: /* RFC 7296, 2.25.2: If a peer receives a request to delete a Child SA when 220: * it is currently rekeying the IKE SA, it SHOULD reply as usual, with a 221: * Delete payload. 222: */ 223: 224: /* INFORMATIONAL { D } --> */ 225: assert_hook_updown(child_updown, FALSE); 226: assert_single_payload(OUT, PLV2_DELETE); 227: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 228: assert_ike_sa_state(b, IKE_REKEYING); 229: assert_child_sa_count(b, 0); 230: assert_hook(); 231: 232: /* RFC 7296, 2.25.1: If a peer receives a request to rekey the IKE SA, and 233: * it is currently, rekeying, or closing a Child SA of that IKE SA, it 234: * SHOULD reply with TEMPORARY_FAILURE. 235: */ 236: 237: /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */ 238: assert_single_notify(OUT, TEMPORARY_FAILURE); 239: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 240: assert_child_sa_state(a, spi_a, CHILD_DELETING); 241: 242: /* <-- INFORMATIONAL { D } */ 243: assert_hook_updown(child_updown, FALSE); 244: exchange_test_helper->process_message(exchange_test_helper, a, NULL); 245: assert_child_sa_count(a, 0); 246: assert_hook(); 247: 248: /* CREATE_CHILD_SA { N(TEMP_FAIL) } --> */ 249: /* we expect a job to retry the rekeying is scheduled */ 250: assert_jobs_scheduled(1); 251: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 252: assert_ike_sa_state(b, IKE_ESTABLISHED); 253: assert_scheduler(); 254: 255: /* ike_rekey */ 256: assert_hook(); 257: 258: call_ikesa(a, destroy); 259: call_ikesa(b, destroy); 260: } 261: END_TEST 262: 263: /** 264: * One of the hosts initiates a delete of the IKE_SA of the CHILD_SA the other 265: * peer is concurrently trying to delete. 266: * 267: * delete ----\ /---- delete IKE 268: * \-----/----> detect collision 269: * <---------/ /---- delete 270: * delete ----\ / 271: * \----/-----> 272: * sa already gone <--------/ 273: */ 274: START_TEST(test_collision_ike_delete) 275: { 276: ike_sa_t *a, *b; 277: uint32_t spi_a = _i+1; 278: message_t *msg; 279: status_t s; 280: 281: if (_i) 282: { /* responder rekeys the CHILD_SA (SPI 2) */ 283: exchange_test_helper->establish_sa(exchange_test_helper, 284: &b, &a, NULL); 285: } 286: else 287: { /* initiator rekeys the CHILD_SA (SPI 1) */ 288: exchange_test_helper->establish_sa(exchange_test_helper, 289: &a, &b, NULL); 290: } 291: call_ikesa(a, delete_child_sa, PROTO_ESP, spi_a, FALSE); 292: assert_child_sa_state(a, spi_a, CHILD_DELETING); 293: call_ikesa(b, delete, FALSE); 294: assert_ike_sa_state(b, IKE_DELETING); 295: 296: /* RFC 7296, 2.25.2 does not explicitly state what the behavior SHOULD be if 297: * a peer receives a request to delete a CHILD_SA when it is currently 298: * closing the IKE SA. We expect a regular response. 299: */ 300: 301: /* INFORMATIONAL { D } --> */ 302: assert_hook_updown(child_updown, FALSE); 303: assert_single_payload(OUT, PLV2_DELETE); 304: exchange_test_helper->process_message(exchange_test_helper, b, NULL); 305: assert_ike_sa_state(b, IKE_DELETING); 306: assert_child_sa_count(b, 0); 307: assert_hook(); 308: 309: /* RFC 7296, 2.25.1 does not explicitly state what the behavior SHOULD be if 310: * a peer receives a request to close the IKE SA if it is currently deleting 311: * a Child SA of that IKE SA. Let's just close the IKE_SA and forget the 312: * delete. 313: */ 314: 315: /* <-- INFORMATIONAL { D } */ 316: assert_hook_updown(ike_updown, FALSE); 317: assert_hook_updown(child_updown, FALSE); 318: assert_message_empty(OUT); 319: s = exchange_test_helper->process_message(exchange_test_helper, a, NULL); 320: ck_assert_int_eq(DESTROY_ME, s); 321: call_ikesa(a, destroy); 322: assert_hook(); 323: assert_hook(); 324: 325: /* <-- INFORMATIONAL { D } */ 326: /* the SA is already gone */ 327: msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender); 328: msg->destroy(msg); 329: 330: /* INFORMATIONAL { } --> */ 331: assert_hook_updown(ike_updown, FALSE); 332: assert_hook_not_called(child_updown); 333: s = exchange_test_helper->process_message(exchange_test_helper, b, NULL); 334: ck_assert_int_eq(DESTROY_ME, s); 335: call_ikesa(b, destroy); 336: assert_hook(); 337: assert_hook(); 338: } 339: END_TEST 340: 341: Suite *child_delete_suite_create() 342: { 343: Suite *s; 344: TCase *tc; 345: 346: s = suite_create("child delete"); 347: 348: tc = tcase_create("regular"); 349: tcase_add_loop_test(tc, test_regular, 0, 2); 350: suite_add_tcase(s, tc); 351: 352: tc = tcase_create("collisions"); 353: tcase_add_test(tc, test_collision); 354: tcase_add_test(tc, test_collision_drop); 355: suite_add_tcase(s, tc); 356: 357: tc = tcase_create("collisions ike rekey"); 358: tcase_add_loop_test(tc, test_collision_ike_rekey, 0, 2); 359: suite_add_tcase(s, tc); 360: 361: tc = tcase_create("collisions ike delete"); 362: tcase_add_loop_test(tc, test_collision_ike_delete, 0, 2); 363: suite_add_tcase(s, tc); 364: 365: return s; 366: }