diff options
Diffstat (limited to 'src/charon/sa/tasks/ike_natd.c')
-rw-r--r-- | src/charon/sa/tasks/ike_natd.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/charon/sa/tasks/ike_natd.c b/src/charon/sa/tasks/ike_natd.c index eea769138..ff3fbb77c 100644 --- a/src/charon/sa/tasks/ike_natd.c +++ b/src/charon/sa/tasks/ike_natd.c @@ -114,6 +114,25 @@ static chunk_t generate_natd_hash(private_ike_natd_t *this, } /** + * build a faked NATD payload to enforce UDP encap + */ +static chunk_t generate_natd_hash_faked(private_ike_natd_t *this) +{ + randomizer_t *randomizer; + chunk_t chunk; + + randomizer = randomizer_create(); + if (randomizer->allocate_pseudo_random_bytes(randomizer, HASH_SIZE_SHA1, + &chunk) != SUCCESS) + { + DBG1(DBG_IKE, "unable to get random bytes for NATD fake"); + chunk = chunk_empty; + } + randomizer->destroy(randomizer); + return chunk; +} + +/** * Build a NAT detection notify payload. */ static notify_payload_t *build_natd_payload(private_ike_natd_t *this, @@ -121,12 +140,21 @@ static notify_payload_t *build_natd_payload(private_ike_natd_t *this, { chunk_t hash; notify_payload_t *notify; - ike_sa_id_t *ike_sa_id; + ike_sa_id_t *ike_sa_id; + peer_cfg_t *config; ike_sa_id = this->ike_sa->get_id(this->ike_sa); + config = this->ike_sa->get_peer_cfg(this->ike_sa); notify = notify_payload_create(); notify->set_notify_type(notify, type); - hash = generate_natd_hash(this, ike_sa_id, host); + if (config->force_encap(config) && type == NAT_DETECTION_SOURCE_IP) + { + hash = generate_natd_hash_faked(this); + } + else + { + hash = generate_natd_hash(this, ike_sa_id, host); + } notify->set_notification_data(notify, hash); chunk_free(&hash); @@ -144,6 +172,7 @@ static void process_payloads(private_ike_natd_t *this, message_t *message) chunk_t hash, src_hash, dst_hash; ike_sa_id_t *ike_sa_id; host_t *me, *other; + peer_cfg_t *config; /* Precompute NAT-D hashes for incoming NAT notify comparison */ ike_sa_id = message->get_ike_sa_id(message); @@ -209,7 +238,12 @@ static void process_payloads(private_ike_natd_t *this, message_t *message) this->ike_sa->set_condition(this->ike_sa, COND_NAT_HERE, !this->dst_matched); this->ike_sa->set_condition(this->ike_sa, COND_NAT_THERE, - !this->src_matched); + !this->src_matched); + config = this->ike_sa->get_peer_cfg(this->ike_sa); + if (config->force_encap(config)) + { + this->ike_sa->set_condition(this->ike_sa, COND_NAT_FAKE, TRUE); + } } } |