diff options
author | Martin Willi <martin@revosec.ch> | 2013-10-11 10:15:43 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-10-11 10:15:43 +0200 |
commit | b59bcba2b38dda5f0f6301b7ae90acc58b4a069b (patch) | |
tree | 65c3cee3a20b6f323f5887b95bd88bc1981fa59c | |
parent | 4524e128f845f8842cdf9ffecf4c1978218212cb (diff) | |
parent | 5fdbb3c6ad49f992c5df7075f920a2a133a81860 (diff) | |
download | strongswan-b59bcba2b38dda5f0f6301b7ae90acc58b4a069b.tar.bz2 strongswan-b59bcba2b38dda5f0f6301b7ae90acc58b4a069b.tar.xz |
Merge branch 'ah'
Brings support for Security Associations integrity protected by the
Authentication Header protocol, both to IKEv1 and IKEv2. Currently only plain
AH is supported, but no (now deprecated) RFC2401 style AH+ESP bundles.
61 files changed, 691 insertions, 137 deletions
diff --git a/man/ipsec.conf.5.in b/man/ipsec.conf.5.in index a62d68aae..f83c45116 100644 --- a/man/ipsec.conf.5.in +++ b/man/ipsec.conf.5.in @@ -236,10 +236,44 @@ identity (such as EAP-TLS), but it does not match the IKEv2 gateway identity. .BR aggressive " = yes | " no whether to use IKEv1 Aggressive or Main Mode (the default). .TP +.BR ah " = <cipher suites>" +comma-separated list of AH algorithms to be used for the connection, e.g. +.BR sha1-sha256-modp1024 . +The notation is +.BR integrity[-dhgroup] . +For IKEv2, multiple algorithms (separated by -) of the same type can be included +in a single proposal. IKEv1 only includes the first algorithm in a proposal. +Only either the +.B ah +or +.B esp +keyword may be used, AH+ESP bundles are not supported. + +There is no default, by default ESP is used. +The daemon adds its extensive default proposal to the configured value. To +restrict it to the configured proposal an +exclamation mark +.RB ( ! ) +can be added at the end. + +If +.B dh-group +is specified, CHILD_SA/Quick Mode setup and rekeying include a separate +Diffie-Hellman exchange. +.TP .BR also " = <name>" includes conn section .BR <name> . .TP +.BR auth " = <value>" +was used by the +.B pluto +IKEv1 daemon to use AH integrity protection for ESP encrypted packets, but is +not supported in charon. The +.B ah +keyword specifies algorithms to use for integrity protection with AH, but +without encryption. AH+ESP bundles are not supported. +.TP .BR authby " = " pubkey " | rsasig | ecdsasig | psk | secret | never | xauthpsk | xauthrsasig" how the two security gateways should authenticate each other; acceptable values are @@ -368,6 +402,13 @@ for the connection, e.g. .BR aes128-sha256 . The notation is .BR encryption-integrity[-dhgroup][-esnmode] . +For IKEv2, multiple algorithms (separated by -) of the same type can be included +in a single proposal. IKEv1 only includes the first algorithm in a proposal. +Only either the +.B ah +or +.B esp +keyword may be used, AH+ESP bundles are not supported. Defaults to .BR aes128-sha1,3des-sha1 . diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in index f582e1a78..ca0398ab7 100644 --- a/src/_updown/_updown.in +++ b/src/_updown/_updown.in @@ -45,7 +45,10 @@ # is the name of the ipsec interface to be used. # # PLUTO_REQID -# is the requid of the ESP policy +# is the requid of the AH|ESP policy +# +# PLUTO_PROTO +# is the negotiated IPsec protocol, ah|esp # # PLUTO_UNIQUEID # is the unique identifier of the associated IKE_SA @@ -280,7 +283,7 @@ then IPSEC_POLICY_OUT="" else KLIPS= - IPSEC_POLICY="-m policy --pol ipsec --proto esp --reqid $PLUTO_REQID" + IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID" IPSEC_POLICY_IN="$IPSEC_POLICY --dir in" IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out" fi diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index 0b702e014..0acc425d6 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -429,30 +429,33 @@ static void check_proposal(private_proposal_t *this) e->destroy(e); } - e = create_enumerator(this, ENCRYPTION_ALGORITHM); - while (e->enumerate(e, &alg, &ks)) + if (this->protocol == PROTO_ESP) { - if (!encryption_algorithm_is_aead(alg)) + e = create_enumerator(this, ENCRYPTION_ALGORITHM); + while (e->enumerate(e, &alg, &ks)) { - all_aead = FALSE; - break; + if (!encryption_algorithm_is_aead(alg)) + { + all_aead = FALSE; + break; + } } - } - e->destroy(e); + e->destroy(e); - if (all_aead) - { - /* if all encryption algorithms in the proposal are AEADs, - * we MUST NOT propose any integrity algorithms */ - e = array_create_enumerator(this->transforms); - while (e->enumerate(e, &entry)) + if (all_aead) { - if (entry->type == INTEGRITY_ALGORITHM) + /* if all encryption algorithms in the proposal are AEADs, + * we MUST NOT propose any integrity algorithms */ + e = array_create_enumerator(this->transforms); + while (e->enumerate(e, &entry)) { - array_remove_at(this->transforms, e); + if (entry->type == INTEGRITY_ALGORITHM) + { + array_remove_at(this->transforms, e); + } } + e->destroy(e); } - e->destroy(e); } if (this->protocol == PROTO_AH || this->protocol == PROTO_ESP) diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 3896d7199..9fc108b40 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -439,7 +439,7 @@ static payload_rule_t id_prot_i_rules[] = { {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, TRUE, FALSE}, - {CERTIFICATE_V1, 0, 2, TRUE, FALSE}, + {CERTIFICATE_V1, 0, MAX_CERT_PAYLOADS, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE}, {HASH_V1, 0, 1, TRUE, FALSE}, {FRAGMENT_V1, 0, 1, FALSE, TRUE}, @@ -479,7 +479,7 @@ static payload_rule_t id_prot_r_rules[] = { {NAT_D_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {NAT_D_DRAFT_00_03_V1, 0, MAX_NAT_D_PAYLOADS, FALSE, FALSE}, {ID_V1, 0, 1, TRUE, FALSE}, - {CERTIFICATE_V1, 0, 2, TRUE, FALSE}, + {CERTIFICATE_V1, 0, MAX_CERT_PAYLOADS, TRUE, FALSE}, {SIGNATURE_V1, 0, 1, TRUE, FALSE}, {HASH_V1, 0, 1, TRUE, FALSE}, {FRAGMENT_V1, 0, 1, FALSE, TRUE}, diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index 3cf22aefd..cb9b359b3 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -246,6 +246,24 @@ typedef enum { } ikev1_esp_auth_transid_it; /** + * IKEv1 Transform ID AH authentication algorithm. + */ +typedef enum { + IKEV1_AH_HMAC_MD5 = 2, + IKEV1_AH_HMAC_SHA = 3, + IKEV1_AH_DES_MAC = 4, + IKEV1_AH_HMAC_SHA2_256 = 5, + IKEV1_AH_HMAC_SHA2_384 = 6, + IKEV1_AH_HMAC_SHA2_512 = 7, + IKEV1_AH_RIPEMD = 8, + IKEV1_AH_AES_XCBC_MAC = 9, + IKEV1_AH_RSA = 10, + IKEV1_AH_AES_128_GMAC = 11, + IKEV1_AH_AES_192_GMAC = 12, + IKEV1_AH_AES_256_GMAC = 13, +} ikev1_ah_transid_t; + +/** * IKEv1 ESP Encapsulation mode. */ typedef enum { @@ -637,6 +655,22 @@ static algo_map_t map_esp_auth[] = { }; /** + * AH authentication algorithm mapping + */ +static algo_map_t map_ah[] = { + { IKEV1_AH_HMAC_MD5, AUTH_HMAC_MD5_96 }, + { IKEV1_AH_HMAC_SHA, AUTH_HMAC_SHA1_96 }, + { IKEV1_AH_DES_MAC, AUTH_DES_MAC }, + { IKEV1_AH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 }, + { IKEV1_AH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 }, + { IKEV1_AH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 }, + { IKEV1_AH_AES_XCBC_MAC, AUTH_AES_XCBC_96 }, + { IKEV1_AH_AES_128_GMAC, AUTH_AES_128_GMAC }, + { IKEV1_AH_AES_192_GMAC, AUTH_AES_192_GMAC }, + { IKEV1_AH_AES_256_GMAC, AUTH_AES_256_GMAC }, +}; + +/** * Get IKEv2 algorithm from IKEv1 identifier */ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value) @@ -713,7 +747,8 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value) /** * Get IKEv2 algorithm from IKEv1 ESP transaction ID */ -static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t value) +static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto, + transform_type_t type, u_int16_t value) { algo_map_t *map; u_int16_t def; @@ -727,8 +762,16 @@ static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t val def = ENCR_UNDEFINED; break; case INTEGRITY_ALGORITHM: - map = map_esp_auth; - count = countof(map_esp_auth); + if (proto == PROTO_ESP) + { + map = map_esp_auth; + count = countof(map_esp_auth); + } + else + { + map = map_ah; + count = countof(map_ah); + } def = AUTH_UNDEFINED; break; default: @@ -745,9 +788,10 @@ static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t val } /** - * Get IKEv1 ESP transaction ID from IKEv2 identifier + * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier */ -static u_int16_t get_ikev1_transid_from_alg(transform_type_t type, u_int16_t value) +static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto, + transform_type_t type, u_int16_t value) { algo_map_t *map; int i, count; @@ -759,8 +803,16 @@ static u_int16_t get_ikev1_transid_from_alg(transform_type_t type, u_int16_t val count = countof(map_esp_encr); break; case INTEGRITY_ALGORITHM: - map = map_esp_auth; - count = countof(map_esp_auth); + if (proto == PROTO_ESP) + { + map = map_esp_auth; + count = countof(map_esp_auth); + } + else + { + map = map_ah; + count = countof(map_ah); + } break; default: return 0; @@ -889,10 +941,10 @@ static void add_to_proposal_v1_ike(proposal_t *proposal, } /** - * Add an ESP transform to a proposal for IKEv1 + * Add an ESP/AH transform to a proposal for IKEv1 */ -static void add_to_proposal_v1_esp(proposal_t *proposal, - transform_substructure_t *transform) +static void add_to_proposal_v1(proposal_t *proposal, + transform_substructure_t *transform, protocol_id_t proto) { transform_attribute_type_t type; transform_attribute_t *tattr; @@ -911,7 +963,7 @@ static void add_to_proposal_v1_esp(proposal_t *proposal, break; case TATTR_PH2_AUTH_ALGORITHM: proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, - get_alg_from_ikev1_transid(INTEGRITY_ALGORITHM, + get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM, value), 0); break; case TATTR_PH2_GROUP: @@ -927,12 +979,15 @@ static void add_to_proposal_v1_esp(proposal_t *proposal, /* TODO-IKEv1: handle ESN attribute */ proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM, - transform->get_transform_id(transform)); - if (encr) + if (proto == PROTO_ESP) { - proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, - key_length); + encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM, + transform->get_transform_id(transform)); + if (encr) + { + proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, + key_length); + } } } @@ -977,7 +1032,8 @@ METHOD(proposal_substructure_t, get_proposals, void, add_to_proposal_v1_ike(proposal, transform); break; case PROTO_ESP: - add_to_proposal_v1_esp(proposal, transform); + case PROTO_AH: + add_to_proposal_v1(proposal, transform, this->protocol_id); break; default: break; @@ -1072,6 +1128,7 @@ METHOD(proposal_substructure_t, get_lifetime, u_int32_t, return get_life_duration(this, TATTR_PH1_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS, TATTR_PH1_LIFE_DURATION); case PROTO_ESP: + case PROTO_AH: duration = get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS, TATTR_PH2_SA_LIFE_DURATION); if (!duration) @@ -1090,6 +1147,7 @@ METHOD(proposal_substructure_t, get_lifebytes, u_int64_t, switch (this->protocol_id) { case PROTO_ESP: + case PROTO_AH: return 1000 * get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES, TATTR_PH2_SA_LIFE_DURATION); case PROTO_IKE: @@ -1281,24 +1339,26 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this, } /** - * Add an IKEv1 ESP proposal to the substructure + * Add an IKEv1 ESP/AH proposal to the substructure */ -static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, +static void set_from_proposal_v1(private_proposal_substructure_t *this, proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, ipsec_mode_t mode, encap_t udp, int number) { transform_substructure_t *transform = NULL; u_int16_t alg, key_size; enumerator_t *enumerator; + protocol_id_t proto; + proto = proposal->get_protocol(proposal); enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg); + alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg); if (alg) { - transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1, - number, alg); + transform = transform_substructure_create_type( + TRANSFORM_SUBSTRUCTURE_V1, number, alg); if (key_size) { transform->add_transform_attribute(transform, @@ -1308,17 +1368,18 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, } } enumerator->destroy(enumerator); - if (!transform) - { - return; - } enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg); + alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg); if (alg) { + if (!transform) + { + transform = transform_substructure_create_type( + TRANSFORM_SUBSTRUCTURE_V1, number, alg); + } transform->add_transform_attribute(transform, transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1, TATTR_PH2_AUTH_ALGORITHM, alg)); @@ -1326,6 +1387,11 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, } enumerator->destroy(enumerator); + if (!transform) + { + return; + } + enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP); if (enumerator->enumerate(enumerator, &alg, &key_size)) { @@ -1493,8 +1559,9 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( set_from_proposal_v1_ike(this, proposal, lifetime, auth, 1); break; case PROTO_ESP: - set_from_proposal_v1_esp(this, proposal, lifetime, - lifebytes, mode, udp, 1); + case PROTO_AH: + set_from_proposal_v1(this, proposal, lifetime, + lifebytes, mode, udp, 1); break; default: break; @@ -1535,8 +1602,9 @@ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( auth, ++number); break; case PROTO_ESP: - set_from_proposal_v1_esp(this, proposal, lifetime, - lifebytes, mode, udp, ++number); + case PROTO_AH: + set_from_proposal_v1(this, proposal, lifetime, + lifebytes, mode, udp, ++number); break; default: break; diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index 613412014..3a5bb43a6 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -341,10 +341,10 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, { int current_proposal = -1, unsupported_proposal = -1; enumerator_t *enumerator; - proposal_substructure_t *substruct, *esp = NULL, *ipcomp = NULL; + proposal_substructure_t *substruct, *espah = NULL, *ipcomp = NULL; linked_list_t *list; - /* we currently only support the combination ESP+IPComp, find the first */ + /* we currently only support the combination ESP|AH+IPComp, find the first */ enumerator = this->proposals->create_enumerator(this->proposals); while (enumerator->enumerate(enumerator, &substruct)) { @@ -355,25 +355,27 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, { continue; } - if (protocol_id != PROTO_ESP && protocol_id != PROTO_IPCOMP) + if (protocol_id != PROTO_ESP && protocol_id != PROTO_AH && + protocol_id != PROTO_IPCOMP) { /* unsupported combination */ - esp = ipcomp = NULL; + espah = ipcomp = NULL; unsupported_proposal = current_proposal; continue; } if (proposal_number != current_proposal) { /* start of a new proposal */ - if (esp && ipcomp) + if (espah && ipcomp) { /* previous proposal is valid */ break; } - esp = ipcomp = NULL; + espah = ipcomp = NULL; current_proposal = proposal_number; } switch (protocol_id) { case PROTO_ESP: - esp = substruct; + case PROTO_AH: + espah = substruct; break; case PROTO_IPCOMP: ipcomp = substruct; @@ -383,9 +385,9 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, enumerator->destroy(enumerator); list = linked_list_create(); - if (esp && ipcomp && ipcomp->get_cpi(ipcomp, cpi)) + if (espah && ipcomp && ipcomp->get_cpi(ipcomp, cpi)) { - esp->get_proposals(esp, list); + espah->get_proposals(espah, list); } return list; } diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index aa5c4e059..059124e35 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -35,7 +35,6 @@ struct private_kernel_handler_t { * Public part of kernel_handler_t object. */ kernel_handler_t public; - }; /** @@ -55,85 +54,83 @@ static inline protocol_id_t proto_ip2ike(u_int8_t protocol) } METHOD(kernel_listener_t, acquire, bool, - private_kernel_handler_t *this, u_int32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + private_kernel_handler_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts) { - job_t *job; if (src_ts && dst_ts) { - DBG1(DBG_KNL, "creating acquire job for policy %R === %R " - "with reqid {%u}", src_ts, dst_ts, reqid); + DBG1(DBG_KNL, "creating acquire job for policy %R === %R with " + "reqid {%u}", src_ts, dst_ts, reqid); } else { DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid); } - job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); - lib->processor->queue_job(lib->processor, job); + lib->processor->queue_job(lib->processor, + (job_t*)acquire_job_create(reqid, src_ts, dst_ts)); return TRUE; } METHOD(kernel_listener_t, expire, bool, - private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol, - u_int32_t spi, bool hard) + private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol, + u_int32_t spi, bool hard) { - job_t *job; protocol_id_t proto = proto_ip2ike(protocol); - DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x " - "and reqid {%u}", hard ? "delete" : "rekey", - protocol_id_names, proto, ntohl(spi), reqid); + + DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}", + hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid); + if (hard) { - job = (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard); + lib->processor->queue_job(lib->processor, + (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard)); } else { - job = (job_t*)rekey_child_sa_job_create(reqid, proto, spi); + lib->processor->queue_job(lib->processor, + (job_t*)rekey_child_sa_job_create(reqid, proto, spi)); } - lib->processor->queue_job(lib->processor, job); return TRUE; } METHOD(kernel_listener_t, mapping, bool, - private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi, - host_t *remote) + private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi, + host_t *remote) { - job_t *job; - DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and " - "reqid {%u} changed, queuing update job", ntohl(spi), reqid); - job = (job_t*)update_sa_job_create(reqid, remote); - lib->processor->queue_job(lib->processor, job); + DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and reqid {%u} " + "changed, queuing update job", ntohl(spi), reqid); + + lib->processor->queue_job(lib->processor, + (job_t*)update_sa_job_create(reqid, remote)); return TRUE; } METHOD(kernel_listener_t, migrate, bool, - private_kernel_handler_t *this, u_int32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, host_t *local, host_t *remote) + private_kernel_handler_t *this, u_int32_t reqid, + traffic_selector_t *src_ts, traffic_selector_t *dst_ts, + policy_dir_t direction, host_t *local, host_t *remote) { - job_t *job; - DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with " - "reqid {%u}", src_ts, dst_ts, policy_dir_names, direction, - reqid, local); - job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, direction, local, - remote); - lib->processor->queue_job(lib->processor, job); + DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}", + src_ts, dst_ts, policy_dir_names, direction, reqid, local); + + lib->processor->queue_job(lib->processor, + (job_t*)migrate_job_create(reqid, src_ts, dst_ts, + direction, local, remote)); return TRUE; } METHOD(kernel_listener_t, roam, bool, - private_kernel_handler_t *this, bool address) + private_kernel_handler_t *this, bool address) { - job_t *job; - DBG2(DBG_KNL, "creating roam job %s", address ? "due to address/link change" - : "due to route change"); - job = (job_t*)roam_job_create(address); - lib->processor->queue_job(lib->processor, job); + DBG2(DBG_KNL, "creating roam job %s", + address ? "due to address/link change" : "due to route change"); + + lib->processor->queue_job(lib->processor, (job_t*)roam_job_create(address)); return TRUE; } METHOD(kernel_handler_t, destroy, void, - private_kernel_handler_t *this) + private_kernel_handler_t *this) { hydra->kernel_interface->remove_listener(hydra->kernel_interface, &this->public.listener); @@ -162,4 +159,3 @@ kernel_handler_t *kernel_handler_create() return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index edfa8a9c3..2e10f324b 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -131,19 +131,14 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*, * parse a proposal string, either into ike_cfg or child_cfg */ static void add_proposals(private_stroke_config_t *this, char *string, - ike_cfg_t *ike_cfg, child_cfg_t *child_cfg) + ike_cfg_t *ike_cfg, child_cfg_t *child_cfg, protocol_id_t proto) { if (string) { char *single; char *strict; proposal_t *proposal; - protocol_id_t proto = PROTO_ESP; - if (ike_cfg) - { - proto = PROTO_IKE; - } strict = string + strlen(string) - 1; if (*strict == '!') { @@ -178,11 +173,11 @@ static void add_proposals(private_stroke_config_t *this, char *string, } if (ike_cfg) { - ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); + ike_cfg->add_proposal(ike_cfg, proposal_create_default(proto)); } else { - child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); + child_cfg->add_proposal(child_cfg, proposal_create_default(proto)); } } @@ -270,7 +265,7 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg msg->add_conn.fragmentation, msg->add_conn.ikedscp); - add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL); + add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL, PROTO_IKE); return ike_cfg; } @@ -1159,8 +1154,16 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this, add_ts(this, &msg->add_conn.me, child_cfg, TRUE); add_ts(this, &msg->add_conn.other, child_cfg, FALSE); - add_proposals(this, msg->add_conn.algorithms.esp, NULL, child_cfg); - + if (msg->add_conn.algorithms.ah) + { + add_proposals(this, msg->add_conn.algorithms.ah, + NULL, child_cfg, PROTO_AH); + } + else + { + add_proposals(this, msg->add_conn.algorithms.esp, + NULL, child_cfg, PROTO_ESP); + } return child_cfg; } diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index a5825519b..ea168058f 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -245,6 +245,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED; u_int16_t encr_size = 0, int_size = 0; u_int16_t esn = NO_EXT_SEQ_NUMBERS; + bool first = TRUE; proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &encr_alg, &encr_size); @@ -256,6 +257,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) if (encr_alg != ENCR_UNDEFINED) { fprintf(out, "%N", encryption_algorithm_names, encr_alg); + first = FALSE; if (encr_size) { fprintf(out, "_%u", encr_size); @@ -263,7 +265,11 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } if (int_alg != AUTH_UNDEFINED) { - fprintf(out, "/%N", integrity_algorithm_names, int_alg); + if (!first) + { + fprintf(out, "/"); + } + fprintf(out, "%N", integrity_algorithm_names, int_alg); if (int_size) { fprintf(out, "_%u", int_size); diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 88f73f3b0..3adebb523 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -186,6 +186,7 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) pop_string(msg, &msg->add_conn.xauth_identity); pop_string(msg, &msg->add_conn.algorithms.ike); pop_string(msg, &msg->add_conn.algorithms.esp); + pop_string(msg, &msg->add_conn.algorithms.ah); pop_string(msg, &msg->add_conn.ikeme.mediated_by); pop_string(msg, &msg->add_conn.ikeme.peerid); DBG2(DBG_CFG, " eap_identity=%s", msg->add_conn.eap_identity); @@ -193,6 +194,7 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) DBG2(DBG_CFG, " xauth_identity=%s", msg->add_conn.xauth_identity); DBG2(DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike); DBG2(DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp); + DBG2(DBG_CFG, " ah=%s", msg->add_conn.algorithms.ah); DBG2(DBG_CFG, " dpddelay=%d", msg->add_conn.dpd.delay); DBG2(DBG_CFG, " dpdtimeout=%d", msg->add_conn.dpd.timeout); DBG2(DBG_CFG, " dpdaction=%d", msg->add_conn.dpd.action); diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 0268c88f3..3c3994b81 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -311,6 +311,7 @@ METHOD(listener_t, child_updown, bool, "PLUTO_CONNECTION='%s' " "PLUTO_INTERFACE='%s' " "PLUTO_REQID='%u' " + "PLUTO_PROTO='%s' " "PLUTO_UNIQUEID='%u' " "PLUTO_ME='%H' " "PLUTO_MY_ID='%Y' " @@ -336,6 +337,7 @@ METHOD(listener_t, child_updown, bool, config->get_name(config), iface ? iface : "unknown", child_sa->get_reqid(child_sa), + child_sa->get_protocol(child_sa) == PROTO_ESP ? "esp" : "ah", ike_sa->get_unique_id(ike_sa), me, ike_sa->get_my_id(ike_sa), my_client, my_client_mask, diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 46e4b6f7b..9bd0c05ad 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -594,6 +594,9 @@ METHOD(child_sa_t, alloc_spi, u_int32_t, proto_ike2ip(protocol), this->reqid, &this->my_spi) == SUCCESS) { + /* if we allocate a SPI, but then are unable to establish the SA, we + * need to know the protocol family to delete the partial SA */ + this->protocol = protocol; return this->my_spi; } return 0; @@ -1039,12 +1042,6 @@ METHOD(child_sa_t, destroy, void, /* delete SAs in the kernel, if they are set up */ if (this->my_spi) { - /* if CHILD was not established, use PROTO_ESP used during alloc_spi(). - * TODO: For AH support, we have to store protocol specific SPI.s */ - if (this->protocol == PROTO_NONE) - { - this->protocol = PROTO_ESP; - } hydra->kernel_interface->del_sa(hydra->kernel_interface, this->other_addr, this->my_addr, this->my_spi, proto_ike2ip(this->protocol), this->my_cpi, diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index 1a2cdb777..605c10cea 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -177,7 +177,7 @@ METHOD(task_t, build_i, status_t, DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x", protocol_id_names, this->protocol, ntohl(this->spi)); - delete_payload = delete_payload_create(DELETE_V1, PROTO_ESP); + delete_payload = delete_payload_create(DELETE_V1, this->protocol); delete_payload->add_spi(delete_payload, this->spi); message->add_payload(message, &delete_payload->payload_interface); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 925b1c617..12ee594b9 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -165,6 +165,11 @@ struct private_quick_mode_t { */ ipsec_mode_t mode; + /* + * SA protocol (ESP|AH) negotiated + */ + protocol_id_t proto; + /** * Use UDP encapsulation */ @@ -722,7 +727,7 @@ static status_t send_notify(private_quick_mode_t *this, notify_type_t type) notify_payload_t *notify; notify = notify_payload_create_from_protocol_and_type(NOTIFY_V1, - PROTO_ESP, type); + this->proto, type); notify->set_spi(notify, this->spi_i); this->ike_sa->queue_task(this->ike_sa, @@ -774,6 +779,7 @@ METHOD(task_t, build_i, status_t, { sa_payload_t *sa_payload; linked_list_t *list, *tsi, *tsr; + proposal_t *proposal; diffie_hellman_group_t group; encap_t encap; @@ -800,12 +806,19 @@ METHOD(task_t, build_i, status_t, } } - this->spi_i = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP); + list = this->config->get_proposals(this->config, MODP_NONE); + if (list->get_first(list, (void**)&proposal) == SUCCESS) + { + this->proto = proposal->get_protocol(proposal); + } + list->destroy_offset(list, offsetof(proposal_t, destroy)); + this->spi_i = this->child_sa->alloc_spi(this->child_sa, this->proto); if (!this->spi_i) { DBG1(DBG_IKE, "allocating SPI from kernel failed"); return FAILED; } + group = this->config->get_dh_group(this->config); if (group != MODP_NONE) { @@ -1139,7 +1152,8 @@ METHOD(task_t, build_r, status_t, sa_payload_t *sa_payload; encap_t encap; - this->spi_r = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP); + this->proto = this->proposal->get_protocol(this->proposal); + this->spi_r = this->child_sa->alloc_spi(this->child_sa, this->proto); if (!this->spi_r) { DBG1(DBG_IKE, "allocating SPI from kernel failed"); @@ -1347,6 +1361,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, .state = QM_INIT, .tsi = tsi ? tsi->clone(tsi) : NULL, .tsr = tsr ? tsr->clone(tsr) : NULL, + .proto = PROTO_ESP, ); if (config) diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 8ae36af84..7cfa537a9 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -244,9 +244,23 @@ static bool allocate_spi(private_child_create_t *this) { enumerator_t *enumerator; proposal_t *proposal; + protocol_id_t proto = PROTO_ESP; - /* TODO: allocate additional SPI for AH if we have such proposals */ - this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP); + if (this->initiator) + { + /* we just get a SPI for the first protocol. TODO: If we ever support + * proposal lists with mixed protocols, we'd need multiple SPIs */ + if (this->proposals->get_first(this->proposals, + (void**)&proposal) == SUCCESS) + { + proto = proposal->get_protocol(proposal); + } + } + else + { + proto = this->proposal->get_protocol(this->proposal); + } + this->my_spi = this->child_sa->alloc_spi(this->child_sa, proto); if (this->my_spi) { if (this->initiator) diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c index 26c305f77..d1f6a1bdc 100644 --- a/src/libcharon/sa/keymat.c +++ b/src/libcharon/sa/keymat.c @@ -93,6 +93,7 @@ int keymat_get_keylen_integ(integrity_algorithm_t alg) {AUTH_HMAC_SHA2_384_192, 384}, {AUTH_HMAC_SHA2_512_256, 512}, {AUTH_AES_XCBC_96, 128}, + {AUTH_AES_CMAC_96, 128}, }; int i; diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 0d5c10d59..5a4c06c2d 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -102,6 +102,9 @@ METHOD(trap_manager_t, install, u_int32_t, linked_list_t *my_ts, *other_ts, *list; enumerator_t *enumerator; status_t status; + linked_list_t *proposals; + proposal_t *proposal; + protocol_id_t proto = PROTO_ESP; /* try to resolve addresses */ ike_cfg = peer->get_ike_cfg(peer); @@ -160,10 +163,15 @@ METHOD(trap_manager_t, install, u_int32_t, other_ts = child->get_traffic_selectors(child, FALSE, NULL, list); list->destroy_offset(list, offsetof(host_t, destroy)); - /* while we don't know the finally negotiated protocol (ESP|AH), we - * could iterate all proposals for a best guess (TODO). But as we - * support ESP only for now, we set it here. */ - child_sa->set_protocol(child_sa, PROTO_ESP); + /* We don't know the finally negotiated protocol (ESP|AH), we install + * the SA with the protocol of the first proposal */ + proposals = child->get_proposals(child, TRUE); + if (proposals->get_first(proposals, (void**)&proposal) == SUCCESS) + { + proto = proposal->get_protocol(proposal); + } + proposals->destroy_offset(proposals, offsetof(proposal_t, destroy)); + child_sa->set_protocol(child_sa, proto); child_sa->set_mode(child_sa, child->get_mode(child)); status = child_sa->add_policies(child_sa, my_ts, other_ts); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); diff --git a/src/starter/args.c b/src/starter/args.c index 5fbf51856..f5a617eaa 100644 --- a/src/starter/args.c +++ b/src/starter/args.c @@ -140,7 +140,6 @@ static const token_info_t token_info[] = { ARG_MISC, 0, NULL /* KW_COMPRESS */ }, { ARG_ENUM, offsetof(starter_conn_t, install_policy), LST_bool }, { ARG_ENUM, offsetof(starter_conn_t, aggressive), LST_bool }, - { ARG_MISC, 0, NULL /* KW_AUTH */ }, { ARG_STR, offsetof(starter_conn_t, authby), LST_authby }, { ARG_STR, offsetof(starter_conn_t, eap_identity), NULL }, { ARG_STR, offsetof(starter_conn_t, aaa_identity), NULL }, @@ -161,6 +160,7 @@ static const token_info_t token_info[] = { ARG_MISC, 0, NULL /* KW_REAUTH */ }, { ARG_STR, offsetof(starter_conn_t, ike), NULL }, { ARG_STR, offsetof(starter_conn_t, esp), NULL }, + { ARG_STR, offsetof(starter_conn_t, ah), NULL }, { ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL }, { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL }, { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action }, @@ -295,6 +295,15 @@ bool assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw, char *base, return FALSE; } + if (token == KW_ESP || token == KW_AH) + { + if (*seen & (SEEN_KW(KW_ESP, first) | SEEN_KW(KW_AH, first))) + { + DBG1(DBG_APP, "# can't have both 'ah' and 'esp' options"); + return FALSE; + } + } + /* set flag that this argument has been seen */ *seen |= SEEN_KW(token, first); diff --git a/src/starter/confread.c b/src/starter/confread.c index 2fb022692..cec9399e3 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -521,9 +521,6 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg case KW_COMPRESS: KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS) break; - case KW_AUTH: - KW_SA_OPTION_FLAG("ah", "esp", SA_OPTION_AUTHENTICATE) - break; case KW_MARK: if (!handle_mark(kw->value, &conn->mark_in)) { diff --git a/src/starter/confread.h b/src/starter/confread.h index 0690bed4e..d55a17e63 100644 --- a/src/starter/confread.h +++ b/src/starter/confread.h @@ -78,7 +78,6 @@ typedef enum { typedef enum { /* IPsec options */ - SA_OPTION_AUTHENTICATE = 1 << 0, /* use AH instead of ESP? */ SA_OPTION_COMPRESS = 1 << 1, /* use IPComp */ /* IKE and other other options */ @@ -171,6 +170,7 @@ struct starter_conn { unsigned long id; char *esp; + char *ah; char *ike; time_t dpd_delay; diff --git a/src/starter/keywords.h b/src/starter/keywords.h index 83ce4a7dd..705a7c16e 100644 --- a/src/starter/keywords.h +++ b/src/starter/keywords.h @@ -36,7 +36,6 @@ typedef enum { KW_COMPRESS, KW_INSTALLPOLICY, KW_AGGRESSIVE, - KW_AUTH, KW_AUTHBY, KW_EAP_IDENTITY, KW_AAA_IDENTITY, @@ -57,6 +56,7 @@ typedef enum { KW_REAUTH, KW_IKE, KW_ESP, + KW_AH, KW_DPDDELAY, KW_DPDTIMEOUT, KW_DPDACTION, diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt index 20d35ded0..ad915bf2a 100644 --- a/src/starter/keywords.txt +++ b/src/starter/keywords.txt @@ -34,7 +34,6 @@ type, KW_TYPE compress, KW_COMPRESS installpolicy, KW_INSTALLPOLICY aggressive, KW_AGGRESSIVE -auth, KW_AUTH authby, KW_AUTHBY eap_identity, KW_EAP_IDENTITY aaa_identity, KW_AAA_IDENTITY @@ -57,6 +56,7 @@ rekey, KW_REKEY reauth, KW_REAUTH ike, KW_IKE esp, KW_ESP +ah, KW_AH dpddelay, KW_DPDDELAY dpdtimeout, KW_DPDTIMEOUT dpdaction, KW_DPDACTION diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index bf7e0284f..fca4b1e7d 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -192,6 +192,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn) msg.add_conn.unique = cfg->setup.uniqueids; msg.add_conn.algorithms.ike = push_string(&msg, conn->ike); msg.add_conn.algorithms.esp = push_string(&msg, conn->esp); + msg.add_conn.algorithms.ah = push_string(&msg, conn->ah); msg.add_conn.dpd.delay = conn->dpd_delay; msg.add_conn.dpd.timeout = conn->dpd_timeout; msg.add_conn.dpd.action = conn->dpd_action; diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index 6c8dcf5f9..5ece7248b 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -275,6 +275,7 @@ struct stroke_msg_t { struct { char *ike; char *esp; + char *ah; } algorithms; struct { int reauth; diff --git a/testing/hosts/default/etc/iptables.rules b/testing/hosts/default/etc/iptables.rules index c3f036cf9..b69e1429e 100644 --- a/testing/hosts/default/etc/iptables.rules +++ b/testing/hosts/default/etc/iptables.rules @@ -9,6 +9,10 @@ -A INPUT -i eth0 -p 50 -j ACCEPT -A OUTPUT -o eth0 -p 50 -j ACCEPT +# allow ah +-A INPUT -i eth0 -p 51 -j ACCEPT +-A OUTPUT -o eth0 -p 51 -j ACCEPT + # allow IKE -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT diff --git a/testing/tests/ikev1/host2host-ah/description.txt b/testing/tests/ikev1/host2host-ah/description.txt new file mode 100644 index 000000000..dccdd52a4 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/description.txt @@ -0,0 +1,5 @@ +An IPsec <b>AH transport-mode</b> connection using HMAC_SHA256 between the hosts +<b>moon</b> and <b>sun</b> is successfully set up using IKEv1. <b>leftfirewall=yes</b> +automatically inserts iptables-based firewall rules that let pass the decrypted +IP packets. In order to test the host-to-host connection <b>moon</b> pings +<b>sun</b>. diff --git a/testing/tests/ikev1/host2host-ah/evaltest.dat b/testing/tests/ikev1/host2host-ah/evaltest.dat new file mode 100644 index 000000000..92695477a --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/evaltest.dat @@ -0,0 +1,7 @@ +moon::ipsec status 2> /dev/null::host-host.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES +sun:: ipsec status 2> /dev/null::host-host.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES +moon::ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES +sun:: ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES +moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: AH::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: AH::YES diff --git a/testing/tests/ikev1/host2host-ah/hosts/moon/etc/ipsec.conf b/testing/tests/ikev1/host2host-ah/hosts/moon/etc/ipsec.conf new file mode 100644 index 000000000..a05e5d040 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/hosts/moon/etc/ipsec.conf @@ -0,0 +1,17 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + +conn %default + keyexchange=ikev1 + +conn host-host + left=PH_IP_MOON + leftcert=moonCert.pem + leftid=@moon.strongswan.org + leftfirewall=yes + right=PH_IP_SUN + rightid=@sun.strongswan.org + type=transport + ah=sha256! + auto=add diff --git a/testing/tests/ikev1/host2host-ah/hosts/moon/etc/strongswan.conf b/testing/tests/ikev1/host2host-ah/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/hosts/moon/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev1/host2host-ah/hosts/sun/etc/ipsec.conf b/testing/tests/ikev1/host2host-ah/hosts/sun/etc/ipsec.conf new file mode 100644 index 000000000..6851ffb5c --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/hosts/sun/etc/ipsec.conf @@ -0,0 +1,17 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + +conn %default + keyexchange=ikev1 + +conn host-host + left=PH_IP_SUN + leftcert=sunCert.pem + leftid=@sun.strongswan.org + leftfirewall=yes + right=PH_IP_MOON + rightid=@moon.strongswan.org + type=transport + ah=sha256! + auto=add diff --git a/testing/tests/ikev1/host2host-ah/hosts/sun/etc/strongswan.conf b/testing/tests/ikev1/host2host-ah/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/hosts/sun/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev1/host2host-ah/posttest.dat b/testing/tests/ikev1/host2host-ah/posttest.dat new file mode 100644 index 000000000..1f7aa73a1 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/posttest.dat @@ -0,0 +1,4 @@ +moon::ipsec stop +sun::ipsec stop +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush diff --git a/testing/tests/ikev1/host2host-ah/pretest.dat b/testing/tests/ikev1/host2host-ah/pretest.dat new file mode 100644 index 000000000..99789b90f --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/pretest.dat @@ -0,0 +1,6 @@ +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::ipsec start +sun::ipsec start +moon::sleep 2 +moon::ipsec up host-host diff --git a/testing/tests/ikev1/host2host-ah/test.conf b/testing/tests/ikev1/host2host-ah/test.conf new file mode 100644 index 000000000..9647dc6a2 --- /dev/null +++ b/testing/tests/ikev1/host2host-ah/test.conf @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="moon winnetou sun" + +# Corresponding block diagram +# +DIAGRAM="m-w-s.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="sun" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon sun" diff --git a/testing/tests/ikev1/net2net-ah/description.txt b/testing/tests/ikev1/net2net-ah/description.txt new file mode 100644 index 000000000..7ced7a551 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/description.txt @@ -0,0 +1,8 @@ +A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> +is set up using the IKEv1 protocol. +With <b>ah=md5,sha1</b> gateway <b>moon</b> proposes the use of an +<b>AH proposal</b>. Gateway <b>sun</b> selects SHA1 for integrity protection +with its <b>ah=sha1!</b> configuration. +<p/> +Upon the successful establishment of the AH CHILD SA, client <b>alice</b> behind +gateway <b>moon</b> pings client <b>bob</b> located behind gateway <b>sun</b>. diff --git a/testing/tests/ikev1/net2net-ah/evaltest.dat b/testing/tests/ikev1/net2net-ah/evaltest.dat new file mode 100644 index 000000000..bf6234b55 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/evaltest.dat @@ -0,0 +1,11 @@ +sun:: cat /var/log/daemon.log::received proposals: AH:HMAC_MD5_96/NO_EXT_SEQ, AH:HMAC_SHA1_96/NO_EXT_SEQ::YES +sun:: cat /var/log/daemon.log::selected proposal: AH:HMAC_SHA1_96/NO_EXT_SEQ::YES +moon:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES +sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES +moon:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES +sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES +alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: AH::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: AH::YES +moon::ipsec statusall 2> /dev/null::HMAC_SHA1_96::YES +sun:: ipsec statusall 2> /dev/null::HMAC_SHA1_96::YES diff --git a/testing/tests/ikev1/net2net-ah/hosts/moon/etc/ipsec.conf b/testing/tests/ikev1/net2net-ah/hosts/moon/etc/ipsec.conf new file mode 100644 index 000000000..d062dfe57 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/hosts/moon/etc/ipsec.conf @@ -0,0 +1,20 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + charondebug="cfg 2, knl 3" + +conn %default + keyexchange=ikev1 + ike=aes128-sha1-modp1536! + ah=md5,sha1 + +conn net-net + left=PH_IP_MOON + leftcert=moonCert.pem + leftid=@moon.strongswan.org + leftsubnet=10.1.0.0/16 + leftfirewall=yes + right=PH_IP_SUN + rightid=@sun.strongswan.org + rightsubnet=10.2.0.0/16 + auto=add diff --git a/testing/tests/ikev1/net2net-ah/hosts/moon/etc/strongswan.conf b/testing/tests/ikev1/net2net-ah/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/hosts/moon/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev1/net2net-ah/hosts/sun/etc/ipsec.conf b/testing/tests/ikev1/net2net-ah/hosts/sun/etc/ipsec.conf new file mode 100644 index 000000000..c374adfc4 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/hosts/sun/etc/ipsec.conf @@ -0,0 +1,20 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + charondebug="cfg 2, knl 3" + +conn %default + keyexchange=ikev1 + ike=aes128-sha1-modp1536! + ah=sha1! + +conn net-net + left=PH_IP_SUN + leftcert=sunCert.pem + leftid=@sun.strongswan.org + leftsubnet=10.2.0.0/16 + leftfirewall=yes + right=PH_IP_MOON + rightid=@moon.strongswan.org + rightsubnet=10.1.0.0/16 + auto=add diff --git a/testing/tests/ikev1/net2net-ah/hosts/sun/etc/strongswan.conf b/testing/tests/ikev1/net2net-ah/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/hosts/sun/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev1/net2net-ah/posttest.dat b/testing/tests/ikev1/net2net-ah/posttest.dat new file mode 100644 index 000000000..1f7aa73a1 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/posttest.dat @@ -0,0 +1,4 @@ +moon::ipsec stop +sun::ipsec stop +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush diff --git a/testing/tests/ikev1/net2net-ah/pretest.dat b/testing/tests/ikev1/net2net-ah/pretest.dat new file mode 100644 index 000000000..81a98fa41 --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/pretest.dat @@ -0,0 +1,6 @@ +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::ipsec start +sun::ipsec start +moon::sleep 1 +moon::ipsec up net-net diff --git a/testing/tests/ikev1/net2net-ah/test.conf b/testing/tests/ikev1/net2net-ah/test.conf new file mode 100644 index 000000000..afa2accbe --- /dev/null +++ b/testing/tests/ikev1/net2net-ah/test.conf @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="alice moon winnetou sun bob" + +# Corresponding block diagram +# +DIAGRAM="a-m-w-s-b.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="sun" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon sun" diff --git a/testing/tests/ikev2/host2host-ah/description.txt b/testing/tests/ikev2/host2host-ah/description.txt new file mode 100644 index 000000000..11d814f8c --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/description.txt @@ -0,0 +1,5 @@ +An IPsec <b>AH transport-mode</b> connection using AES-XCBC between the hosts +<b>moon</b> and <b>sun</b> is successfully set up. <b>leftfirewall=yes</b> +automatically inserts iptables-based firewall rules that let pass the decrypted +IP packets. In order to test the host-to-host connection <b>moon</b> pings +<b>sun</b>. diff --git a/testing/tests/ikev2/host2host-ah/evaltest.dat b/testing/tests/ikev2/host2host-ah/evaltest.dat new file mode 100644 index 000000000..92695477a --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/evaltest.dat @@ -0,0 +1,7 @@ +moon::ipsec status 2> /dev/null::host-host.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES +sun:: ipsec status 2> /dev/null::host-host.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES +moon::ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES +sun:: ipsec status 2> /dev/null::host-host.*INSTALLED, TRANSPORT::YES +moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_req=1::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: AH::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: AH::YES diff --git a/testing/tests/ikev2/host2host-ah/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/host2host-ah/hosts/moon/etc/ipsec.conf new file mode 100644 index 000000000..535e3d491 --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/hosts/moon/etc/ipsec.conf @@ -0,0 +1,17 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + +conn %default + keyexchange=ikev2 + +conn host-host + left=PH_IP_MOON + leftcert=moonCert.pem + leftid=@moon.strongswan.org + leftfirewall=yes + right=PH_IP_SUN + rightid=@sun.strongswan.org + type=transport + ah=aesxcbc + auto=add diff --git a/testing/tests/ikev2/host2host-ah/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/host2host-ah/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/hosts/moon/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev2/host2host-ah/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2/host2host-ah/hosts/sun/etc/ipsec.conf new file mode 100644 index 000000000..9537c187b --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/hosts/sun/etc/ipsec.conf @@ -0,0 +1,17 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + +conn %default + keyexchange=ikev2 + +conn host-host + left=PH_IP_SUN + leftcert=sunCert.pem + leftid=@sun.strongswan.org + leftfirewall=yes + right=PH_IP_MOON + rightid=@moon.strongswan.org + type=transport + ah=aesxcbc + auto=add diff --git a/testing/tests/ikev2/host2host-ah/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/host2host-ah/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/hosts/sun/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev2/host2host-ah/posttest.dat b/testing/tests/ikev2/host2host-ah/posttest.dat new file mode 100644 index 000000000..1f7aa73a1 --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/posttest.dat @@ -0,0 +1,4 @@ +moon::ipsec stop +sun::ipsec stop +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush diff --git a/testing/tests/ikev2/host2host-ah/pretest.dat b/testing/tests/ikev2/host2host-ah/pretest.dat new file mode 100644 index 000000000..99789b90f --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/pretest.dat @@ -0,0 +1,6 @@ +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::ipsec start +sun::ipsec start +moon::sleep 2 +moon::ipsec up host-host diff --git a/testing/tests/ikev2/host2host-ah/test.conf b/testing/tests/ikev2/host2host-ah/test.conf new file mode 100644 index 000000000..9647dc6a2 --- /dev/null +++ b/testing/tests/ikev2/host2host-ah/test.conf @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="moon winnetou sun" + +# Corresponding block diagram +# +DIAGRAM="m-w-s.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="sun" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon sun" diff --git a/testing/tests/ikev2/net2net-ah/description.txt b/testing/tests/ikev2/net2net-ah/description.txt new file mode 100644 index 000000000..a8ac7ee6b --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/description.txt @@ -0,0 +1,7 @@ +A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up. +With <b>ah=sha1-md5</b> gateway <b>moon</b> proposes the use of an +<b>AH proposal</b>. Gateway <b>sun</b> selects SHA1 for integrity protection +with its <b>ah=sha1!</b> configuration. +<p/> +Upon the successful establishment of the AH CHILD SA, client <b>alice</b> behind +gateway <b>moon</b> pings client <b>bob</b> located behind gateway <b>sun</b>. diff --git a/testing/tests/ikev2/net2net-ah/evaltest.dat b/testing/tests/ikev2/net2net-ah/evaltest.dat new file mode 100644 index 000000000..c5f2b1ecb --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/evaltest.dat @@ -0,0 +1,11 @@ +sun:: cat /var/log/daemon.log::received proposals: AH:HMAC_SHA1_96/HMAC_MD5_96/NO_EXT_SEQ::YES +sun:: cat /var/log/daemon.log::selected proposal: AH:HMAC_SHA1_96/NO_EXT_SEQ::YES +moon:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES +sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES +moon:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES +sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES +alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES +sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: AH::YES +sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: AH::YES +moon::ipsec statusall 2> /dev/null::HMAC_SHA1_96::YES +sun:: ipsec statusall 2> /dev/null::HMAC_SHA1_96::YES diff --git a/testing/tests/ikev2/net2net-ah/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/net2net-ah/hosts/moon/etc/ipsec.conf new file mode 100644 index 000000000..602119553 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/hosts/moon/etc/ipsec.conf @@ -0,0 +1,20 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + charondebug="cfg 2, knl 2" + +conn %default + keyexchange=ikev2 + ike=aes128-sha1-modp1536! + ah=sha1-md5 + +conn net-net + left=PH_IP_MOON + leftcert=moonCert.pem + leftid=@moon.strongswan.org + leftsubnet=10.1.0.0/16 + leftfirewall=yes + right=PH_IP_SUN + rightid=@sun.strongswan.org + rightsubnet=10.2.0.0/16 + auto=add diff --git a/testing/tests/ikev2/net2net-ah/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/net2net-ah/hosts/moon/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/hosts/moon/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev2/net2net-ah/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2/net2net-ah/hosts/sun/etc/ipsec.conf new file mode 100644 index 000000000..3f1ee5991 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/hosts/sun/etc/ipsec.conf @@ -0,0 +1,20 @@ +# /etc/ipsec.conf - strongSwan IPsec configuration file + +config setup + charondebug="cfg 2, knl 2" + +conn %default + keyexchange=ikev2 + ike=aes128-sha1-modp1536! + ah=sha1! + +conn net-net + left=PH_IP_SUN + leftcert=sunCert.pem + leftid=@sun.strongswan.org + leftsubnet=10.2.0.0/16 + leftfirewall=yes + right=PH_IP_MOON + rightid=@moon.strongswan.org + rightsubnet=10.1.0.0/16 + auto=add diff --git a/testing/tests/ikev2/net2net-ah/hosts/sun/etc/strongswan.conf b/testing/tests/ikev2/net2net-ah/hosts/sun/etc/strongswan.conf new file mode 100644 index 000000000..8e685c862 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/hosts/sun/etc/strongswan.conf @@ -0,0 +1,6 @@ +# /etc/strongswan.conf - strongSwan configuration file + +charon { + load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac xcbc stroke kernel-netlink socket-default updown + multiple_authentication = no +} diff --git a/testing/tests/ikev2/net2net-ah/posttest.dat b/testing/tests/ikev2/net2net-ah/posttest.dat new file mode 100644 index 000000000..1f7aa73a1 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/posttest.dat @@ -0,0 +1,4 @@ +moon::ipsec stop +sun::ipsec stop +moon::iptables-restore < /etc/iptables.flush +sun::iptables-restore < /etc/iptables.flush diff --git a/testing/tests/ikev2/net2net-ah/pretest.dat b/testing/tests/ikev2/net2net-ah/pretest.dat new file mode 100644 index 000000000..81a98fa41 --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/pretest.dat @@ -0,0 +1,6 @@ +moon::iptables-restore < /etc/iptables.rules +sun::iptables-restore < /etc/iptables.rules +moon::ipsec start +sun::ipsec start +moon::sleep 1 +moon::ipsec up net-net diff --git a/testing/tests/ikev2/net2net-ah/test.conf b/testing/tests/ikev2/net2net-ah/test.conf new file mode 100644 index 000000000..afa2accbe --- /dev/null +++ b/testing/tests/ikev2/net2net-ah/test.conf @@ -0,0 +1,21 @@ +#!/bin/bash +# +# This configuration file provides information on the +# guest instances used for this test + +# All guest instances that are required for this test +# +VIRTHOSTS="alice moon winnetou sun bob" + +# Corresponding block diagram +# +DIAGRAM="a-m-w-s-b.png" + +# Guest instances on which tcpdump is to be started +# +TCPDUMPHOSTS="sun" + +# Guest instances on which IPsec is started +# Used for IPsec logging purposes +# +IPSECHOSTS="moon sun" |