2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2011 Martin Willi
6 * Copyright (C) 2011 revosec AG
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * Copyright (C) 2012 Volker RĂ¼melin
22 * Permission is hereby granted, free of charge, to any person obtaining a copy
23 * of this software and associated documentation files (the "Software"), to deal
24 * in the Software without restriction, including without limitation the rights
25 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26 * copies of the Software, and to permit persons to whom the Software is
27 * furnished to do so, subject to the following conditions:
29 * The above copyright notice and this permission notice shall be included in
30 * all copies or substantial portions of the Software.
32 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41 #include "quick_mode.h"
46 #include <sa/ikev1/keymat_v1.h>
47 #include <encoding/payloads/sa_payload.h>
48 #include <encoding/payloads/nonce_payload.h>
49 #include <encoding/payloads/ke_payload.h>
50 #include <encoding/payloads/id_payload.h>
51 #include <encoding/payloads/payload.h>
52 #include <sa/ikev1/tasks/informational.h>
53 #include <sa/ikev1/tasks/quick_delete.h>
54 #include <processing/jobs/inactivity_job.h>
56 typedef struct private_quick_mode_t private_quick_mode_t
;
59 * Private members of a quick_mode_t task.
61 struct private_quick_mode_t
{
64 * Public methods and task_t interface.
74 * TRUE if we are initiating quick mode
79 * Traffic selector of initiator
81 traffic_selector_t
*tsi
;
84 * Traffic selector of responder
86 traffic_selector_t
*tsr
;
109 * Initiators IPComp CPI
114 * Responders IPComp CPI
119 * selected CHILD_SA proposal
121 proposal_t
*proposal
;
124 * Config of CHILD_SA to establish
129 * CHILD_SA we are about to establish
131 child_sa_t
*child_sa
;
139 * DH exchange, when PFS is in use
141 diffie_hellman_t
*dh
;
144 * Negotiated lifetime of new SA
149 * Negotaited lifebytes of new SA
154 * Reqid to use, 0 for auto-allocate
164 * Negotiated mode, tunnel or transport
169 * Use UDP encapsulation
173 /** states of quick mode */
181 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
183 static void schedule_inactivity_timeout(private_quick_mode_t
*this)
188 timeout
= this->config
->get_inactivity(this->config
);
191 close_ike
= lib
->settings
->get_bool(lib
->settings
,
192 "%s.inactivity_close_ike", FALSE
, charon
->name
);
193 lib
->scheduler
->schedule_job(lib
->scheduler
, (job_t
*)
194 inactivity_job_create(this->child_sa
->get_reqid(this->child_sa
),
195 timeout
, close_ike
), timeout
);
200 * Check if we have a an address pool configured
202 static bool have_pool(ike_sa_t
*ike_sa
)
204 enumerator_t
*enumerator
;
205 peer_cfg_t
*peer_cfg
;
209 peer_cfg
= ike_sa
->get_peer_cfg(ike_sa
);
212 enumerator
= peer_cfg
->create_pool_enumerator(peer_cfg
);
213 if (enumerator
->enumerate(enumerator
, &pool
))
217 enumerator
->destroy(enumerator
);
223 * Get hosts to use for dynamic traffic selectors
225 static linked_list_t
*get_dynamic_hosts(ike_sa_t
*ike_sa
, bool local
)
227 enumerator_t
*enumerator
;
231 list
= linked_list_create();
232 enumerator
= ike_sa
->create_virtual_ip_enumerator(ike_sa
, local
);
233 while (enumerator
->enumerate(enumerator
, &host
))
235 list
->insert_last(list
, host
);
237 enumerator
->destroy(enumerator
);
239 if (list
->get_count(list
) == 0)
240 { /* no virtual IPs assigned */
243 host
= ike_sa
->get_my_host(ike_sa
);
244 list
->insert_last(list
, host
);
246 else if (!have_pool(ike_sa
))
247 { /* use host only if we don't have a pool configured */
248 host
= ike_sa
->get_other_host(ike_sa
);
249 list
->insert_last(list
, host
);
256 * Install negotiated CHILD_SA
258 static bool install(private_quick_mode_t
*this)
260 status_t status
, status_i
, status_o
;
261 chunk_t encr_i
, encr_r
, integ_i
, integ_r
;
262 linked_list_t
*tsi
, *tsr
;
263 child_sa_t
*old
= NULL
;
265 this->child_sa
->set_proposal(this->child_sa
, this->proposal
);
266 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLING
);
267 this->child_sa
->set_mode(this->child_sa
, this->mode
);
269 if (this->cpi_i
&& this->cpi_r
)
270 { /* DEFLATE is the only transform we currently support */
271 this->child_sa
->set_ipcomp(this->child_sa
, IPCOMP_DEFLATE
);
275 this->cpi_i
= this->cpi_r
= 0;
278 this->child_sa
->set_protocol(this->child_sa
,
279 this->proposal
->get_protocol(this->proposal
));
281 status_i
= status_o
= FAILED
;
282 encr_i
= encr_r
= integ_i
= integ_r
= chunk_empty
;
283 tsi
= linked_list_create_with_items(this->tsi
->clone(this->tsi
), NULL
);
284 tsr
= linked_list_create_with_items(this->tsr
->clone(this->tsr
), NULL
);
287 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
288 NARROW_INITIATOR_POST_AUTH
, tsi
, tsr
);
292 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
293 NARROW_RESPONDER_POST
, tsr
, tsi
);
295 if (tsi
->get_count(tsi
) == 0 || tsr
->get_count(tsr
) == 0)
297 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
298 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
299 DBG1(DBG_IKE
, "no acceptable traffic selectors found");
303 if (this->keymat
->derive_child_keys(this->keymat
, this->proposal
, this->dh
,
304 this->spi_i
, this->spi_r
, this->nonce_i
, this->nonce_r
,
305 &encr_i
, &integ_i
, &encr_r
, &integ_r
))
309 status_i
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
310 this->spi_i
, this->cpi_i
, TRUE
, FALSE
, tsi
, tsr
);
311 status_o
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
312 this->spi_r
, this->cpi_r
, FALSE
, FALSE
, tsi
, tsr
);
316 status_i
= this->child_sa
->install(this->child_sa
, encr_i
, integ_i
,
317 this->spi_r
, this->cpi_r
, TRUE
, FALSE
, tsr
, tsi
);
318 status_o
= this->child_sa
->install(this->child_sa
, encr_r
, integ_r
,
319 this->spi_i
, this->cpi_i
, FALSE
, FALSE
, tsr
, tsi
);
322 chunk_clear(&integ_i
);
323 chunk_clear(&integ_r
);
324 chunk_clear(&encr_i
);
325 chunk_clear(&encr_r
);
327 if (status_i
!= SUCCESS
|| status_o
!= SUCCESS
)
329 DBG1(DBG_IKE
, "unable to install %s%s%sIPsec SA (SAD) in kernel",
330 (status_i
!= SUCCESS
) ?
"inbound " : "",
331 (status_i
!= SUCCESS
&& status_o
!= SUCCESS
) ?
"and ": "",
332 (status_o
!= SUCCESS
) ?
"outbound " : "");
333 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
334 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
340 status
= this->child_sa
->add_policies(this->child_sa
, tsi
, tsr
);
344 status
= this->child_sa
->add_policies(this->child_sa
, tsr
, tsi
);
346 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
347 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
348 if (status
!= SUCCESS
)
350 DBG1(DBG_IKE
, "unable to install IPsec policies (SPD) in kernel");
354 charon
->bus
->child_keys(charon
->bus
, this->child_sa
, this->initiator
,
355 this->dh
, this->nonce_i
, this->nonce_r
);
357 /* add to IKE_SA, and remove from task */
358 this->child_sa
->set_state(this->child_sa
, CHILD_INSTALLED
);
359 this->ike_sa
->add_child_sa(this->ike_sa
, this->child_sa
);
361 DBG0(DBG_IKE
, "CHILD_SA %s{%d} established "
362 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
363 this->child_sa
->get_name(this->child_sa
),
364 this->child_sa
->get_reqid(this->child_sa
),
365 ntohl(this->child_sa
->get_spi(this->child_sa
, TRUE
)),
366 ntohl(this->child_sa
->get_spi(this->child_sa
, FALSE
)),
367 this->child_sa
->get_traffic_selectors(this->child_sa
, TRUE
),
368 this->child_sa
->get_traffic_selectors(this->child_sa
, FALSE
));
372 old
= this->ike_sa
->get_child_sa(this->ike_sa
,
373 this->proposal
->get_protocol(this->proposal
),
378 charon
->bus
->child_rekey(charon
->bus
, old
, this->child_sa
);
382 charon
->bus
->child_updown(charon
->bus
, this->child_sa
, TRUE
);
386 schedule_inactivity_timeout(this);
388 this->child_sa
= NULL
;
393 * Generate and add NONCE
395 static bool add_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
398 nonce_payload_t
*nonce_payload
;
401 nonceg
= this->keymat
->keymat
.create_nonce_gen(&this->keymat
->keymat
);
404 DBG1(DBG_IKE
, "no nonce generator found to create nonce");
407 if (!nonceg
->allocate_nonce(nonceg
, NONCE_SIZE
, nonce
))
409 DBG1(DBG_IKE
, "nonce allocation failed");
410 nonceg
->destroy(nonceg
);
413 nonceg
->destroy(nonceg
);
415 nonce_payload
= nonce_payload_create(NONCE_V1
);
416 nonce_payload
->set_nonce(nonce_payload
, *nonce
);
417 message
->add_payload(message
, &nonce_payload
->payload_interface
);
423 * Extract nonce from NONCE payload
425 static bool get_nonce(private_quick_mode_t
*this, chunk_t
*nonce
,
428 nonce_payload_t
*nonce_payload
;
430 nonce_payload
= (nonce_payload_t
*)message
->get_payload(message
, NONCE_V1
);
433 DBG1(DBG_IKE
, "NONCE payload missing in message");
436 *nonce
= nonce_payload
->get_nonce(nonce_payload
);
442 * Add KE payload to message
444 static void add_ke(private_quick_mode_t
*this, message_t
*message
)
446 ke_payload_t
*ke_payload
;
448 ke_payload
= ke_payload_create_from_diffie_hellman(KEY_EXCHANGE_V1
, this->dh
);
449 message
->add_payload(message
, &ke_payload
->payload_interface
);
453 * Get DH value from a KE payload
455 static bool get_ke(private_quick_mode_t
*this, message_t
*message
)
457 ke_payload_t
*ke_payload
;
459 ke_payload
= (ke_payload_t
*)message
->get_payload(message
, KEY_EXCHANGE_V1
);
462 DBG1(DBG_IKE
, "KE payload missing");
465 this->dh
->set_other_public_value(this->dh
,
466 ke_payload
->get_key_exchange_data(ke_payload
));
471 * Select a traffic selector from configuration
473 static traffic_selector_t
* select_ts(private_quick_mode_t
*this, bool local
,
474 linked_list_t
*supplied
)
476 traffic_selector_t
*ts
;
477 linked_list_t
*list
, *hosts
;
479 hosts
= get_dynamic_hosts(this->ike_sa
, local
);
480 list
= this->config
->get_traffic_selectors(this->config
,
481 local
, supplied
, hosts
);
482 hosts
->destroy(hosts
);
483 if (list
->get_first(list
, (void**)&ts
) == SUCCESS
)
489 DBG1(DBG_IKE
, "%s traffic selector missing in configuration",
490 local ?
"local" : "local");
493 list
->destroy_offset(list
, offsetof(traffic_selector_t
, destroy
));
498 * Add selected traffic selectors to message
500 static void add_ts(private_quick_mode_t
*this, message_t
*message
)
502 id_payload_t
*id_payload
;
507 hsi
= this->ike_sa
->get_my_host(this->ike_sa
);
508 hsr
= this->ike_sa
->get_other_host(this->ike_sa
);
512 hsr
= this->ike_sa
->get_my_host(this->ike_sa
);
513 hsi
= this->ike_sa
->get_other_host(this->ike_sa
);
515 /* add ID payload only if negotiating non host2host tunnels */
516 if (!this->tsi
->is_host(this->tsi
, hsi
) ||
517 !this->tsr
->is_host(this->tsr
, hsr
) ||
518 this->tsi
->get_protocol(this->tsi
) ||
519 this->tsr
->get_protocol(this->tsr
) ||
520 this->tsi
->get_from_port(this->tsi
) ||
521 this->tsr
->get_from_port(this->tsr
) ||
522 this->tsi
->get_to_port(this->tsi
) != 65535 ||
523 this->tsr
->get_to_port(this->tsr
) != 65535)
525 id_payload
= id_payload_create_from_ts(this->tsi
);
526 message
->add_payload(message
, &id_payload
->payload_interface
);
527 id_payload
= id_payload_create_from_ts(this->tsr
);
528 message
->add_payload(message
, &id_payload
->payload_interface
);
533 * Get traffic selectors from received message
535 static bool get_ts(private_quick_mode_t
*this, message_t
*message
)
537 traffic_selector_t
*tsi
= NULL
, *tsr
= NULL
;
538 enumerator_t
*enumerator
;
539 id_payload_t
*id_payload
;
544 enumerator
= message
->create_payload_enumerator(message
);
545 while (enumerator
->enumerate(enumerator
, &payload
))
547 if (payload
->get_type(payload
) == ID_V1
)
549 id_payload
= (id_payload_t
*)payload
;
553 tsi
= id_payload
->get_ts(id_payload
);
558 tsr
= id_payload
->get_ts(id_payload
);
563 enumerator
->destroy(enumerator
);
565 /* create host2host selectors if ID payloads missing */
568 hsi
= this->ike_sa
->get_my_host(this->ike_sa
);
569 hsr
= this->ike_sa
->get_other_host(this->ike_sa
);
573 hsr
= this->ike_sa
->get_my_host(this->ike_sa
);
574 hsi
= this->ike_sa
->get_other_host(this->ike_sa
);
578 tsi
= traffic_selector_create_from_subnet(hsi
->clone(hsi
),
579 hsi
->get_family(hsi
) == AF_INET ?
32 : 128, 0, 0, 65535);
583 tsr
= traffic_selector_create_from_subnet(hsr
->clone(hsr
),
584 hsr
->get_family(hsr
) == AF_INET ?
32 : 128, 0, 0, 65535);
586 if (this->mode
== MODE_TRANSPORT
&& this->udp
&&
587 (!tsi
->is_host(tsi
, hsi
) || !tsr
->is_host(tsr
, hsr
)))
588 { /* change TS in case of a NAT in transport mode */
589 DBG2(DBG_IKE
, "changing received traffic selectors %R=== %R due to NAT",
591 tsi
->set_address(tsi
, hsi
);
592 tsr
->set_address(tsr
, hsr
);
597 traffic_selector_t
*tsisub
, *tsrsub
;
599 /* check if peer selection is valid */
600 tsisub
= this->tsi
->get_subset(this->tsi
, tsi
);
601 tsrsub
= this->tsr
->get_subset(this->tsr
, tsr
);
602 if (!tsisub
|| !tsrsub
)
604 DBG1(DBG_IKE
, "peer selected invalid traffic selectors: "
605 "%R for %R, %R for %R", tsi
, this->tsi
, tsr
, this->tsr
);
614 this->tsi
->destroy(this->tsi
);
615 this->tsr
->destroy(this->tsr
);
630 static encap_t
get_encap(ike_sa_t
* ike_sa
, bool udp
)
636 if (ike_sa
->supports_extension(ike_sa
, EXT_NATT_DRAFT_02_03
))
638 return ENCAP_UDP_DRAFT_00_03
;
644 * Get NAT-OA payload type (RFC 3947 or RFC 3947 drafts).
646 static payload_type_t
get_nat_oa_payload_type(ike_sa_t
*ike_sa
)
648 if (ike_sa
->supports_extension(ike_sa
, EXT_NATT_DRAFT_02_03
))
650 return NAT_OA_DRAFT_00_03_V1
;
656 * Add NAT-OA payloads
658 static void add_nat_oa_payloads(private_quick_mode_t
*this, message_t
*message
)
660 identification_t
*id
;
661 id_payload_t
*nat_oa
;
663 payload_type_t nat_oa_payload_type
;
665 src
= message
->get_source(message
);
666 dst
= message
->get_destination(message
);
668 src
= this->initiator ? src
: dst
;
669 dst
= this->initiator ? dst
: src
;
671 nat_oa_payload_type
= get_nat_oa_payload_type(this->ike_sa
);
673 /* first NAT-OA is the initiator's address */
674 id
= identification_create_from_sockaddr(src
->get_sockaddr(src
));
675 nat_oa
= id_payload_create_from_identification(nat_oa_payload_type
, id
);
676 message
->add_payload(message
, (payload_t
*)nat_oa
);
679 /* second NAT-OA is that of the responder */
680 id
= identification_create_from_sockaddr(dst
->get_sockaddr(dst
));
681 nat_oa
= id_payload_create_from_identification(nat_oa_payload_type
, id
);
682 message
->add_payload(message
, (payload_t
*)nat_oa
);
689 static void get_lifetimes(private_quick_mode_t
*this)
693 lft
= this->config
->get_lifetime(this->config
);
696 this->lifetime
= lft
->time
.life
;
698 else if (lft
->bytes
.life
)
700 this->lifebytes
= lft
->bytes
.life
;
706 * Check and apply lifetimes
708 static void apply_lifetimes(private_quick_mode_t
*this, sa_payload_t
*sa_payload
)
713 lifetime
= sa_payload
->get_lifetime(sa_payload
);
714 lifebytes
= sa_payload
->get_lifebytes(sa_payload
);
715 if (this->lifetime
!= lifetime
)
717 DBG1(DBG_IKE
, "received %us lifetime, configured %us",
718 lifetime
, this->lifetime
);
719 this->lifetime
= lifetime
;
721 if (this->lifebytes
!= lifebytes
)
723 DBG1(DBG_IKE
, "received %llu lifebytes, configured %llu",
724 lifebytes
, this->lifebytes
);
725 this->lifebytes
= lifebytes
;
730 * Set the task ready to build notify error message
732 static status_t
send_notify(private_quick_mode_t
*this, notify_type_t type
)
734 notify_payload_t
*notify
;
736 notify
= notify_payload_create_from_protocol_and_type(NOTIFY_V1
,
738 notify
->set_spi(notify
, this->spi_i
);
740 this->ike_sa
->queue_task(this->ike_sa
,
741 (task_t
*)informational_create(this->ike_sa
, notify
));
742 /* cancel all active/passive tasks in favour of informational */
743 this->ike_sa
->flush_queue(this->ike_sa
,
744 this->initiator ? TASK_QUEUE_ACTIVE
: TASK_QUEUE_PASSIVE
);
748 METHOD(task_t
, build_i
, status_t
,
749 private_quick_mode_t
*this, message_t
*message
)
755 enumerator_t
*enumerator
;
756 sa_payload_t
*sa_payload
;
757 linked_list_t
*list
, *tsi
, *tsr
;
758 proposal_t
*proposal
;
759 diffie_hellman_group_t group
;
762 this->udp
= this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
);
763 this->mode
= this->config
->get_mode(this->config
);
764 this->child_sa
= child_sa_create(
765 this->ike_sa
->get_my_host(this->ike_sa
),
766 this->ike_sa
->get_other_host(this->ike_sa
),
767 this->config
, this->reqid
, this->udp
);
769 if (this->udp
&& this->mode
== MODE_TRANSPORT
)
771 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
772 add_nat_oa_payloads(this, message
);
775 if (this->config
->use_ipcomp(this->config
))
779 DBG1(DBG_IKE
, "IPComp is not supported if either peer is "
780 "natted, IPComp disabled");
784 this->cpi_i
= this->child_sa
->alloc_cpi(this->child_sa
);
787 DBG1(DBG_IKE
, "unable to allocate a CPI from kernel, "
793 this->spi_i
= this->child_sa
->alloc_spi(this->child_sa
, PROTO_ESP
);
796 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
799 group
= this->config
->get_dh_group(this->config
);
800 if (group
!= MODP_NONE
)
802 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
806 DBG1(DBG_IKE
, "configured DH group %N not supported",
807 diffie_hellman_group_names
, group
);
812 list
= this->config
->get_proposals(this->config
, FALSE
);
813 enumerator
= list
->create_enumerator(list
);
814 while (enumerator
->enumerate(enumerator
, &proposal
))
816 if (group
!= MODP_NONE
)
818 if (!proposal
->has_dh_group(proposal
, group
))
820 list
->remove_at(list
, enumerator
);
821 proposal
->destroy(proposal
);
824 proposal
->strip_dh(proposal
, group
);
826 proposal
->set_spi(proposal
, this->spi_i
);
828 enumerator
->destroy(enumerator
);
831 encap
= get_encap(this->ike_sa
, this->udp
);
832 sa_payload
= sa_payload_create_from_proposals_v1(list
,
833 this->lifetime
, this->lifebytes
, AUTH_NONE
,
834 this->mode
, encap
, this->cpi_i
);
835 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
836 message
->add_payload(message
, &sa_payload
->payload_interface
);
838 if (!add_nonce(this, &this->nonce_i
, message
))
842 if (group
!= MODP_NONE
)
844 add_ke(this, message
);
848 this->tsi
= select_ts(this, TRUE
, NULL
);
852 this->tsr
= select_ts(this, FALSE
, NULL
);
854 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
855 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
856 this->tsi
= this->tsr
= NULL
;
857 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
858 NARROW_INITIATOR_PRE_AUTH
, tsi
, tsr
);
859 tsi
->remove_first(tsi
, (void**)&this->tsi
);
860 tsr
->remove_first(tsr
, (void**)&this->tsr
);
861 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
862 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
863 if (!this->tsi
|| !this->tsr
)
867 add_ts(this, message
);
880 * Check for notify errors, return TRUE if error found
882 static bool has_notify_errors(private_quick_mode_t
*this, message_t
*message
)
884 enumerator_t
*enumerator
;
888 enumerator
= message
->create_payload_enumerator(message
);
889 while (enumerator
->enumerate(enumerator
, &payload
))
891 if (payload
->get_type(payload
) == NOTIFY_V1
)
893 notify_payload_t
*notify
;
896 notify
= (notify_payload_t
*)payload
;
897 type
= notify
->get_notify_type(notify
);
901 DBG1(DBG_IKE
, "received %N error notify",
902 notify_type_names
, type
);
907 DBG1(DBG_IKE
, "received %N notify", notify_type_names
, type
);
911 enumerator
->destroy(enumerator
);
917 * Check if this is a rekey for an existing CHILD_SA, reuse reqid if so
919 static void check_for_rekeyed_child(private_quick_mode_t
*this)
921 enumerator_t
*enumerator
, *policies
;
922 traffic_selector_t
*local
, *remote
;
923 child_sa_t
*child_sa
;
925 enumerator
= this->ike_sa
->create_child_sa_enumerator(this->ike_sa
);
926 while (this->reqid
== 0 && enumerator
->enumerate(enumerator
, &child_sa
))
928 if (child_sa
->get_state(child_sa
) == CHILD_INSTALLED
&&
929 streq(child_sa
->get_name(child_sa
),
930 this->config
->get_name(this->config
)))
932 policies
= child_sa
->create_policy_enumerator(child_sa
);
933 if (policies
->enumerate(policies
, &local
, &remote
))
935 if (local
->equals(local
, this->tsr
) &&
936 remote
->equals(remote
, this->tsi
) &&
937 this->proposal
->equals(this->proposal
,
938 child_sa
->get_proposal(child_sa
)))
940 this->reqid
= child_sa
->get_reqid(child_sa
);
941 this->rekey
= child_sa
->get_spi(child_sa
, TRUE
);
942 child_sa
->set_state(child_sa
, CHILD_REKEYING
);
943 DBG1(DBG_IKE
, "detected rekeying of CHILD_SA %s{%u}",
944 child_sa
->get_name(child_sa
), this->reqid
);
947 policies
->destroy(policies
);
950 enumerator
->destroy(enumerator
);
953 METHOD(task_t
, process_r
, status_t
,
954 private_quick_mode_t
*this, message_t
*message
)
960 sa_payload_t
*sa_payload
;
961 linked_list_t
*tsi
, *tsr
, *hostsi
, *hostsr
, *list
= NULL
;
962 peer_cfg_t
*peer_cfg
;
966 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
967 SECURITY_ASSOCIATION_V1
);
970 DBG1(DBG_IKE
, "sa payload missing");
971 return send_notify(this, INVALID_PAYLOAD_TYPE
);
974 this->mode
= sa_payload
->get_encap_mode(sa_payload
, &this->udp
);
976 if (!get_ts(this, message
))
980 peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
981 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
982 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
983 this->tsi
= this->tsr
= NULL
;
984 hostsi
= get_dynamic_hosts(this->ike_sa
, FALSE
);
985 hostsr
= get_dynamic_hosts(this->ike_sa
, TRUE
);
986 this->config
= peer_cfg
->select_child_cfg(peer_cfg
, tsr
, tsi
,
988 hostsi
->destroy(hostsi
);
989 hostsr
->destroy(hostsr
);
992 this->tsi
= select_ts(this, FALSE
, tsi
);
993 this->tsr
= select_ts(this, TRUE
, tsr
);
995 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
996 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
997 if (!this->config
|| !this->tsi
|| !this->tsr
)
999 DBG1(DBG_IKE
, "no matching CHILD_SA config found");
1000 return send_notify(this, INVALID_ID_INFORMATION
);
1003 if (this->config
->use_ipcomp(this->config
))
1005 if (this->ike_sa
->has_condition(this->ike_sa
, COND_NAT_ANY
))
1007 DBG1(DBG_IKE
, "IPComp is not supported if either peer is "
1008 "natted, IPComp disabled");
1012 list
= sa_payload
->get_ipcomp_proposals(sa_payload
,
1014 if (!list
->get_count(list
))
1016 DBG1(DBG_IKE
, "expected IPComp proposal but peer did "
1017 "not send one, IPComp disabled");
1022 if (!list
|| !list
->get_count(list
))
1025 list
= sa_payload
->get_proposals(sa_payload
);
1027 private = this->ike_sa
->supports_extension(this->ike_sa
,
1029 this->proposal
= this->config
->select_proposal(this->config
,
1030 list
, FALSE
, private);
1031 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1033 get_lifetimes(this);
1034 apply_lifetimes(this, sa_payload
);
1036 if (!this->proposal
)
1038 DBG1(DBG_IKE
, "no matching proposal found, sending %N",
1039 notify_type_names
, NO_PROPOSAL_CHOSEN
);
1040 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1042 this->spi_i
= this->proposal
->get_spi(this->proposal
);
1044 if (!get_nonce(this, &this->nonce_i
, message
))
1046 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1049 if (this->proposal
->get_algorithm(this->proposal
,
1050 DIFFIE_HELLMAN_GROUP
, &group
, NULL
))
1052 this->dh
= this->keymat
->keymat
.create_dh(&this->keymat
->keymat
,
1056 DBG1(DBG_IKE
, "negotiated DH group %N not supported",
1057 diffie_hellman_group_names
, group
);
1058 return send_notify(this, INVALID_KEY_INFORMATION
);
1060 if (!get_ke(this, message
))
1062 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1066 check_for_rekeyed_child(this);
1068 this->child_sa
= child_sa_create(
1069 this->ike_sa
->get_my_host(this->ike_sa
),
1070 this->ike_sa
->get_other_host(this->ike_sa
),
1071 this->config
, this->reqid
, this->udp
);
1073 tsi
= linked_list_create_with_items(this->tsi
, NULL
);
1074 tsr
= linked_list_create_with_items(this->tsr
, NULL
);
1075 this->tsi
= this->tsr
= NULL
;
1076 charon
->bus
->narrow(charon
->bus
, this->child_sa
,
1077 NARROW_RESPONDER
, tsr
, tsi
);
1078 if (tsi
->remove_first(tsi
, (void**)&this->tsi
) != SUCCESS
||
1079 tsr
->remove_first(tsr
, (void**)&this->tsr
) != SUCCESS
)
1081 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1082 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1083 return send_notify(this, INVALID_ID_INFORMATION
);
1085 tsi
->destroy_offset(tsi
, offsetof(traffic_selector_t
, destroy
));
1086 tsr
->destroy_offset(tsr
, offsetof(traffic_selector_t
, destroy
));
1092 if (message
->get_exchange_type(message
) == INFORMATIONAL_V1
||
1093 has_notify_errors(this, message
))
1099 ike_sa_t
*ike_sa
= this->ike_sa
;
1102 task
= (task_t
*)quick_delete_create(this->ike_sa
,
1103 this->proposal
->get_protocol(this->proposal
),
1104 this->spi_i
, TRUE
, TRUE
);
1105 /* flush_queue() destroys the current task */
1106 ike_sa
->flush_queue(ike_sa
, TASK_QUEUE_PASSIVE
);
1107 ike_sa
->queue_task(ike_sa
, task
);
1108 return ALREADY_DONE
;
1117 METHOD(task_t
, build_r
, status_t
,
1118 private_quick_mode_t
*this, message_t
*message
)
1120 switch (this->state
)
1124 sa_payload_t
*sa_payload
;
1127 this->spi_r
= this->child_sa
->alloc_spi(this->child_sa
, PROTO_ESP
);
1130 DBG1(DBG_IKE
, "allocating SPI from kernel failed");
1131 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1133 this->proposal
->set_spi(this->proposal
, this->spi_r
);
1137 this->cpi_r
= this->child_sa
->alloc_cpi(this->child_sa
);
1140 DBG1(DBG_IKE
, "unable to allocate a CPI from "
1141 "kernel, IPComp disabled");
1142 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1146 if (this->udp
&& this->mode
== MODE_TRANSPORT
)
1148 /* TODO-IKEv1: disable NAT-T for TRANSPORT mode by default? */
1149 add_nat_oa_payloads(this, message
);
1152 encap
= get_encap(this->ike_sa
, this->udp
);
1153 sa_payload
= sa_payload_create_from_proposal_v1(this->proposal
,
1154 this->lifetime
, this->lifebytes
, AUTH_NONE
,
1155 this->mode
, encap
, this->cpi_r
);
1156 message
->add_payload(message
, &sa_payload
->payload_interface
);
1158 if (!add_nonce(this, &this->nonce_r
, message
))
1164 add_ke(this, message
);
1167 add_ts(this, message
);
1169 this->state
= QM_NEGOTIATED
;
1177 METHOD(task_t
, process_i
, status_t
,
1178 private_quick_mode_t
*this, message_t
*message
)
1180 switch (this->state
)
1184 sa_payload_t
*sa_payload
;
1185 linked_list_t
*list
= NULL
;
1188 sa_payload
= (sa_payload_t
*)message
->get_payload(message
,
1189 SECURITY_ASSOCIATION_V1
);
1192 DBG1(DBG_IKE
, "sa payload missing");
1193 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1197 list
= sa_payload
->get_ipcomp_proposals(sa_payload
,
1199 if (!list
->get_count(list
))
1201 DBG1(DBG_IKE
, "peer did not acccept our IPComp proposal, "
1206 if (!list
|| !list
->get_count(list
))
1209 list
= sa_payload
->get_proposals(sa_payload
);
1211 private = this->ike_sa
->supports_extension(this->ike_sa
,
1213 this->proposal
= this->config
->select_proposal(this->config
,
1214 list
, FALSE
, private);
1215 list
->destroy_offset(list
, offsetof(proposal_t
, destroy
));
1216 if (!this->proposal
)
1218 DBG1(DBG_IKE
, "no matching proposal found");
1219 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1221 this->spi_r
= this->proposal
->get_spi(this->proposal
);
1223 apply_lifetimes(this, sa_payload
);
1225 if (!get_nonce(this, &this->nonce_r
, message
))
1227 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1229 if (this->dh
&& !get_ke(this, message
))
1231 return send_notify(this, INVALID_KEY_INFORMATION
);
1233 if (!get_ts(this, message
))
1235 return send_notify(this, INVALID_PAYLOAD_TYPE
);
1239 return send_notify(this, NO_PROPOSAL_CHOSEN
);
1241 this->state
= QM_NEGOTIATED
;
1249 METHOD(task_t
, get_type
, task_type_t
,
1250 private_quick_mode_t
*this)
1252 return TASK_QUICK_MODE
;
1255 METHOD(quick_mode_t
, use_reqid
, void,
1256 private_quick_mode_t
*this, u_int32_t reqid
)
1258 this->reqid
= reqid
;
1261 METHOD(quick_mode_t
, rekey
, void,
1262 private_quick_mode_t
*this, u_int32_t spi
)
1267 METHOD(task_t
, migrate
, void,
1268 private_quick_mode_t
*this, ike_sa_t
*ike_sa
)
1270 chunk_free(&this->nonce_i
);
1271 chunk_free(&this->nonce_r
);
1272 DESTROY_IF(this->tsi
);
1273 DESTROY_IF(this->tsr
);
1274 DESTROY_IF(this->proposal
);
1275 DESTROY_IF(this->child_sa
);
1276 DESTROY_IF(this->dh
);
1278 this->ike_sa
= ike_sa
;
1279 this->keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
);
1280 this->state
= QM_INIT
;
1283 this->proposal
= NULL
;
1284 this->child_sa
= NULL
;
1289 if (!this->initiator
)
1291 DESTROY_IF(this->config
);
1292 this->config
= NULL
;
1296 METHOD(task_t
, destroy
, void,
1297 private_quick_mode_t
*this)
1299 chunk_free(&this->nonce_i
);
1300 chunk_free(&this->nonce_r
);
1301 DESTROY_IF(this->tsi
);
1302 DESTROY_IF(this->tsr
);
1303 DESTROY_IF(this->proposal
);
1304 DESTROY_IF(this->child_sa
);
1305 DESTROY_IF(this->config
);
1306 DESTROY_IF(this->dh
);
1311 * Described in header.
1313 quick_mode_t
*quick_mode_create(ike_sa_t
*ike_sa
, child_cfg_t
*config
,
1314 traffic_selector_t
*tsi
, traffic_selector_t
*tsr
)
1316 private_quick_mode_t
*this;
1321 .get_type
= _get_type
,
1322 .migrate
= _migrate
,
1323 .destroy
= _destroy
,
1325 .use_reqid
= _use_reqid
,
1329 .initiator
= config
!= NULL
,
1331 .keymat
= (keymat_v1_t
*)ike_sa
->get_keymat(ike_sa
),
1333 .tsi
= tsi ? tsi
->clone(tsi
) : NULL
,
1334 .tsr
= tsr ? tsr
->clone(tsr
) : NULL
,
1339 this->public.task
.build
= _build_i
;
1340 this->public.task
.process
= _process_i
;
1344 this->public.task
.build
= _build_r
;
1345 this->public.task
.process
= _process_r
;
1348 return &this->public;