]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Merge branch 'ah'
authorMartin Willi <martin@revosec.ch>
Fri, 11 Oct 2013 08:15:43 +0000 (10:15 +0200)
committerMartin Willi <martin@revosec.ch>
Fri, 11 Oct 2013 08:15:43 +0000 (10:15 +0200)
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:
man/ipsec.conf.5.in
src/_updown/_updown.in
src/libcharon/config/proposal.c
src/libcharon/encoding/message.c
src/libcharon/encoding/payloads/proposal_substructure.c
src/libcharon/encoding/payloads/sa_payload.c
src/libcharon/kernel/kernel_handler.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/stroke/stroke_socket.c
src/libcharon/plugins/updown/updown_listener.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/ikev1/tasks/quick_delete.c
src/libcharon/sa/ikev1/tasks/quick_mode.c
src/libcharon/sa/ikev2/tasks/child_create.c
src/libcharon/sa/keymat.c
src/libcharon/sa/trap_manager.c
src/starter/args.c
src/starter/confread.c
src/starter/confread.h
src/starter/keywords.h
src/starter/keywords.txt
src/starter/starterstroke.c
src/stroke/stroke_msg.h
testing/hosts/default/etc/iptables.rules
testing/tests/ikev1/host2host-ah/description.txt [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/evaltest.dat [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/hosts/moon/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/hosts/sun/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/hosts/sun/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/posttest.dat [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/pretest.dat [new file with mode: 0644]
testing/tests/ikev1/host2host-ah/test.conf [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/description.txt [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/evaltest.dat [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/hosts/moon/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/hosts/sun/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/hosts/sun/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/posttest.dat [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/pretest.dat [new file with mode: 0644]
testing/tests/ikev1/net2net-ah/test.conf [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/description.txt [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/evaltest.dat [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/hosts/moon/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/hosts/sun/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/hosts/sun/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/posttest.dat [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/pretest.dat [new file with mode: 0644]
testing/tests/ikev2/host2host-ah/test.conf [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/description.txt [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/evaltest.dat [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/hosts/moon/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/hosts/sun/etc/ipsec.conf [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/hosts/sun/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/posttest.dat [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/pretest.dat [new file with mode: 0644]
testing/tests/ikev2/net2net-ah/test.conf [new file with mode: 0644]

index a62d68aaee4e9cd38a1a13aebd6738060c4b98ee..f83c45116bb318c91822f93fc4ce499879689213 100644 (file)
@@ -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 .
index f582e1a78f0c9523bb255dc6b337830802fdee39..ca0398ab7aa57c290a1a9b648ec0c26fa716774a 100644 (file)
 #              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
index 0b702e0141f09754d86c29f2567d44d5804c6210..0acc425d6e76feabf01631f423dcaf4b51f58caa 100644 (file)
@@ -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)
index 3896d71997acaec1e569859ae9078f1a097212ce..9fc108b40446784221687270b98c8aaf788dfb60 100644 (file)
@@ -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},
index 3cf22aefde33144fbb225c4e3b640939bf2b125d..cb9b359b3f38fb14e12b896dc7d1f5c0191ebbd6 100644 (file)
@@ -245,6 +245,24 @@ typedef enum {
        IKEV1_ESP_AUTH_AES_256_GMAC = 13,
 } 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.
  */
@@ -636,6 +654,22 @@ static algo_map_t map_esp_auth[] = {
        { IKEV1_ESP_AUTH_AES_256_GMAC,          AUTH_AES_256_GMAC },
 };
 
+/**
+ * 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
  */
@@ -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;
index 6134120141a07f322aa5bada3b289d284b338318..3a5bb43a6812a735664a33fb2ea4dd4283220804 100644 (file)
@@ -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;
 }
index aa5c4e0595df7985585e9c2232ab78c7047baba6..059124e35bdd34feb586d3d73f52cf224cdd4c05 100644 (file)
@@ -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;
 }
-
index edfa8a9c3f109c81236e1b74da24c9eae980de0f..2e10f324b789f4d60096b5fa4910c92ed1fb5c41 100644 (file)
@@ -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;
 }
 
index a5825519b2d6ca9ec447122cf839694f79d2ea31..ea168058ff545e8f0807d12149f93b21ada6dd18 100644 (file)
@@ -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);
index 88f73f3b04bdbb02ffc8ad485af1cd43beff8165..3adebb52318a26fdce8e2caa6d1456eeddcb6dd0 100644 (file)
@@ -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);
index 0268c88f3ac15c532916f3450ea56933bc2674ee..3c3994b812f35a9e7cf61bc5a4cb882559509c15 100644 (file)
@@ -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,
index 46e4b6f7ba73a7bea2b5bfe38a4bb33312e970da..9bd0c05adb37472f18d94c19fad3cf09dc974f5a 100644 (file)
@@ -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,
index 1a2cdb777d7b4c733fd29b8cc0ef0b6ba2df8f9e..605c10cea88aad50fe14a92802aeb6511c73d3fe 100644 (file)
@@ -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);
 
index 925b1c617694d4aceca9cd5f2637deda7bc1160d..12ee594b9b90dd9bc39077e798c4ae3cb15bfedb 100644 (file)
@@ -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)
index 8ae36af84a73f7d3adf602c8b2c6cc1a2155109b..7cfa537a98de7ddb3e1071cd92e5af6b64bd1cca 100644 (file)
@@ -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)
index 26c305f776ae56d235b4707ad5e1ebdf924e5182..d1f6a1bdc5060c83b959dbcf5f4e739f62c6f501 100644 (file)
@@ -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;
 
index 0d5c10d592b94800424485baeab39935d89525e3..5a4c06c2deb4d3236f375151bdfd8e94dea82319 100644 (file)
@@ -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));
index 5fbf51856bc7e5ee38eecb8a25adc681df535bb6..f5a617eaa806b04f5db504006957c17ab8c2406e 100644 (file)
@@ -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);
 
index 2fb022692f265be4933116a2e0bd269a1d1430b3..cec9399e326f60ec86eb08ce69bc8cc3a2dc9cd0 100644 (file)
@@ -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))
                        {
index 0690bed4e4fa80faafa35d078bddda226a7d36fe..d55a17e631c324bc9821f5d7650ed9403fc53164 100644 (file)
@@ -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;
index 83ce4a7ddfca1ebb6b7f2e3af899458840ce6667..705a7c16e97906f20b4c54eec4909dd862341a26 100644 (file)
@@ -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,
index 20d35ded06f70194387949906f81627fff935f11..ad915bf2afcf2b02a025dc909852975e4bc6de53 100644 (file)
@@ -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
index bf7e0284fd99df0d312f59ae88b7e009c1dc5ef5..fca4b1e7dca927f4e8a08c9480709177c2fa7d9c 100644 (file)
@@ -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;
index 6c8dcf5f93f9b2d00bda159f1d67032842fcddba..5ece7248bf76328b7cd90196bd24f17a7a11e3b3 100644 (file)
@@ -275,6 +275,7 @@ struct stroke_msg_t {
                        struct {
                                char *ike;
                                char *esp;
+                               char *ah;
                        } algorithms;
                        struct {
                                int reauth;
index c3f036cf97b79ae1a24c30487fac3da1da52bf13..b69e1429e0eefe03095b7804d1070d902f5e26a4 100644 (file)
@@ -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 (file)
index 0000000..dccdd52
--- /dev/null
@@ -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 (file)
index 0000000..9269547
--- /dev/null
@@ -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 (file)
index 0000000..a05e5d0
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..6851ffb
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..1f7aa73
--- /dev/null
@@ -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 (file)
index 0000000..99789b9
--- /dev/null
@@ -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 (file)
index 0000000..9647dc6
--- /dev/null
@@ -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 (file)
index 0000000..7ced7a5
--- /dev/null
@@ -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 (file)
index 0000000..bf6234b
--- /dev/null
@@ -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 (file)
index 0000000..d062dfe
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..c374adf
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..1f7aa73
--- /dev/null
@@ -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 (file)
index 0000000..81a98fa
--- /dev/null
@@ -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 (file)
index 0000000..afa2acc
--- /dev/null
@@ -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 (file)
index 0000000..11d814f
--- /dev/null
@@ -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 (file)
index 0000000..9269547
--- /dev/null
@@ -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 (file)
index 0000000..535e3d4
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..9537c18
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..1f7aa73
--- /dev/null
@@ -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 (file)
index 0000000..99789b9
--- /dev/null
@@ -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 (file)
index 0000000..9647dc6
--- /dev/null
@@ -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 (file)
index 0000000..a8ac7ee
--- /dev/null
@@ -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 (file)
index 0000000..c5f2b1e
--- /dev/null
@@ -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 (file)
index 0000000..6021195
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..3f1ee59
--- /dev/null
@@ -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 (file)
index 0000000..8e685c8
--- /dev/null
@@ -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 (file)
index 0000000..1f7aa73
--- /dev/null
@@ -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 (file)
index 0000000..81a98fa
--- /dev/null
@@ -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 (file)
index 0000000..afa2acc
--- /dev/null
@@ -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"