From: Tobias Brunner Date: Fri, 25 Sep 2015 17:24:44 +0000 (+0200) Subject: ike-natd: Create fake NAT-D payloads in a more static way X-Git-Tag: 5.3.4dr3~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8484d2b01d5475abd1ded60b6b451a22cec99a61;p=thirdparty%2Fstrongswan.git ike-natd: Create fake NAT-D payloads in a more static way In some scenarios an IKE_SA might get restarted multiple times (e.g. due to retransmits and delayed INVALID_KE_PAYLOAD notifies) so that two IKE_SA_INIT messages might be sent that only differ in the previously randomly generated NAT_DETECTION_SOURCE_IP payload. This could cause an authentication failure on the responder if the two peers don't use the same IKE_SA_INIT message in their InitiatorSignedOctets. While the payload is generated in a reproducible way it will still change when the daemon is restarted, which should make detecting the payloads as fake a bit harder (compared to e.g. just using 0.0.0.0:0 as address). Fixes #1131. --- diff --git a/src/libcharon/sa/ikev2/tasks/ike_natd.c b/src/libcharon/sa/ikev2/tasks/ike_natd.c index 9e0eb68ce9..dd34c12347 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_natd.c +++ b/src/libcharon/sa/ikev2/tasks/ike_natd.c @@ -128,25 +128,6 @@ static chunk_t generate_natd_hash(private_ike_natd_t *this, return natd_hash; } -/** - * build a faked NATD payload to enforce UDP encap - */ -static chunk_t generate_natd_hash_faked(private_ike_natd_t *this) -{ - rng_t *rng; - chunk_t chunk; - - rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); - if (!rng || !rng->allocate_bytes(rng, HASH_SIZE_SHA1, &chunk)) - { - DBG1(DBG_IKE, "unable to get random bytes for NATD fake"); - DESTROY_IF(rng); - return chunk_empty; - } - rng->destroy(rng); - return chunk; -} - /** * Build a NAT detection notify payload. */ @@ -162,7 +143,14 @@ static notify_payload_t *build_natd_payload(private_ike_natd_t *this, config = this->ike_sa->get_ike_cfg(this->ike_sa); if (force_encap(config) && type == NAT_DETECTION_SOURCE_IP) { - hash = generate_natd_hash_faked(this); + u_int32_t addr; + + /* chunk_hash() is randomly keyed so this produces a random IPv4 address + * that changes with every restart but otherwise stays the same */ + addr = chunk_hash(chunk_from_chars(0x00, 0x00, 0x00, 0x00)); + host = host_create_from_chunk(AF_INET, chunk_from_thing(addr), 0); + hash = generate_natd_hash(this, ike_sa_id, host); + host->destroy(host); } else {