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
23 #include <config/peer_cfg.h>
24 #include <crypto/hashers/hasher.h>
25 #include <encoding/payloads/notify_payload.h>
28 typedef struct private_ike_natd_t private_ike_natd_t
;
31 * Private members of a ike_natd_t task.
33 struct private_ike_natd_t
{
36 * Public methods and task_t interface.
46 * Are we the initiator?
51 * Hasher used to build NAT detection hashes
56 * Did we process any NAT detection notifys for a source address?
61 * Did we process any NAT detection notifys for a destination address?
66 * Have we found a matching source address NAT hash?
71 * Have we found a matching destination address NAT hash?
76 * whether NAT mappings for our NATed address has changed
83 * Build NAT detection hash for a host
85 static chunk_t
generate_natd_hash(private_ike_natd_t
*this,
86 ike_sa_id_t
*ike_sa_id
, host_t
*host
)
88 chunk_t natd_chunk
, spi_i_chunk
, spi_r_chunk
, addr_chunk
, port_chunk
;
90 u_int64_t spi_i
, spi_r
;
93 /* prepare all required chunks */
94 spi_i
= ike_sa_id
->get_initiator_spi(ike_sa_id
);
95 spi_r
= ike_sa_id
->get_responder_spi(ike_sa_id
);
96 spi_i_chunk
.ptr
= (void*)&spi_i
;
97 spi_i_chunk
.len
= sizeof(spi_i
);
98 spi_r_chunk
.ptr
= (void*)&spi_r
;
99 spi_r_chunk
.len
= sizeof(spi_r
);
100 port
= htons(host
->get_port(host
));
101 port_chunk
.ptr
= (void*)&port
;
102 port_chunk
.len
= sizeof(port
);
103 addr_chunk
= host
->get_address(host
);
105 /* natd_hash = SHA1( spi_i | spi_r | address | port ) */
106 natd_chunk
= chunk_cat("cccc", spi_i_chunk
, spi_r_chunk
, addr_chunk
, port_chunk
);
107 this->hasher
->allocate_hash(this->hasher
, natd_chunk
, &natd_hash
);
108 DBG3(DBG_IKE
, "natd_chunk %B", &natd_chunk
);
109 DBG3(DBG_IKE
, "natd_hash %B", &natd_hash
);
111 chunk_free(&natd_chunk
);
116 * build a faked NATD payload to enforce UDP encap
118 static chunk_t
generate_natd_hash_faked(private_ike_natd_t
*this)
123 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_WEAK
);
126 DBG1(DBG_IKE
, "unable to get random bytes for NATD fake");
129 rng
->allocate_bytes(rng
, HASH_SIZE_SHA1
, &chunk
);
135 * Build a NAT detection notify payload.
137 static notify_payload_t
*build_natd_payload(private_ike_natd_t
*this,
138 notify_type_t type
, host_t
*host
)
141 notify_payload_t
*notify
;
142 ike_sa_id_t
*ike_sa_id
;
145 ike_sa_id
= this->ike_sa
->get_id(this->ike_sa
);
146 config
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
147 if (config
->force_encap(config
) && type
== NAT_DETECTION_SOURCE_IP
)
149 hash
= generate_natd_hash_faked(this);
153 hash
= generate_natd_hash(this, ike_sa_id
, host
);
155 notify
= notify_payload_create(NOTIFY
);
156 notify
->set_notify_type(notify
, type
);
157 notify
->set_notification_data(notify
, hash
);
164 * read notifys from message and evaluate them
166 static void process_payloads(private_ike_natd_t
*this, message_t
*message
)
168 enumerator_t
*enumerator
;
170 notify_payload_t
*notify
;
171 chunk_t hash
, src_hash
, dst_hash
;
172 ike_sa_id_t
*ike_sa_id
;
176 /* Precompute NAT-D hashes for incoming NAT notify comparison */
177 ike_sa_id
= message
->get_ike_sa_id(message
);
178 me
= message
->get_destination(message
);
179 other
= message
->get_source(message
);
180 dst_hash
= generate_natd_hash(this, ike_sa_id
, me
);
181 src_hash
= generate_natd_hash(this, ike_sa_id
, other
);
183 DBG3(DBG_IKE
, "precalculated src_hash %B", &src_hash
);
184 DBG3(DBG_IKE
, "precalculated dst_hash %B", &dst_hash
);
186 enumerator
= message
->create_payload_enumerator(message
);
187 while (enumerator
->enumerate(enumerator
, &payload
))
189 if (payload
->get_type(payload
) != NOTIFY
)
193 notify
= (notify_payload_t
*)payload
;
194 switch (notify
->get_notify_type(notify
))
196 case NAT_DETECTION_DESTINATION_IP
:
198 this->dst_seen
= TRUE
;
199 hash
= notify
->get_notification_data(notify
);
200 if (!this->dst_matched
)
202 DBG3(DBG_IKE
, "received dst_hash %B", &hash
);
203 if (chunk_equals(hash
, dst_hash
))
205 this->dst_matched
= TRUE
;
208 /* RFC4555 says we should also compare against IKE_SA_INIT
209 * NATD payloads, but this does not work: We are running
210 * there at port 500, but use 4500 afterwards... */
211 if (message
->get_exchange_type(message
) == INFORMATIONAL
&&
212 this->initiator
&& !this->dst_matched
)
214 this->mapping_changed
= this->ike_sa
->has_mapping_changed(
219 case NAT_DETECTION_SOURCE_IP
:
221 this->src_seen
= TRUE
;
222 if (!this->src_matched
)
224 hash
= notify
->get_notification_data(notify
);
225 DBG3(DBG_IKE
, "received src_hash %B", &hash
);
226 if (chunk_equals(hash
, src_hash
))
228 this->src_matched
= TRUE
;
237 enumerator
->destroy(enumerator
);
239 chunk_free(&src_hash
);
240 chunk_free(&dst_hash
);
242 if (this->src_seen
&& this->dst_seen
)
244 this->ike_sa
->enable_extension(this->ike_sa
, EXT_NATT
);
246 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_HERE
,
248 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_THERE
,
250 config
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
251 if (this->dst_matched
&& this->src_matched
&&
252 config
->force_encap(config
))
254 this->ike_sa
->set_condition(this->ike_sa
, COND_NAT_FAKE
, TRUE
);
259 METHOD(task_t
, process_i
, status_t
,
260 private_ike_natd_t
*this, message_t
*message
)
262 process_payloads(this, message
);
264 if (message
->get_exchange_type(message
) == IKE_SA_INIT
)
266 peer_cfg_t
*peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
267 if (this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
) ||
268 /* if peer supports NAT-T, we switch to port 4500 even
269 * if no NAT is detected. can't be done later (when we would know
270 * whether the peer supports MOBIKE) because there would be no
271 * exchange to actually do the switch (other than a forced DPD). */
272 (peer_cfg
->use_mobike(peer_cfg
) &&
273 this->ike_sa
->supports_extension(this->ike_sa
, EXT_NATT
)))
275 this->ike_sa
->float_ports(this->ike_sa
);
282 METHOD(task_t
, build_i
, status_t
,
283 private_ike_natd_t
*this, message_t
*message
)
285 notify_payload_t
*notify
;
286 enumerator_t
*enumerator
;
290 if (this->hasher
== NULL
)
292 DBG1(DBG_IKE
, "unable to build NATD payloads, SHA1 not supported");
296 ike_cfg
= this->ike_sa
->get_ike_cfg(this->ike_sa
);
298 /* destination is always set */
299 host
= message
->get_destination(message
);
300 notify
= build_natd_payload(this, NAT_DETECTION_DESTINATION_IP
, host
);
301 message
->add_payload(message
, (payload_t
*)notify
);
303 /* source may be any, we have 3 possibilities to get our source address:
304 * 1. It is defined in the config => use the one of the IKE_SA
305 * 2. We do a routing lookup in the kernel interface
306 * 3. Include all possbile addresses
308 host
= message
->get_source(message
);
309 if (!host
->is_anyaddr(host
))
311 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
312 message
->add_payload(message
, (payload_t
*)notify
);
316 host
= hydra
->kernel_interface
->get_source_addr(hydra
->kernel_interface
,
317 this->ike_sa
->get_other_host(this->ike_sa
), NULL
);
320 host
->set_port(host
, ike_cfg
->get_my_port(ike_cfg
));
321 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
322 message
->add_payload(message
, (payload_t
*)notify
);
327 enumerator
= hydra
->kernel_interface
->create_address_enumerator(
328 hydra
->kernel_interface
, FALSE
, FALSE
);
329 while (enumerator
->enumerate(enumerator
, (void**)&host
))
331 /* apply port 500 to host, but work on a copy */
332 host
= host
->clone(host
);
333 host
->set_port(host
, ike_cfg
->get_my_port(ike_cfg
));
334 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, host
);
336 message
->add_payload(message
, (payload_t
*)notify
);
338 enumerator
->destroy(enumerator
);
344 METHOD(task_t
, build_r
, status_t
,
345 private_ike_natd_t
*this, message_t
*message
)
347 notify_payload_t
*notify
;
350 /* only add notifies on successful responses. */
351 if (message
->get_exchange_type(message
) == IKE_SA_INIT
&&
352 message
->get_payload(message
, SECURITY_ASSOCIATION
) == NULL
)
357 if (this->src_seen
&& this->dst_seen
)
359 if (this->hasher
== NULL
)
361 DBG1(DBG_IKE
, "unable to build NATD payloads, SHA1 not supported");
365 /* initiator seems to support NAT detection, add response */
366 me
= message
->get_source(message
);
367 notify
= build_natd_payload(this, NAT_DETECTION_SOURCE_IP
, me
);
368 message
->add_payload(message
, (payload_t
*)notify
);
370 other
= message
->get_destination(message
);
371 notify
= build_natd_payload(this, NAT_DETECTION_DESTINATION_IP
, other
);
372 message
->add_payload(message
, (payload_t
*)notify
);
377 METHOD(task_t
, process_r
, status_t
,
378 private_ike_natd_t
*this, message_t
*message
)
380 process_payloads(this, message
);
385 METHOD(task_t
, get_type
, task_type_t
,
386 private_ike_natd_t
*this)
388 return TASK_IKE_NATD
;
391 METHOD(task_t
, migrate
, void,
392 private_ike_natd_t
*this, ike_sa_t
*ike_sa
)
394 this->ike_sa
= ike_sa
;
395 this->src_seen
= FALSE
;
396 this->dst_seen
= FALSE
;
397 this->src_matched
= FALSE
;
398 this->dst_matched
= FALSE
;
399 this->mapping_changed
= FALSE
;
402 METHOD(task_t
, destroy
, void,
403 private_ike_natd_t
*this)
405 DESTROY_IF(this->hasher
);
409 METHOD(ike_natd_t
, has_mapping_changed
, bool,
410 private_ike_natd_t
*this)
412 return this->mapping_changed
;
416 * Described in header.
418 ike_natd_t
*ike_natd_create(ike_sa_t
*ike_sa
, bool initiator
)
420 private_ike_natd_t
*this;
425 .get_type
= _get_type
,
429 .has_mapping_changed
= _has_mapping_changed
,
432 .initiator
= initiator
,
433 .hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
),
438 this->public.task
.build
= _build_i
;
439 this->public.task
.process
= _process_i
;
443 this->public.task
.build
= _build_r
;
444 this->public.task
.process
= _process_r
;
447 return &this->public;