1 /* Mode config related functions
2 * Copyright (C) 2001-2002 Colubris Networks
3 * Copyright (C) 2003 Sean Mathews - Nu Tech Software Solutions, inc.
4 * Copyright (C) 2003-2004 Xelerance Corporation
5 * Copyright (C) 2006-2010 Andreas Steffen - Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * This code originally written by Colubris Networks, Inc.
18 * Extraction of patch and porting to 1.99 codebases by Xelerance Corporation
19 * Porting to 2.x by Sean Mathews
30 #include <utils/linked_list.h>
31 #include <crypto/prfs/prf.h>
33 #include "constants.h"
38 #include "ipsec_doi.h"
45 #define MAX_XAUTH_TRIES 3
47 #define DEFAULT_UNITY_BANNER "Welcome to strongSwan - the Linux VPN Solution!\n"
50 * Creates a modecfg_attribute_t object
52 static modecfg_attribute_t
*modecfg_attribute_create(configuration_attribute_type_t type
,
55 modecfg_attribute_t
*this;
57 this = malloc_thing(modecfg_attribute_t
);
58 this->type
= ((u_int16_t
)type
) & 0x7FFF;
60 this->value
= chunk_clone(value
);
67 * Creates a modecfg_attribute_t object coded in TV format
69 static modecfg_attribute_t
*modecfg_attribute_create_tv(configuration_attribute_type_t type
,
72 modecfg_attribute_t
*this;
74 this = modecfg_attribute_create(type
, chunk_empty
);
75 this->value
.len
= value
;
82 * Destroys a modecfg_attribute_t object
84 void modecfg_attribute_destroy(modecfg_attribute_t
*this)
86 free(this->value
.ptr
);
91 * Get attributes to be sent to client
93 static void get_attributes(connection_t
*c
, linked_list_t
*ca_list
)
95 configuration_attribute_type_t type
;
96 identification_t
*client_id
;
97 modecfg_attribute_t
*ca
;
98 enumerator_t
*enumerator
;
100 host_t
*vip
= NULL
, *requested_vip
= NULL
;
101 bool want_unity_banner
= FALSE
;
105 /* always send banner in ModeCfg push mode */
106 if (ca_list
->get_count(ca_list
) == 0)
108 want_unity_banner
= TRUE
;
112 /* scan list of requested attributes in ModeCfg pull mode */
113 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
)
117 case INTERNAL_IP4_ADDRESS
:
118 case INTERNAL_IP6_ADDRESS
:
122 family
= (ca
->type
== INTERNAL_IP4_ADDRESS
) ? AF_INET
: AF_INET6
;
123 requested_vip
= (ca
->value
.len
) ?
124 host_create_from_chunk(family
, ca
->value
, 0) :
125 host_create_any(family
);
126 plog("peer requested virtual IP %H", requested_vip
);
131 want_unity_banner
= TRUE
;
137 modecfg_attribute_destroy(ca
);
140 if (requested_vip
== NULL
)
142 requested_vip
= host_create_any(AF_INET
);
145 client_id
= (c
->xauth_identity
) ? c
->xauth_identity
: c
->spd
.that
.id
;
147 /* if no virtual IP has been assigned yet - acquire one */
148 if (c
->spd
.that
.host_srcip
->is_anyaddr(c
->spd
.that
.host_srcip
))
150 if (c
->spd
.that
.pool
)
152 vip
= hydra
->attributes
->acquire_address(hydra
->attributes
,
153 c
->spd
.that
.pool
, client_id
, requested_vip
);
156 c
->spd
.that
.host_srcip
->destroy(c
->spd
.that
.host_srcip
);
157 c
->spd
.that
.host_srcip
= vip
;
162 plog("no virtual IP found");
166 requested_vip
->destroy(requested_vip
);
168 /* if we have a virtual IP address - send it */
169 if (!c
->spd
.that
.host_srcip
->is_anyaddr(c
->spd
.that
.host_srcip
))
171 vip
= c
->spd
.that
.host_srcip
;
172 plog("assigning virtual IP %H to peer", vip
);
173 family
= vip
->get_family(vip
);
174 ca
= modecfg_attribute_create((family
== AF_INET
) ?
175 INTERNAL_IP4_ADDRESS
:
176 INTERNAL_IP6_ADDRESS
,
177 vip
->get_address(vip
));
178 ca_list
->insert_last(ca_list
, ca
);
180 /* set the remote client subnet to virtual IP */
181 c
->spd
.that
.client
.addr
= *(ip_address
*)vip
->get_sockaddr(vip
);
182 c
->spd
.that
.client
.maskbits
= (family
== AF_INET
) ?
32 : 128;
183 c
->spd
.that
.has_client
= TRUE
;
186 /* assign attributes from registered providers */
187 enumerator
= hydra
->attributes
->create_responder_enumerator(hydra
->attributes
,
188 c
->spd
.that
.pool
, client_id
, vip
);
189 while (enumerator
->enumerate(enumerator
, &type
, &value
))
191 ca
= modecfg_attribute_create(type
, value
);
192 ca_list
->insert_last(ca_list
, ca
);
193 if (type
== UNITY_BANNER
)
195 want_unity_banner
= FALSE
;
198 enumerator
->destroy(enumerator
);
200 if (want_unity_banner
)
202 ca
= modecfg_attribute_create(UNITY_BANNER
,
203 chunk_create(DEFAULT_UNITY_BANNER
,
204 strlen(DEFAULT_UNITY_BANNER
)));
205 ca_list
->insert_last(ca_list
, ca
);
210 * Set srcip and client subnet to internal IP address
212 static bool set_attributes(connection_t
*c
, linked_list_t
*ca_list
)
215 modecfg_attribute_t
*ca
, *ca_handler
;
216 enumerator_t
*enumerator
;
217 bool vip_set
= FALSE
;
219 enumerator
= ca_list
->create_enumerator(ca_list
);
220 while (enumerator
->enumerate(enumerator
, &ca
))
222 int family
= AF_INET6
;
223 attribute_handler_t
*handler
= NULL
;
228 case INTERNAL_IP4_ADDRESS
:
231 case INTERNAL_IP6_ADDRESS
:
232 if (ca
->value
.len
== 0)
234 vip
= host_create_any(family
);
238 /* skip prefix byte in IPv6 payload*/
239 if (family
== AF_INET6
)
243 vip
= host_create_from_chunk(family
, ca
->value
, 0);
247 srcip
= c
->spd
.this.host_srcip
;
249 if (srcip
->is_anyaddr(srcip
) || srcip
->equals(srcip
, vip
))
251 plog("setting virtual IP source address to %H", vip
);
255 plog("replacing virtual IP source address %H by %H",
258 srcip
->destroy(srcip
);
259 c
->spd
.this.host_srcip
= vip
;
261 /* setting client subnet to vip/32 */
262 addrtosubnet((ip_address
*)vip
->get_sockaddr(vip
),
263 &c
->spd
.this.client
);
264 setportof(0, &c
->spd
.this.client
.addr
);
265 c
->spd
.this.has_client
= TRUE
;
270 case APPLICATION_VERSION
:
274 if (ca
->value
.len
> 0)
276 DBG(DBG_PARSING
| DBG_CONTROLMORE
,
277 DBG_log(" '%.*s'", ca
->value
.len
, ca
->value
.ptr
)
285 /* find the first handler which requested this attribute */
286 e
= c
->requested
->create_enumerator(c
->requested
);
287 while (e
->enumerate(e
, &ca_handler
))
289 if (ca_handler
->type
== ca
->type
)
291 handler
= ca_handler
->handler
;
297 /* and pass it to the handle function */
298 handler
= hydra
->attributes
->handle(hydra
->attributes
,
299 c
->spd
.that
.id
, handler
, ca
->type
, ca
->value
);
302 ca_handler
= modecfg_attribute_create(ca
->type
, ca
->value
);
303 ca_handler
->handler
= handler
;
305 if (c
->attributes
== NULL
)
307 c
->attributes
= linked_list_create();
309 c
->attributes
->insert_last(c
->attributes
, ca_handler
);
312 enumerator
->destroy(enumerator
);
313 c
->requested
->destroy_function(c
->requested
, (void*)modecfg_attribute_destroy
);
319 * Register configuration attribute handlers
321 static void register_attribute_handlers(connection_t
*c
)
323 configuration_attribute_type_t type
;
324 modecfg_attribute_t
*ca
;
326 attribute_handler_t
*handler
;
327 enumerator_t
*enumerator
;
329 /* add configuration attributes requested by handlers */
330 if (c
->requested
== NULL
)
332 c
->requested
= linked_list_create();
334 enumerator
= hydra
->attributes
->create_initiator_enumerator(
335 hydra
->attributes
,c
->spd
.that
.id
, c
->spd
.this.host_srcip
);
336 while (enumerator
->enumerate(enumerator
, &handler
, &type
, &value
))
338 ca
= modecfg_attribute_create(type
, value
);
339 ca
->handler
= handler
;
340 c
->requested
->insert_last(c
->requested
, ca
);
342 enumerator
->destroy(enumerator
);
346 * Compute HASH of Mode Config.
348 static size_t modecfg_hash(u_char
*dest
, u_char
*start
, u_char
*roof
,
349 const struct state
*st
)
351 chunk_t msgid_chunk
= chunk_from_thing(st
->st_msgid
);
352 chunk_t msg_chunk
= { start
, roof
- start
};
353 size_t prf_block_size
;
354 pseudo_random_function_t prf_alg
;
357 prf_alg
= oakley_to_prf(st
->st_oakley
.hash
);
358 prf
= lib
->crypto
->create_prf(lib
->crypto
, prf_alg
);
359 prf
->set_key(prf
, st
->st_skeyid_a
);
360 prf
->get_bytes(prf
, msgid_chunk
, NULL
);
361 prf
->get_bytes(prf
, msg_chunk
, dest
);
362 prf_block_size
= prf
->get_block_size(prf
);
366 DBG_log("ModeCfg HASH computed:");
367 DBG_dump("", dest
, prf_block_size
)
369 return prf_block_size
;
374 * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
376 static stf_status
modecfg_build_msg(struct state
*st
, pb_stream
*rbody
,
377 u_int16_t msg_type
, linked_list_t
*ca_list
,
380 u_char
*r_hash_start
, *r_hashval
;
381 struct isakmp_mode_attr attrh
;
382 struct isakmp_attribute attr
;
383 pb_stream strattr
,attrval
;
384 enumerator_t
*enumerator
;
385 modecfg_attribute_t
*ca
;
387 START_HASH_PAYLOAD(*rbody
, ISAKMP_NEXT_ATTR
);
389 attrh
.isama_np
= ISAKMP_NEXT_NONE
;
390 attrh
.isama_type
= msg_type
;
391 attrh
.isama_identifier
= ap_id
;
393 if (!out_struct(&attrh
, &isakmp_attr_desc
, rbody
, &strattr
))
395 return STF_INTERNAL_ERROR
;
398 enumerator
= ca_list
->create_enumerator(ca_list
);
399 while (enumerator
->enumerate(enumerator
, &ca
))
402 DBG_log("building %N attribute", configuration_attribute_type_names
, ca
->type
)
406 attr
.isaat_af_type
= ca
->type
| ISAKMP_ATTR_AF_TV
;
407 attr
.isaat_lv
= ca
->value
.len
;
408 out_struct(&attr
, &isakmp_modecfg_attribute_desc
, &strattr
, &attrval
);
414 attr
.isaat_af_type
= ca
->type
| ISAKMP_ATTR_AF_TLV
;
415 out_struct(&attr
, &isakmp_modecfg_attribute_desc
, &strattr
, &attrval
);
416 snprintf(buf
, BUF_LEN
, "%N", configuration_attribute_type_names
, ca
->type
);
417 out_raw(ca
->value
.ptr
, ca
->value
.len
, &attrval
, buf
);
419 close_output_pbs(&attrval
);
421 enumerator
->destroy(enumerator
);
422 close_output_pbs(&strattr
);
424 modecfg_hash(r_hashval
, r_hash_start
, rbody
->cur
, st
);
425 close_message(rbody
);
426 encrypt_message(rbody
, st
);
431 * Send ModeCfg message
433 static stf_status
modecfg_send_msg(struct state
*st
, int isama_type
,
434 linked_list_t
*ca_list
)
441 init_pbs(&msg
, buf
, sizeof(buf
), "ModeCfg msg buffer");
443 /* this is the beginning of a new exchange */
444 st
->st_msgid
= generate_msgid(st
);
445 init_phase2_iv(st
, &st
->st_msgid
);
449 struct isakmp_hdr hdr
;
451 zero(&hdr
); /* default to 0 */
452 hdr
.isa_version
= ISAKMP_MAJOR_VERSION
<< ISA_MAJ_SHIFT
| ISAKMP_MINOR_VERSION
;
453 hdr
.isa_np
= ISAKMP_NEXT_HASH
;
454 hdr
.isa_xchg
= ISAKMP_XCHG_MODE_CFG
;
455 hdr
.isa_flags
= ISAKMP_FLAG_ENCRYPTION
;
456 memcpy(hdr
.isa_icookie
, st
->st_icookie
, COOKIE_SIZE
);
457 memcpy(hdr
.isa_rcookie
, st
->st_rcookie
, COOKIE_SIZE
);
458 hdr
.isa_msgid
= st
->st_msgid
;
460 if (!out_struct(&hdr
, &isakmp_hdr_desc
, &msg
, &rbody
))
462 return STF_INTERNAL_ERROR
;
466 /* ATTR out with isama_id of 0 */
467 modecfg_build_msg(st
, &rbody
, isama_type
, ca_list
, 0);
469 free(st
->st_tpacket
.ptr
);
470 st
->st_tpacket
= chunk_create(msg
.start
, pbs_offset(&msg
));
471 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
474 send_packet(st
, "ModeCfg msg");
476 if (st
->st_event
->ev_type
!= EVENT_RETRANSMIT
)
479 event_schedule(EVENT_RETRANSMIT
, EVENT_RETRANSMIT_DELAY_0
, st
);
485 * Parse a ModeCfg attribute payload
487 static stf_status
modecfg_parse_attributes(pb_stream
*attrs
, linked_list_t
*ca_list
)
489 struct isakmp_attribute attr
;
494 modecfg_attribute_t
*ca
;
496 while (pbs_left(attrs
) >= sizeof(struct isakmp_attribute
))
498 if (!in_struct(&attr
, &isakmp_modecfg_attribute_desc
, attrs
, &strattr
))
502 attr_type
= attr
.isaat_af_type
& ISAKMP_ATTR_RTYPE_MASK
;
503 attr_len
= attr
.isaat_lv
;
505 DBG_log("processing %N attribute",
506 configuration_attribute_type_names
, attr_type
)
511 case INTERNAL_IP4_ADDRESS
:
512 case INTERNAL_IP4_NETMASK
:
513 case INTERNAL_IP4_DNS
:
514 case INTERNAL_IP4_NBNS
:
515 case INTERNAL_ADDRESS_EXPIRY
:
516 case INTERNAL_IP4_DHCP
:
517 if (attr_len
!= 4 && attr_len
!= 0)
522 case INTERNAL_IP4_SUBNET
:
523 if (attr_len
!= 8 && attr_len
!= 0)
528 case INTERNAL_IP6_NETMASK
:
529 case INTERNAL_IP6_DNS
:
530 case INTERNAL_IP6_NBNS
:
531 case INTERNAL_IP6_DHCP
:
532 if (attr_len
!= 16 && attr_len
!= 0)
537 case INTERNAL_IP6_ADDRESS
:
538 if (attr_len
!= 17 && attr_len
!= 16 && attr_len
!= 0)
543 case INTERNAL_IP6_SUBNET
:
544 if (attr_len
!= 17 && attr_len
!= 0)
549 case SUPPORTED_ATTRIBUTES
:
555 case APPLICATION_VERSION
:
557 /* XAUTH attributes */
560 case XAUTH_USER_NAME
:
561 case XAUTH_USER_PASSWORD
:
564 case XAUTH_CHALLENGE
:
569 /* Microsoft attributes */
570 case INTERNAL_IP4_SERVER
:
571 case INTERNAL_IP6_SERVER
:
573 /* Cisco Unity attributes */
575 case UNITY_SAVE_PASSWD
:
576 case UNITY_DEF_DOMAIN
:
577 case UNITY_SPLITDNS_NAME
:
578 case UNITY_SPLIT_INCLUDE
:
579 case UNITY_NATT_PORT
:
580 case UNITY_LOCAL_LAN
:
583 case UNITY_BACKUP_SERVERS
:
584 case UNITY_DDNS_HOSTNAME
:
587 plog("unknown attribute type (%u)", attr_type
);
592 if (attr
.isaat_af_type
& ISAKMP_ATTR_AF_TV
)
594 ca
= modecfg_attribute_create_tv(attr_type
, attr_len
);
598 attr_chunk
= chunk_create(strattr
.cur
, attr_len
);
599 ca
= modecfg_attribute_create(attr_type
, attr_chunk
);
601 ca_list
->insert_last(ca_list
, ca
);
606 plog("%N attribute has invalid size of %u octets",
607 configuration_attribute_type_names
, attr_type
, attr_len
);
612 * Parse a ModeCfg message
614 static stf_status
modecfg_parse_msg(struct msg_digest
*md
, int isama_type
,
615 u_int16_t
*isama_id
, linked_list_t
*ca_list
)
617 modecfg_attribute_t
*ca
;
618 struct state
*const st
= md
->st
;
619 struct payload_digest
*p
;
622 st
->st_msgid
= md
->hdr
.isa_msgid
;
624 CHECK_QUICK_HASH(md
, modecfg_hash(hash_val
, hash_pbs
->roof
,
625 md
->message_pbs
.roof
, st
), "MODECFG-HASH", "ISAKMP_CFG_MSG");
627 /* process the ModeCfg payloads received */
628 for (p
= md
->chain
[ISAKMP_NEXT_ATTR
]; p
!= NULL
; p
= p
->next
)
630 if (p
->payload
.attribute
.isama_type
== isama_type
)
632 *isama_id
= p
->payload
.attribute
.isama_identifier
;
634 stat
= modecfg_parse_attributes(&p
->pbs
, ca_list
);
637 /* return with a valid set of attributes */
643 plog("expected %s, got %s instead (ignored)"
644 , enum_name(&attr_msg_type_names
, isama_type
)
645 , enum_name(&attr_msg_type_names
, p
->payload
.attribute
.isama_type
));
647 stat
= modecfg_parse_attributes(&p
->pbs
, ca_list
);
650 /* abort if a parsing error occurred */
653 ca_list
->destroy_function(ca_list
, (void*)modecfg_attribute_destroy
);
657 /* discard the parsed attributes and look for another payload */
658 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
) {}
664 * Used in ModeCfg pull mode on the client (initiator)
666 * client -> CFG_REQUEST
667 * STF_OK transitions to STATE_MODE_CFG_I1
669 stf_status
modecfg_send_request(struct state
*st
)
671 connection_t
*c
= st
->st_connection
;
673 modecfg_attribute_t
*ca
;
674 enumerator_t
*enumerator
;
678 linked_list_t
*ca_list
= linked_list_create();
680 vip
= c
->spd
.this.host_srcip
;
681 value
= vip
->is_anyaddr(vip
) ? chunk_empty
: vip
->get_address(vip
);
682 family
= vip
->get_family(vip
);
683 ca
= modecfg_attribute_create((family
== AF_INET
) ?
684 INTERNAL_IP4_ADDRESS
: INTERNAL_IP6_ADDRESS
,
686 ca_list
->insert_last(ca_list
, ca
);
688 register_attribute_handlers(c
);
689 enumerator
= c
->requested
->create_enumerator(c
->requested
);
690 while (enumerator
->enumerate(enumerator
, &ca
))
692 ca
= modecfg_attribute_create(ca
->type
, chunk_empty
);
693 ca_list
->insert_last(ca_list
, ca
);
695 enumerator
->destroy(enumerator
);
697 plog("sending ModeCfg request");
699 st
->st_state
= STATE_MODE_CFG_I1
;
700 stat
= modecfg_send_msg(st
, ISAKMP_CFG_REQUEST
, ca_list
);
701 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
704 st
->st_modecfg
.started
= TRUE
;
710 * Used in ModeCfg pull mode on the server (responder)
711 * called in demux.c from STATE_MODE_CFG_R0
712 * server <- CFG_REQUEST
713 * server -> CFG_REPLY
714 * STF_OK transitions to STATE_MODE_CFG_R0
716 stf_status
modecfg_inR0(struct msg_digest
*md
)
718 struct state
*const st
= md
->st
;
720 stf_status stat
, stat_build
;
721 linked_list_t
*ca_list
= linked_list_create();
723 plog("parsing ModeCfg request");
725 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REQUEST
, &isama_id
, ca_list
);
731 /* build the CFG_REPLY */
732 get_attributes(st
->st_connection
, ca_list
);
734 plog("sending ModeCfg reply");
736 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_REPLY
,
738 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
740 if (stat_build
!= STF_OK
)
749 * Used in ModeCfg pull mode on the client (initiator)
750 * called in demux.c from STATE_MODE_CFG_I1
751 * client <- CFG_REPLY
752 * STF_OK transitions to STATE_MODE_CFG_I2
754 stf_status
modecfg_inI1(struct msg_digest
*md
)
756 struct state
*const st
= md
->st
;
759 linked_list_t
*ca_list
= linked_list_create();
761 plog("parsing ModeCfg reply");
763 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REPLY
, &isama_id
, ca_list
);
768 st
->st_modecfg
.vars_set
= set_attributes(st
->st_connection
, ca_list
);
770 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
775 * Used in ModeCfg push mode on the server (responder)
778 * STF_OK transitions to STATE_MODE_CFG_R3
780 stf_status
modecfg_send_set(struct state
*st
)
783 linked_list_t
*ca_list
= linked_list_create();
786 plog("sending ModeCfg set");
788 get_attributes(st
->st_connection
, ca_list
);
789 st
->st_state
= STATE_MODE_CFG_R3
;
790 stat
= modecfg_send_msg(st
, ISAKMP_CFG_SET
, ca_list
);
791 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
794 st
->st_modecfg
.started
= TRUE
;
800 * Used in ModeCfg push mode on the client (initiator)
801 * called in demux.c from STATE_MODE_CFG_I0
804 * STF_OK transitions to STATE_MODE_CFG_I3
806 stf_status
modecfg_inI0(struct msg_digest
*md
)
808 struct state
*const st
= md
->st
;
810 stf_status stat
, stat_build
;
811 modecfg_attribute_t
*ca
;
812 linked_list_t
*ca_list
, *ca_ack_list
;
814 plog("parsing ModeCfg set");
816 ca_list
= linked_list_create();
817 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_SET
, &isama_id
, ca_list
);
822 register_attribute_handlers(st
->st_connection
);
823 st
->st_modecfg
.vars_set
= set_attributes(st
->st_connection
, ca_list
);
825 /* prepare ModeCfg ack which sends zero length attributes */
826 ca_ack_list
= linked_list_create();
827 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
)
831 case INTERNAL_IP4_ADDRESS
:
832 case INTERNAL_IP4_DNS
:
833 case INTERNAL_IP4_NBNS
:
834 case APPLICATION_VERSION
:
835 case INTERNAL_IP6_ADDRESS
:
836 case INTERNAL_IP6_DNS
:
837 case INTERNAL_IP6_NBNS
:
841 /* supported attributes */
843 ca_ack_list
->insert_last(ca_ack_list
, ca
);
846 /* unsupportd attributes */
847 modecfg_attribute_destroy(ca
);
850 ca_list
->destroy(ca_list
);
852 plog("sending ModeCfg ack");
854 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_ACK
,
855 ca_ack_list
, isama_id
);
856 ca_ack_list
->destroy_function(ca_ack_list
, (void *)modecfg_attribute_destroy
);
857 if (stat_build
!= STF_OK
)
866 * Used in ModeCfg push mode on the server (responder)
867 * called in demux.c from STATE_MODE_CFG_R3
869 * STF_OK transitions to STATE_MODE_CFG_R4
871 stf_status
modecfg_inR3(struct msg_digest
*md
)
873 struct state
*const st
= md
->st
;
876 linked_list_t
*ca_list
= linked_list_create();
878 plog("parsing ModeCfg ack");
880 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_ACK
, &isama_id
, ca_list
);
881 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
891 * Used on the XAUTH server (responder)
893 * server -> CFG_REQUEST
894 * STF_OK transitions to STATE_XAUTH_R1
896 stf_status
xauth_send_request(struct state
*st
)
899 modecfg_attribute_t
*ca
;
900 linked_list_t
*ca_list
= linked_list_create();
902 ca
= modecfg_attribute_create(XAUTH_USER_NAME
, chunk_empty
);
903 ca_list
->insert_last(ca_list
, ca
);
904 ca
= modecfg_attribute_create(XAUTH_USER_PASSWORD
, chunk_empty
);
905 ca_list
->insert_last(ca_list
, ca
);
907 plog("sending XAUTH request");
908 st
->st_state
= STATE_XAUTH_R1
;
909 stat
= modecfg_send_msg(st
, ISAKMP_CFG_REQUEST
, ca_list
);
910 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
913 st
->st_xauth
.started
= TRUE
;
919 * Used on the XAUTH client (initiator)
920 * called in demux.c from STATE_XAUTH_I0
921 * client <- CFG_REQUEST
922 * client -> CFG_REPLY
923 * STF_OK transitions to STATE_XAUTH_I1
925 stf_status
xauth_inI0(struct msg_digest
*md
)
927 struct state
*const st
= md
->st
;
928 connection_t
*c
= st
->st_connection
;
930 stf_status stat
, stat_build
;
931 modecfg_attribute_t
*ca
;
932 bool xauth_user_name_present
= FALSE
;
933 bool xauth_user_password_present
= FALSE
;
934 bool xauth_type_present
= FALSE
;
935 chunk_t xauth_user_name
, xauth_user_password
;
936 identification_t
*user_id
;
937 linked_list_t
*ca_list
= linked_list_create();
939 plog("parsing XAUTH request");
941 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REQUEST
, &isama_id
, ca_list
);
947 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
)
952 if (ca
->value
.len
!= XAUTH_TYPE_GENERIC
)
954 plog("xauth type %s is not supported",
955 enum_name(&xauth_type_names
, ca
->value
.len
));
960 xauth_type_present
= TRUE
;
963 case XAUTH_USER_NAME
:
964 xauth_user_name_present
= TRUE
;
966 case XAUTH_USER_PASSWORD
:
967 xauth_user_password_present
= TRUE
;
972 DBG(DBG_PARSING
| DBG_CONTROLMORE
,
973 DBG_log(" '%.*s'", ca
->value
.len
, ca
->value
.ptr
)
980 modecfg_attribute_destroy(ca
);
983 if (!xauth_user_name_present
)
985 plog("user name attribute is missing in XAUTH request");
988 if (!xauth_user_password_present
)
990 plog("user password attribute is missing in XAUTH request");
994 /* prepare XAUTH reply */
997 /* get user credentials using a plugin function */
998 if (!pluto
->xauth
->get_secret(pluto
->xauth
, c
, &xauth_user_password
))
1000 plog("xauth user credentials not found");
1006 /* insert xauth type if present */
1007 if (xauth_type_present
)
1009 ca
= modecfg_attribute_create_tv(XAUTH_TYPE
, XAUTH_TYPE_GENERIC
);
1010 ca_list
->insert_last(ca_list
, ca
);
1013 /* insert xauth user name */
1014 user_id
= (c
->xauth_identity
) ? c
->xauth_identity
: c
->spd
.this.id
;
1015 xauth_user_name
= user_id
->get_encoding(user_id
);
1017 DBG_log("my xauth user name is '%.*s'", xauth_user_name
.len
,
1018 xauth_user_name
.ptr
)
1020 ca
= modecfg_attribute_create(XAUTH_USER_NAME
, xauth_user_name
);
1021 ca_list
->insert_last(ca_list
, ca
);
1023 /* insert xauth user password */
1025 DBG_log("my xauth user password is '%.*s'", xauth_user_password
.len
,
1026 xauth_user_password
.ptr
)
1028 ca
= modecfg_attribute_create(XAUTH_USER_PASSWORD
, xauth_user_password
);
1029 ca_list
->insert_last(ca_list
, ca
);
1030 chunk_clear(&xauth_user_password
);
1034 ca
= modecfg_attribute_create_tv(XAUTH_STATUS
, XAUTH_STATUS_FAIL
);
1035 ca_list
->insert_last(ca_list
, ca
);
1038 plog("sending XAUTH reply");
1039 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_REPLY
,
1041 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1042 if (stat_build
!= STF_OK
)
1048 st
->st_xauth
.started
= TRUE
;
1054 /* send XAUTH reply msg and then delete ISAKMP SA */
1055 free(st
->st_tpacket
.ptr
);
1056 st
->st_tpacket
= chunk_create(md
->reply
.start
, pbs_offset(&md
->reply
));
1057 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
1058 send_packet(st
, "XAUTH reply msg");
1065 * Used on the XAUTH server (responder)
1066 * called in demux.c from STATE_XAUTH_R1
1069 STF_OK transitions to STATE_XAUTH_R2
1071 stf_status
xauth_inR1(struct msg_digest
*md
)
1073 struct state
*const st
= md
->st
;
1074 connection_t
*c
= st
->st_connection
;
1076 stf_status stat
, stat_build
;
1077 chunk_t xauth_user_name
, xauth_user_password
;
1078 int xauth_status
= XAUTH_STATUS_OK
;
1079 modecfg_attribute_t
*ca
;
1080 linked_list_t
*ca_list
= linked_list_create();
1082 plog("parsing XAUTH reply");
1084 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REPLY
, &isama_id
, ca_list
);
1090 /* initialize xauth_secret */
1091 xauth_user_name
= chunk_empty
;
1092 xauth_user_password
= chunk_empty
;
1094 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
)
1099 xauth_status
= ca
->value
.len
;
1101 case XAUTH_USER_NAME
:
1102 xauth_user_name
= chunk_clone(ca
->value
);
1104 case XAUTH_USER_PASSWORD
:
1105 xauth_user_password
= chunk_clone(ca
->value
);
1110 modecfg_attribute_destroy(ca
);
1112 /* did the client return an XAUTH FAIL status? */
1113 if (xauth_status
== XAUTH_STATUS_FAIL
)
1115 plog("received FAIL status in XAUTH reply");
1117 /* client is not able to do XAUTH, delete ISAKMP SA */
1118 free(xauth_user_name
.ptr
);
1119 free(xauth_user_password
.ptr
);
1121 ca_list
->destroy(ca_list
);
1125 /* check XAUTH reply */
1126 if (xauth_user_name
.ptr
== NULL
)
1128 plog("user name attribute is missing in XAUTH reply");
1129 st
->st_xauth
.status
= FALSE
;
1131 else if (xauth_user_password
.ptr
== NULL
)
1133 plog("user password attribute is missing in XAUTH reply");
1134 st
->st_xauth
.status
= FALSE
;
1139 DBG_log("peer xauth user name is '%.*s'", xauth_user_name
.len
,
1140 xauth_user_name
.ptr
)
1142 DESTROY_IF(c
->xauth_identity
);
1143 c
->xauth_identity
= identification_create_from_data(xauth_user_name
);
1146 DBG_log("peer xauth user password is '%.*s'", xauth_user_password
.len
,
1147 xauth_user_password
.ptr
)
1149 /* verify the user credentials using a plugin function */
1150 st
->st_xauth
.status
= pluto
->xauth
->verify_secret(pluto
->xauth
, c
,
1151 xauth_user_password
);
1152 plog("extended authentication %s", st
->st_xauth
.status?
"was successful":"failed");
1154 chunk_clear(&xauth_user_name
);
1155 chunk_clear(&xauth_user_password
);
1157 plog("sending XAUTH status");
1158 xauth_status
= (st
->st_xauth
.status
) ? XAUTH_STATUS_OK
: XAUTH_STATUS_FAIL
;
1159 ca
= modecfg_attribute_create_tv(XAUTH_STATUS
, xauth_status
);
1160 ca_list
->insert_last(ca_list
, ca
);
1161 stat_build
= modecfg_send_msg(st
, ISAKMP_CFG_SET
, ca_list
);
1162 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1163 if (stat_build
!= STF_OK
)
1171 * Used on the XAUTH client (initiator)
1172 * called in demux.c from STATE_XAUTH_I1
1175 * STF_OK transitions to STATE_XAUTH_I2
1177 stf_status
xauth_inI1(struct msg_digest
*md
)
1179 struct state
*const st
= md
->st
;
1181 stf_status stat
, stat_build
;
1182 modecfg_attribute_t
*ca
;
1183 linked_list_t
*ca_list
= linked_list_create();
1185 plog("parsing XAUTH status");
1186 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_SET
, &isama_id
, ca_list
);
1189 /* notification payload - not exactly the right choice, but okay */
1190 md
->note
= ISAKMP_ATTRIBUTES_NOT_SUPPORTED
;
1194 st
->st_xauth
.status
= FALSE
;
1195 while (ca_list
->remove_last(ca_list
, (void **)&ca
) == SUCCESS
)
1197 if (ca
->type
== XAUTH_STATUS
)
1199 st
->st_xauth
.status
= (ca
->value
.len
== XAUTH_STATUS_OK
);
1201 modecfg_attribute_destroy(ca
);
1203 plog("extended authentication %s", st
->st_xauth
.status?
"was successful":"failed");
1205 plog("sending XAUTH ack");
1206 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_ACK
, ca_list
, isama_id
);
1207 ca_list
->destroy(ca_list
);
1209 if (stat_build
!= STF_OK
)
1213 if (st
->st_xauth
.status
)
1220 /* send XAUTH ack msg and then delete ISAKMP SA */
1221 free(st
->st_tpacket
.ptr
);
1222 st
->st_tpacket
= chunk_create(md
->reply
.start
, pbs_offset(&md
->reply
));
1223 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
1224 send_packet(st
, "XAUTH ack msg");
1231 * Used on the XAUTH server (responder)
1232 * called in demux.c from STATE_XAUTH_R2
1234 * STF_OK transitions to STATE_XAUTH_R3
1236 stf_status
xauth_inR2(struct msg_digest
*md
)
1238 struct state
*const st
= md
->st
;
1241 linked_list_t
*ca_list
= linked_list_create();
1243 plog("parsing XAUTH ack");
1245 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_ACK
, &isama_id
, ca_list
);
1250 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1252 if (st
->st_xauth
.status
)