2 * Copyright (C) 2006-2007 Martin Willi
3 * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 #include <config/peer_cfg.h>
23 #include <crypto/hashers/hasher.h>
24 #include <encoding/payloads/notify_payload.h>
27 typedef struct private_ike_natd_t private_ike_natd_t
;
30 * Private members of a ike_natd_t task.
32 struct private_ike_natd_t
{
35 * Public methods and task_t interface.
45 * Are we the initiator?
50 * Hasher used to build NAT detection hashes
55 * Did we process any NAT detection notifys for a source address?
60 * Did we process any NAT detection notifys for a destination address?
65 * Have we found a matching source address NAT hash?
70 * Have we found a matching destination address NAT hash?
75 * whether NAT mappings for our NATed address has changed
82 * Build NAT detection hash for a host
84 static chunk_t
generate_natd_hash(private_ike_natd_t
*this,
85 ike_sa_id_t
*ike_sa_id
, host_t
*host
)
87 chunk_t natd_chunk
, spi_i_chunk
, spi_r_chunk
, addr_chunk
, port_chunk
;
89 u_int64_t spi_i
, spi_r
;
92 /* prepare all required chunks */
93 spi_i
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
94 spi_r
= ike_sa_id
->get_responder_spi(ike_sa_id
);
95 spi_i_chunk
.ptr
= (void*)&spi_i
;
96 spi_i_chunk
.len
= sizeof(spi_i
);
97 spi_r_chunk
.ptr
= (void*)&spi_r
;
98 spi_r_chunk
.len
= sizeof(spi_r
);
99 port
= htons(host
->get_port(host
));
100 port_chunk
.ptr
= (void*)&port
;
101 port_chunk
.len
= sizeof(port
);
102 addr_chunk
= host
->get_address(host
);
104 /* natd_hash = SHA1( spi_i | spi_r | address | port ) */
105 natd_chunk
= chunk_cat("cccc", spi_i_chunk
, spi_r_chunk
, addr_chunk
, port_chunk
);
106 this->hasher
->allocate_hash(this->hasher
, natd_chunk
, &natd_hash
);
107 DBG3(DBG_IKE
, "natd_chunk %B", &natd_chunk
);
108 DBG3(DBG_IKE
, "natd_hash %B", &natd_hash
);
110 chunk_free(&natd_chunk
);
115 * build a faked NATD payload to enforce UDP encap
117 static chunk_t
generate_natd_hash_faked(private_ike_natd_t
*this)
122 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
125 DBG1(DBG_IKE
, "unable to get random bytes for NATD fake");
128 rng
->allocate_bytes(rng
, HASH_SIZE_SHA1
, &chunk
);
134 * Build a NAT detection notify payload.
136 static notify_payload_t
*build_natd_payload(private_ike_natd_t
*this,
137 notify_type_t type
, host_t
*host
)
140 notify_payload_t
*notify
;
141 ike_sa_id_t
*ike_sa_id
;
144 ike_sa_id
= this->ike_sa
->get_id(this->ike_sa
);
145 config
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
146 if (config
->force_encap(config
) && type
== NAT_DETECTION_SOURCE_IP
)
148 hash
= generate_natd_hash_faked(this);
152 hash
= generate_natd_hash(this, ike_sa_id
, host
);
154 notify
= notify_payload_create();
155 notify
->set_notify_type(notify
, type
);
156 notify
->set_notification_data(notify
, hash
);
163 * read notifys from message and evaluate them
165 static void process_payloads(private_ike_natd_t
*this, message_t
*message
)
167 enumerator_t
*enumerator
;
169 notify_payload_t
*notify
;
170 chunk_t hash
, src_hash
, dst_hash
;
171 ike_sa_id_t
*ike_sa_id
;
175 /* Precompute NAT-D hashes for incoming NAT notify comparison */
176 ike_sa_id
= message
->get_ike_sa_id(message
);
177 me
= message
->get_destination(message
);
178 other
= message
->get_source(message
);
179 dst_hash
= generate_natd_hash(this, ike_sa_id
, me
);
180 src_hash
= generate_natd_hash(this, ike_sa_id
, other
);
182 DBG3(DBG_IKE
, "precalculated src_hash %B", &src_hash
);
183 DBG3(DBG_IKE
, "precalculated dst_hash %B", &dst_hash
);
185 enumerator
= message
->create_payload_enumerator(message
);
186 while (enumerator
->enumerate(enumerator
, &payload
))
188 if (payload
->get_type(payload
) != NOTIFY
)
192 notify
= (notify_payload_t
*)payload
;
193 switch (notify
->get_notify_type(notify
))
195 case NAT_DETECTION_DESTINATION_IP
:
197 this->dst_seen
= TRUE
;
198 hash
= notify
->get_notification_data(notify
);
199 if (!this->dst_matched
)
201 DBG3(DBG_IKE
, "received dst_hash %B", &hash
);
202 if (chunk_equals(hash
, dst_hash
))
204 this->dst_matched
= TRUE
;
207 /* RFC4555 says we should also compare against IKE_SA_INIT
208 * NATD payloads, but this does not work: We are running
209 * there at port 500, but use 4500 afterwards... */
210 if (message
->get_exchange_type(message
) == INFORMATIONAL
&&
211 this->initiator
&& !this->dst_matched
)
213 this->mapping_changed
= this->ike_sa
->has_mapping_changed(
218 case NAT_DETECTION_SOURCE_IP
:
220 this->src_seen
= TRUE
;
221 if (!this->src_matched
)
223 hash
= notify
->get_notification_data(notify
);
224 DBG3(DBG_IKE
, "received src_hash %B", &hash
);
225 if (chunk_equals(hash
, src_hash
))
227 this->src_matched
= TRUE
;
236 enumerator
->destroy(enumerator
);
238 chunk_free(&src_hash
);
239 chunk_free(&dst_hash
);
241 if (this->src_seen
&& this->dst_seen
)
243 this->ike_sa
->enable_extension(this->ike_sa
, EXT_NATT
);
245 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_HERE
,
247 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_THERE
,
249 config
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
250 if (this->dst_matched
&& this->src_matched
&&
251 config
->force_encap(config
))
253 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_FAKE
, TRUE
);
259 * Implementation of task_t.process for initiator
261 static status_t
process_i(private_ike_natd_t
*this, message_t
*message
)
263 process_payloads(this, message
);
265 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
267 peer_cfg_t
*peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
270 /* if we are on a mediated connection we have already switched to
271 * port 4500 and the correct destination port is already configured,
272 * therefore we must not switch again */
273 if (peer_cfg
->get_mediated_by(peer_cfg
))
279 if (this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
) ||
281 /* if we are on a mediation connection we switch to port 4500 even
282 * if no NAT is detected. */
283 peer_cfg
->is_mediation(peer_cfg
) ||
285 /* if peer supports NAT-T, we switch to port 4500 even
286 * if no NAT is detected. MOBIKE requires this. */
287 (peer_cfg
->use_mobike(peer_cfg
) &&
288 this->ike_sa
->supports_extension(this->ike_sa
, EXT_NATT
)))
292 /* do not switch if we have a custom port from mobike/NAT */
293 me
= this->ike_sa
->get_my_host(this->ike_sa
);
294 if (me
->get_port(me
) == IKEV2_UDP_PORT
)
296 me
->set_port(me
, IKEV2_NATT_PORT
);
298 other
= this->ike_sa
->get_other_host(this->ike_sa
);
299 if (other
->get_port(other
) == IKEV2_UDP_PORT
)
301 other
->set_port(other
, IKEV2_NATT_PORT
);
310 * Implementation of task_t.process for initiator
312 static status_t
build_i(private_ike_natd_t
*this, message_t
*message
)
314 notify_payload_t
*notify
;
315 enumerator_t
*enumerator
;
318 if (this->hasher
== NULL
)
320 DBG1(DBG_IKE
, "unable to build NATD payloads, SHA1 not supported");
324 /* destination is always set */
325 host
= message
->get_destination(message
);
326 notify
= build_natd_payload(this, NAT_DETECTION_DESTINATION_IP
, host
);
327 message
->add_payload(message
, (payload_t
*)notify
);
329 /* source may be any, we have 3 possibilities to get our source address:
330 * 1. It is defined in the config => use the one of the IKE_SA
331 * 2. We do a routing lookup in the kernel interface
332 * 3. Include all possbile addresses
334 host
= message
->get_source(message
);
335 if (!host
->is_anyaddr(host
))
337 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
338 message
->add_payload(message
, (payload_t
*)notify
);
342 host
= charon
->kernel_interface
->get_source_addr(charon
->kernel_interface
,
343 this->ike_sa
->get_other_host(this->ike_sa
), NULL
);
346 host
->set_port(host
, IKEV2_UDP_PORT
);
347 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
348 message
->add_payload(message
, (payload_t
*)notify
);
353 enumerator
= charon
->kernel_interface
->create_address_enumerator(
354 charon
->kernel_interface
, FALSE
, FALSE
);
355 while (enumerator
->enumerate(enumerator
, (void**)&host
))
357 /* apply port 500 to host, but work on a copy */
358 host
= host
->clone(host
);
359 host
->set_port(host
, IKEV2_UDP_PORT
);
360 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
362 message
->add_payload(message
, (payload_t
*)notify
);
364 enumerator
->destroy(enumerator
);
371 * Implementation of task_t.build for responder
373 static status_t
build_r(private_ike_natd_t
*this, message_t
*message
)
375 notify_payload_t
*notify
;
378 /* only add notifies on successfull responses. */
379 if (message
->get_exchange_type(message
) == IKE_SA_INIT
&&
380 message
->get_payload(message
, SECURITY_ASSOCIATION
) == NULL
)
385 if (this->src_seen
&& this->dst_seen
)
387 if (this->hasher
== NULL
)
389 DBG1(DBG_IKE
, "unable to build NATD payloads, SHA1 not supported");
393 /* initiator seems to support NAT detection, add response */
394 me
= message
->get_source(message
);
395 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, me
);
396 message
->add_payload(message
, (payload_t
*)notify
);
398 other
= message
->get_destination(message
);
399 notify
= build_natd_payload(this, NAT_DETECTION_DESTINATION_IP
, other
);
400 message
->add_payload(message
, (payload_t
*)notify
);
406 * Implementation of task_t.process for responder
408 static status_t
process_r(private_ike_natd_t
*this, message_t
*message
)
410 process_payloads(this, message
);
416 * Implementation of task_t.get_type
418 static task_type_t
get_type(private_ike_natd_t
*this)
424 * Implementation of task_t.migrate
426 static void migrate(private_ike_natd_t
*this, ike_sa_t
*ike_sa
)
428 this->ike_sa
= ike_sa
;
429 this->src_seen
= FALSE
;
430 this->dst_seen
= FALSE
;
431 this->src_matched
= FALSE
;
432 this->dst_matched
= FALSE
;
433 this->mapping_changed
= FALSE
;
437 * Implementation of ike_natd_t.has_mapping_changed
439 static bool has_mapping_changed(private_ike_natd_t
*this)
441 return this->mapping_changed
;
445 * Implementation of task_t.destroy
447 static void destroy(private_ike_natd_t
*this)
449 DESTROY_IF(this->hasher
);
454 * Described in header.
456 ike_natd_t
*ike_natd_create(ike_sa_t
*ike_sa
, bool initiator
)
458 private_ike_natd_t
*this = malloc_thing(private_ike_natd_t
);
460 this->public.task
.get_type
= (task_type_t(*)(task_t
*))get_type
;
461 this->public.task
.migrate
= (void(*)(task_t
*,ike_sa_t
*))migrate
;
462 this->public.task
.destroy
= (void(*)(task_t
*))destroy
;
466 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_i
;
467 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_i
;
471 this->public.task
.build
= (status_t(*)(task_t
*,message_t
*))build_r
;
472 this->public.task
.process
= (status_t(*)(task_t
*,message_t
*))process_r
;
475 this->public.has_mapping_changed
= (bool(*)(ike_natd_t
*))has_mapping_changed
;
477 this->ike_sa
= ike_sa
;
478 this->initiator
= initiator
;
479 this->hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
480 this->src_seen
= FALSE
;
481 this->dst_seen
= FALSE
;
482 this->src_matched
= FALSE
;
483 this->dst_matched
= FALSE
;
484 this->mapping_changed
= FALSE
;
486 return &this->public;