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-2009 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 SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
48 | LELEM(INTERNAL_IP4_NETMASK) \
49 | LELEM(INTERNAL_IP4_DNS) \
50 | LELEM(INTERNAL_IP4_NBNS) \
51 | LELEM(APPLICATION_VERSION) \
52 | LELEM(INTERNAL_IP6_DNS) \
53 | LELEM(INTERNAL_IP6_NBNS) \
56 #define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) )
58 #define UNITY_BANNER_STR "Welcome to strongSwan - the Linux VPN Solution!\n"
62 * Creates a modecfg_attribute_t object
64 static modecfg_attribute_t
*modecfg_attribute_create(configuration_attribute_type_t type
,
67 modecfg_attribute_t
*this;
69 this = malloc_thing(modecfg_attribute_t
);
70 this->type
= ((u_int16_t
)type
) & 0x7FFF;
71 this->value
= chunk_clone(value
);
78 * Destroys a modecfg_attribute_t object
80 void modecfg_attribute_destroy(modecfg_attribute_t
*this)
82 free(this->value
.ptr
);
87 * Addresses assigned (usually via ModeCfg) to the Initiator
89 typedef struct internal_addr internal_addr_t
;
94 lset_t xauth_attr_set
;
95 lset_t unity_attr_set
;
97 /* ModeCfg variables */
102 /* XAUTH variables */
103 u_int16_t xauth_type
;
104 xauth_t xauth_secret
;
109 * Initialize an internal_addr struct
111 static void init_internal_addr(internal_addr_t
*ia
)
113 ia
->attr_set
= LEMPTY
;
114 ia
->xauth_attr_set
= LEMPTY
;
115 ia
->xauth_secret
.user_name
= chunk_empty
;
116 ia
->xauth_secret
.user_password
= chunk_empty
;
117 ia
->xauth_type
= XAUTH_TYPE_GENERIC
;
118 ia
->xauth_status
= XAUTH_STATUS_FAIL
;
119 ia
->unity_attr_set
= LEMPTY
;
120 ia
->unity_banner
= NULL
;
122 anyaddr(AF_INET
, &ia
->ipaddr
);
126 * Get internal IP address for a connection
128 static void get_internal_addr(connection_t
*c
, host_t
*requested_vip
,
129 internal_addr_t
*ia
, linked_list_t
*ca_list
)
131 enumerator_t
*enumerator
;
132 configuration_attribute_type_t type
;
134 modecfg_attribute_t
*ca
;
137 if (isanyaddr(&c
->spd
.that
.host_srcip
))
139 if (c
->spd
.that
.pool
)
141 vip
= hydra
->attributes
->acquire_address(hydra
->attributes
,
142 c
->spd
.that
.pool
, c
->spd
.that
.id
,
146 chunk_t addr
= vip
->get_address(vip
);
148 plog("assigning virtual IP %H to peer", vip
);
149 initaddr(addr
.ptr
, addr
.len
, vip
->get_family(vip
), &ia
->ipaddr
);
155 plog("no virtual IP found");
160 ia
->ipaddr
= c
->spd
.that
.host_srcip
;
161 vip
= host_create_from_sockaddr((sockaddr_t
*)&ia
->ipaddr
);
162 plog("assigning virtual IP %H to peer", vip
);
165 if (!isanyaddr(&ia
->ipaddr
)) /* We got an IP address, send it */
167 c
->spd
.that
.host_srcip
= ia
->ipaddr
;
168 c
->spd
.that
.client
.addr
= ia
->ipaddr
;
169 c
->spd
.that
.client
.maskbits
= 32;
170 c
->spd
.that
.has_client
= TRUE
;
172 ia
->attr_set
= LELEM(INTERNAL_IP4_ADDRESS
)
173 | LELEM(INTERNAL_IP4_NETMASK
);
176 /* assign attributes from registered providers */
177 enumerator
= hydra
->attributes
->create_responder_enumerator(hydra
->attributes
,
178 c
->spd
.that
.id
, vip
);
179 while (enumerator
->enumerate(enumerator
, &type
, &value
))
182 DBG_log("building %N attribute",
183 configuration_attribute_type_names
, type
)
185 ca
= modecfg_attribute_create(type
, value
);
186 ca_list
->insert_last(ca_list
, ca
);
188 enumerator
->destroy(enumerator
);
194 * Set srcip and client subnet to internal IP address
196 static bool set_internal_addr(connection_t
*c
, internal_addr_t
*ia
,
197 linked_list_t
*ca_list
)
199 if (ia
->attr_set
& LELEM(INTERNAL_IP4_ADDRESS
)
200 && !isanyaddr(&ia
->ipaddr
))
203 modecfg_attribute_t
*ca
;
204 enumerator_t
*enumerator
;
206 if (addrbytesptr(&c
->spd
.this.host_srcip
, NULL
) == 0
207 || isanyaddr(&c
->spd
.this.host_srcip
)
208 || sameaddr(&c
->spd
.this.host_srcip
, &ia
->ipaddr
))
210 char srcip
[ADDRTOT_BUF
];
212 addrtot(&ia
->ipaddr
, 0, srcip
, sizeof(srcip
));
213 plog("setting virtual IP source address to %s", srcip
);
217 char old_srcip
[ADDRTOT_BUF
];
218 char new_srcip
[ADDRTOT_BUF
];
220 addrtot(&c
->spd
.this.host_srcip
, 0, old_srcip
, sizeof(old_srcip
));
221 addrtot(&ia
->ipaddr
, 0, new_srcip
, sizeof(new_srcip
));
222 plog("replacing virtual IP source address %s by %s"
223 , old_srcip
, new_srcip
);
227 c
->spd
.this.host_srcip
= ia
->ipaddr
;
228 vip
= host_create_from_sockaddr((sockaddr_t
*)&ia
->ipaddr
);
230 /* setting client subnet to srcip/32 */
231 addrtosubnet(&ia
->ipaddr
, &c
->spd
.this.client
);
232 setportof(0, &c
->spd
.this.client
.addr
);
233 c
->spd
.this.has_client
= TRUE
;
235 /* setting other attributes (e.g. DNS and NBNS servers) */
236 enumerator
= ca_list
->create_enumerator(ca_list
);
237 while (enumerator
->enumerate(enumerator
, &ca
))
239 modecfg_attribute_t
*ca_handler
;
240 attribute_handler_t
*handler
= NULL
;
243 /* find the first handler which requested this attribute */
244 e
= c
->requested
->create_enumerator(c
->requested
);
245 while (e
->enumerate(e
, &ca_handler
))
247 if (ca_handler
->type
== ca
->type
)
249 handler
= ca_handler
->handler
;
255 /* and pass it to the handle function */
256 handler
= hydra
->attributes
->handle(hydra
->attributes
,
257 c
->spd
.that
.id
, handler
, ca
->type
, ca
->value
);
260 ca_handler
= modecfg_attribute_create(ca
->type
, ca
->value
);
261 ca_handler
->handler
= handler
;
263 if (c
->attributes
== NULL
)
265 c
->attributes
= linked_list_create();
267 c
->attributes
->insert_last(c
->attributes
, ca_handler
);
270 enumerator
->destroy(enumerator
);
272 c
->requested
->destroy_function(c
->requested
,
273 (void*)modecfg_attribute_destroy
);
281 * Compute HASH of Mode Config.
283 static size_t modecfg_hash(u_char
*dest
, u_char
*start
, u_char
*roof
,
284 const struct state
*st
)
286 chunk_t msgid_chunk
= chunk_from_thing(st
->st_msgid
);
287 chunk_t msg_chunk
= { start
, roof
- start
};
288 size_t prf_block_size
;
289 pseudo_random_function_t prf_alg
;
292 prf_alg
= oakley_to_prf(st
->st_oakley
.hash
);
293 prf
= lib
->crypto
->create_prf(lib
->crypto
, prf_alg
);
294 prf
->set_key(prf
, st
->st_skeyid_a
);
295 prf
->get_bytes(prf
, msgid_chunk
, NULL
);
296 prf
->get_bytes(prf
, msg_chunk
, dest
);
297 prf_block_size
= prf
->get_block_size(prf
);
301 DBG_log("ModeCfg HASH computed:");
302 DBG_dump("", dest
, prf_block_size
)
304 return prf_block_size
;
309 * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
311 static stf_status
modecfg_build_msg(struct state
*st
, pb_stream
*rbody
,
314 linked_list_t
*ca_list
,
317 u_char
*r_hash_start
, *r_hashval
;
319 START_HASH_PAYLOAD(*rbody
, ISAKMP_NEXT_ATTR
);
323 struct isakmp_mode_attr attrh
;
324 struct isakmp_attribute attr
;
325 pb_stream strattr
,attrval
;
327 bool is_xauth_attr_set
= ia
->xauth_attr_set
!= LEMPTY
;
328 bool is_unity_attr_set
= ia
->unity_attr_set
!= LEMPTY
;
329 lset_t attr_set
= ia
->attr_set
;
330 enumerator_t
*enumerator
;
331 modecfg_attribute_t
*ca
;
333 attrh
.isama_np
= ISAKMP_NEXT_NONE
;
334 attrh
.isama_type
= msg_type
;
335 attrh
.isama_identifier
= ap_id
;
337 if (!out_struct(&attrh
, &isakmp_attr_desc
, rbody
, &strattr
))
339 return STF_INTERNAL_ERROR
;
343 enumerator
= ca_list
->create_enumerator(ca_list
);
344 while (enumerator
->enumerate(enumerator
, &ca
))
346 char ca_type_name
[BUF_LEN
];
348 snprintf(ca_type_name
, BUF_LEN
, "%N",
349 configuration_attribute_type_names
, ca
->type
);
350 attr
.isaat_af_type
= ca
->type
| ISAKMP_ATTR_AF_TLV
;
351 out_struct(&attr
, &isakmp_modecfg_attribute_desc
, &strattr
, &attrval
);
352 out_raw(ca
->value
.ptr
, ca
->value
.len
, &attrval
, ca_type_name
);
353 close_output_pbs(&attrval
);
355 enumerator
->destroy(enumerator
);
357 while (attr_set
!= LEMPTY
|| is_xauth_attr_set
|| is_unity_attr_set
)
359 if (attr_set
== LEMPTY
)
361 if (is_xauth_attr_set
)
363 attr_set
= ia
->xauth_attr_set
;
364 attr_type
= XAUTH_BASE
;
365 is_xauth_attr_set
= FALSE
;
369 attr_set
= ia
->unity_attr_set
;
370 attr_type
= UNITY_BASE
;
371 is_unity_attr_set
= FALSE
;
377 const u_char
*byte_ptr
;
380 /* ISAKMP attr out */
381 if (attr_type
== XAUTH_TYPE
)
383 attr
.isaat_af_type
= attr_type
| ISAKMP_ATTR_AF_TV
;
384 attr
.isaat_lv
= ia
->xauth_type
;
386 else if (attr_type
== XAUTH_STATUS
)
388 attr
.isaat_af_type
= attr_type
| ISAKMP_ATTR_AF_TV
;
389 attr
.isaat_lv
= ia
->xauth_status
;
393 attr
.isaat_af_type
= attr_type
| ISAKMP_ATTR_AF_TLV
;
395 out_struct(&attr
, &isakmp_modecfg_attribute_desc
, &strattr
, &attrval
);
399 case INTERNAL_IP4_ADDRESS
:
400 if (!isanyaddr(&ia
->ipaddr
))
402 len
= addrbytesptr(&ia
->ipaddr
, &byte_ptr
);
403 out_raw(byte_ptr
, len
, &attrval
, "IP4_addr");
406 case INTERNAL_IP4_NETMASK
:
410 char mask
[4],bits
[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
411 int t
,m
=st
->st_connection
->that
.host_addr
.maskbit
;
421 if (st
->st_connection
->spd
.this.client
.maskbits
== 0)
427 mask
= 0xffffffff * 1;
428 out_raw(&mask
, 4, &attrval
, "IP4_mask");
432 case INTERNAL_IP4_SUBNET
:
435 char bits
[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
437 int m
= st
->st_connection
->spd
.this.client
.maskbits
;
439 for (t
= 0; t
< 4; t
++)
441 mask
[t
] = (m
< 8) ? bits
[m
] : 0xff;
448 len
= addrbytesptr(&st
->st_connection
->spd
.this.client
.addr
, &byte_ptr
);
449 out_raw(byte_ptr
, len
, &attrval
, "IP4_subnet");
450 out_raw(mask
, sizeof(mask
), &attrval
, "IP4_submsk");
455 case XAUTH_USER_NAME
:
456 if (ia
->xauth_secret
.user_name
.ptr
!= NULL
)
458 out_raw(ia
->xauth_secret
.user_name
.ptr
459 , ia
->xauth_secret
.user_name
.len
460 , &attrval
, "xauth_user_name");
463 case XAUTH_USER_PASSWORD
:
464 if (ia
->xauth_secret
.user_password
.ptr
!= NULL
)
466 out_raw(ia
->xauth_secret
.user_password
.ptr
467 , ia
->xauth_secret
.user_password
.len
468 , &attrval
, "xauth_user_password");
474 if (ia
->unity_banner
!= NULL
)
476 out_raw(ia
->unity_banner
477 , strlen(ia
->unity_banner
)
478 , &attrval
, "UNITY_BANNER");
482 plog("attempt to send unsupported mode cfg attribute %s."
483 , enum_show(&modecfg_attr_names
, attr_type
));
486 close_output_pbs(&attrval
);
491 close_message(&strattr
);
494 modecfg_hash(r_hashval
, r_hash_start
, rbody
->cur
, st
);
495 close_message(rbody
);
496 encrypt_message(rbody
, st
);
501 * Send ModeCfg message
503 static stf_status
modecfg_send_msg(struct state
*st
, int isama_type
,
504 internal_addr_t
*ia
, linked_list_t
*ca_list
)
511 init_pbs(&msg
, buf
, sizeof(buf
), "ModeCfg msg buffer");
513 /* this is the beginning of a new exchange */
514 st
->st_msgid
= generate_msgid(st
);
515 init_phase2_iv(st
, &st
->st_msgid
);
519 struct isakmp_hdr hdr
;
521 zero(&hdr
); /* default to 0 */
522 hdr
.isa_version
= ISAKMP_MAJOR_VERSION
<< ISA_MAJ_SHIFT
| ISAKMP_MINOR_VERSION
;
523 hdr
.isa_np
= ISAKMP_NEXT_HASH
;
524 hdr
.isa_xchg
= ISAKMP_XCHG_MODE_CFG
;
525 hdr
.isa_flags
= ISAKMP_FLAG_ENCRYPTION
;
526 memcpy(hdr
.isa_icookie
, st
->st_icookie
, COOKIE_SIZE
);
527 memcpy(hdr
.isa_rcookie
, st
->st_rcookie
, COOKIE_SIZE
);
528 hdr
.isa_msgid
= st
->st_msgid
;
530 if (!out_struct(&hdr
, &isakmp_hdr_desc
, &msg
, &rbody
))
532 return STF_INTERNAL_ERROR
;
536 /* ATTR out with isama_id of 0 */
537 modecfg_build_msg(st
, &rbody
, isama_type
, ia
, ca_list
, 0);
539 free(st
->st_tpacket
.ptr
);
540 st
->st_tpacket
= chunk_create(msg
.start
, pbs_offset(&msg
));
541 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
544 send_packet(st
, "ModeCfg msg");
546 if (st
->st_event
->ev_type
!= EVENT_RETRANSMIT
)
549 event_schedule(EVENT_RETRANSMIT
, EVENT_RETRANSMIT_DELAY_0
, st
);
555 * Parse a ModeCfg attribute payload
557 static stf_status
modecfg_parse_attributes(pb_stream
*attrs
, internal_addr_t
*ia
,
558 linked_list_t
*ca_list
)
560 struct isakmp_attribute attr
;
564 while (pbs_left(attrs
) >= sizeof(struct isakmp_attribute
))
569 modecfg_attribute_t
*ca
;
571 if (!in_struct(&attr
, &isakmp_modecfg_attribute_desc
, attrs
, &strattr
))
575 attr_type
= attr
.isaat_af_type
& ISAKMP_ATTR_RTYPE_MASK
;
576 attr_len
= attr
.isaat_lv
;
578 DBG_log("processing %N attribute",
579 configuration_attribute_type_names
, attr_type
)
584 case INTERNAL_IP4_ADDRESS
:
587 ugh
= initaddr((char *)(strattr
.cur
), 4, AF_INET
, &ia
->ipaddr
);
590 plog("received invalid virtual IPv4 address: %s", ugh
);
593 ia
->attr_set
|= LELEM(attr_type
);
595 case INTERNAL_IP4_DNS
:
596 case INTERNAL_IP4_NBNS
:
599 attr_chunk
= chunk_create(strattr
.cur
, attr_len
);
600 ca
= modecfg_attribute_create(attr_type
, attr_chunk
);
601 ca_list
->insert_last(ca_list
, ca
);
604 case INTERNAL_IP6_DNS
:
605 case INTERNAL_IP6_NBNS
:
608 attr_chunk
= chunk_create(strattr
.cur
, attr_len
);
609 ca
= modecfg_attribute_create(attr_type
, attr_chunk
);
610 ca_list
->insert_last(ca_list
, ca
);
613 case INTERNAL_IP4_NETMASK
:
614 case INTERNAL_IP4_SUBNET
:
615 case INTERNAL_ADDRESS_EXPIRY
:
616 case INTERNAL_IP4_DHCP
:
617 case INTERNAL_IP6_ADDRESS
:
618 case INTERNAL_IP6_NETMASK
:
619 case INTERNAL_IP6_DHCP
:
620 case SUPPORTED_ATTRIBUTES
:
621 case INTERNAL_IP6_SUBNET
:
622 ia
->attr_set
|= LELEM(attr_type
);
624 case APPLICATION_VERSION
:
628 DBG_log(" '%.*s'", attr_len
, strattr
.cur
)
631 ia
->attr_set
|= LELEM(attr_type
);
634 ia
->xauth_type
= attr
.isaat_lv
;
635 ia
->xauth_attr_set
|= LELEM(attr_type
- XAUTH_BASE
);
637 case XAUTH_USER_NAME
:
638 ia
->xauth_secret
.user_name
= chunk_create(strattr
.cur
, attr_len
);
639 ia
->xauth_attr_set
|= LELEM(attr_type
- XAUTH_BASE
);
641 case XAUTH_USER_PASSWORD
:
642 ia
->xauth_secret
.user_password
= chunk_create(strattr
.cur
, attr_len
);
643 ia
->xauth_attr_set
|= LELEM(attr_type
- XAUTH_BASE
);
646 ia
->xauth_status
= attr
.isaat_lv
;
647 ia
->xauth_attr_set
|= LELEM(attr_type
- XAUTH_BASE
);
653 DBG_log(" '%.*s'", attr_len
, strattr
.cur
)
656 /* fall through to set attribute flag */
658 case XAUTH_CHALLENGE
:
662 ia
->xauth_attr_set
|= LELEM(attr_type
- XAUTH_BASE
);
664 case UNITY_DDNS_HOSTNAME
:
668 DBG_log(" '%.*s'", attr_len
, strattr
.cur
)
671 /* fall through to set attribute flag */
673 case UNITY_SAVE_PASSWD
:
674 case UNITY_DEF_DOMAIN
:
675 case UNITY_SPLITDNS_NAME
:
676 case UNITY_SPLIT_INCLUDE
:
677 case UNITY_NATT_PORT
:
678 case UNITY_LOCAL_LAN
:
681 case UNITY_BACKUP_SERVERS
:
682 ia
->unity_attr_set
|= LELEM(attr_type
- UNITY_BASE
);
685 plog("unsupported ModeCfg attribute %s received."
686 , enum_show(&modecfg_attr_names
, attr_type
));
694 * Parse a ModeCfg message
696 static stf_status
modecfg_parse_msg(struct msg_digest
*md
, int isama_type
,
697 u_int16_t
*isama_id
, internal_addr_t
*ia
,
698 linked_list_t
*ca_list
)
700 struct state
*const st
= md
->st
;
701 struct payload_digest
*p
;
704 st
->st_msgid
= md
->hdr
.isa_msgid
;
706 CHECK_QUICK_HASH(md
, modecfg_hash(hash_val
708 , md
->message_pbs
.roof
, st
)
709 , "MODECFG-HASH", "ISAKMP_CFG_MSG");
711 /* process the ModeCfg payloads received */
712 for (p
= md
->chain
[ISAKMP_NEXT_ATTR
]; p
!= NULL
; p
= p
->next
)
714 internal_addr_t ia_candidate
;
716 init_internal_addr(&ia_candidate
);
718 if (p
->payload
.attribute
.isama_type
== isama_type
)
720 *isama_id
= p
->payload
.attribute
.isama_identifier
;
722 stat
= modecfg_parse_attributes(&p
->pbs
, &ia_candidate
, ca_list
);
725 /* return with a valid set of attributes */
732 plog("expected %s, got %s instead (ignored)"
733 , enum_name(&attr_msg_type_names
, isama_type
)
734 , enum_name(&attr_msg_type_names
, p
->payload
.attribute
.isama_type
));
736 stat
= modecfg_parse_attributes(&p
->pbs
, &ia_candidate
, ca_list
);
747 * Send ModeCfg request message from client to server in pull mode
749 stf_status
modecfg_send_request(struct state
*st
)
751 connection_t
*c
= st
->st_connection
;
754 attribute_handler_t
*handler
;
755 configuration_attribute_type_t type
;
758 enumerator_t
*enumerator
;
760 init_internal_addr(&ia
);
762 ia
.attr_set
= LELEM(INTERNAL_IP4_ADDRESS
)
763 | LELEM(INTERNAL_IP4_NETMASK
);
764 ia
.ipaddr
= c
->spd
.this.host_srcip
;
765 vip
= host_create_from_sockaddr((sockaddr_t
*)&ia
.ipaddr
);
767 /* add configuration attributes requested by handlers */
768 enumerator
= hydra
->attributes
->create_initiator_enumerator(
769 hydra
->attributes
,c
->spd
.that
.id
, vip
);
770 while (enumerator
->enumerate(enumerator
, &handler
, &type
, &data
))
772 modecfg_attribute_t
*ca
;
774 /* create configuration attribute request and link to handler */
776 DBG_log("building %N attribute", configuration_attribute_type_names
, type
)
778 ca
= modecfg_attribute_create(type
, data
);
779 ca
->handler
= handler
;
781 if (c
->requested
== NULL
)
783 c
->requested
= linked_list_create();
785 c
->requested
->insert_last(c
->requested
, ca
);
787 enumerator
->destroy(enumerator
);
790 plog("sending ModeCfg request");
791 st
->st_state
= STATE_MODE_CFG_I1
;
792 stat
= modecfg_send_msg(st
, ISAKMP_CFG_REQUEST
, &ia
, c
->requested
);
795 st
->st_modecfg
.started
= TRUE
;
800 /* STATE_MODE_CFG_R0:
801 * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
803 * used in ModeCfg pull mode, on the server (responder)
805 stf_status
modecfg_inR0(struct msg_digest
*md
)
807 struct state
*const st
= md
->st
;
810 bool want_unity_banner
;
811 stf_status stat
, stat_build
;
812 host_t
*requested_vip
;
813 linked_list_t
*ca_list
= linked_list_create();
815 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REQUEST
, &isama_id
, &ia
, ca_list
);
821 if (ia
.attr_set
& LELEM(INTERNAL_IP4_ADDRESS
))
823 requested_vip
= host_create_from_sockaddr((sockaddr_t
*)&ia
.ipaddr
);
827 requested_vip
= host_create_any(AF_INET
);
829 plog("peer requested virtual IP %H", requested_vip
);
831 want_unity_banner
= (ia
.unity_attr_set
& LELEM(UNITY_BANNER
- UNITY_BASE
)) != LEMPTY
;
832 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
834 /* build the CFG_REPLY */
835 ca_list
= linked_list_create();
836 init_internal_addr(&ia
);
837 get_internal_addr(st
->st_connection
, requested_vip
, &ia
, ca_list
);
838 requested_vip
->destroy(requested_vip
);
840 if (want_unity_banner
)
842 ia
.unity_banner
= UNITY_BANNER_STR
;
843 ia
.unity_attr_set
|= LELEM(UNITY_BANNER
- UNITY_BASE
);
846 plog("sending ModeCfg reply");
848 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_REPLY
,
849 &ia
, ca_list
, isama_id
);
850 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
852 if (stat_build
!= STF_OK
)
860 /* STATE_MODE_CFG_I1:
861 * HDR*, HASH, ATTR(REPLY=IP)
863 * used in ModeCfg pull mode, on the client (initiator)
865 stf_status
modecfg_inI1(struct msg_digest
*md
)
867 struct state
*const st
= md
->st
;
871 linked_list_t
*ca_list
= linked_list_create();
873 plog("parsing ModeCfg reply");
875 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REPLY
, &isama_id
, &ia
, ca_list
);
880 st
->st_modecfg
.vars_set
= set_internal_addr(st
->st_connection
, &ia
, ca_list
);
882 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
888 * Send ModeCfg set message from server to client in push mode
890 stf_status
modecfg_send_set(struct state
*st
)
895 linked_list_t
*ca_list
= linked_list_create();
897 init_internal_addr(&ia
);
898 vip
= host_create_any(AF_INET
);
899 get_internal_addr(st
->st_connection
, vip
, &ia
, ca_list
);
903 ia
.unity_banner
= UNITY_BANNER_STR
;
904 ia
.unity_attr_set
|= LELEM(UNITY_BANNER
- UNITY_BASE
);
907 plog("sending ModeCfg set");
908 st
->st_state
= STATE_MODE_CFG_R3
;
909 stat
= modecfg_send_msg(st
, ISAKMP_CFG_SET
, &ia
, ca_list
);
910 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
913 st
->st_modecfg
.started
= TRUE
;
918 /* STATE_MODE_CFG_I0:
919 * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
921 * used in ModeCfg push mode, on the client (initiator).
923 stf_status
modecfg_inI0(struct msg_digest
*md
)
925 struct state
*const st
= md
->st
;
928 lset_t attr_set
, unity_attr_set
;
929 stf_status stat
, stat_build
;
930 linked_list_t
*ca_list
= linked_list_create();
932 plog("parsing ModeCfg set");
934 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_SET
, &isama_id
, &ia
, ca_list
);
935 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
941 st
->st_modecfg
.vars_set
= set_internal_addr(st
->st_connection
, &ia
, ca_list
);
943 /* prepare ModeCfg ack which sends zero length attributes */
944 attr_set
= ia
.attr_set
;
945 unity_attr_set
= ia
.unity_attr_set
;
946 init_internal_addr(&ia
);
947 ia
.attr_set
= attr_set
& SUPPORTED_ATTR_SET
;
948 ia
.unity_attr_set
= unity_attr_set
& SUPPORTED_UNITY_ATTR_SET
;
950 plog("sending ModeCfg ack");
952 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_ACK
,
953 &ia
, ca_list
, isama_id
);
954 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
955 if (stat_build
!= STF_OK
)
963 /* STATE_MODE_CFG_R3:
964 * HDR*, HASH, ATTR(ACK,OK)
966 * used in ModeCfg push mode, on the server (responder)
968 stf_status
modecfg_inR3(struct msg_digest
*md
)
970 struct state
*const st
= md
->st
;
974 linked_list_t
*ca_list
= linked_list_create();
976 plog("parsing ModeCfg ack");
978 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_ACK
, &isama_id
, &ia
, ca_list
);
979 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
989 * Send XAUTH credentials request (username + password)
991 stf_status
xauth_send_request(struct state
*st
)
995 linked_list_t
*ca_list
= linked_list_create();
997 init_internal_addr(&ia
);
998 ia
.xauth_attr_set
= LELEM(XAUTH_USER_NAME
- XAUTH_BASE
)
999 | LELEM(XAUTH_USER_PASSWORD
- XAUTH_BASE
);
1001 plog("sending XAUTH request");
1002 st
->st_state
= STATE_XAUTH_R1
;
1003 stat
= modecfg_send_msg(st
, ISAKMP_CFG_REQUEST
, &ia
, ca_list
);
1004 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1007 st
->st_xauth
.started
= TRUE
;
1013 * HDR*, HASH, ATTR(REQ) --> HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD)
1015 * used on the XAUTH client (initiator)
1017 stf_status
xauth_inI0(struct msg_digest
*md
)
1019 struct state
*const st
= md
->st
;
1022 stf_status stat
, stat_build
;
1023 bool xauth_type_present
;
1024 linked_list_t
*ca_list
= linked_list_create();
1026 plog("parsing XAUTH request");
1028 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REQUEST
, &isama_id
, &ia
, ca_list
);
1029 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1035 /* check XAUTH attributes */
1036 xauth_type_present
= (ia
.xauth_attr_set
& LELEM(XAUTH_TYPE
- XAUTH_BASE
)) != LEMPTY
;
1038 if (xauth_type_present
&& ia
.xauth_type
!= XAUTH_TYPE_GENERIC
)
1040 plog("xauth type %s is not supported", enum_name(&xauth_type_names
, ia
.xauth_type
));
1043 else if ((ia
.xauth_attr_set
& LELEM(XAUTH_USER_NAME
- XAUTH_BASE
)) == LEMPTY
)
1045 plog("user name attribute is missing in XAUTH request");
1048 else if ((ia
.xauth_attr_set
& LELEM(XAUTH_USER_PASSWORD
- XAUTH_BASE
)) == LEMPTY
)
1050 plog("user password attribute is missing in XAUTH request");
1054 /* prepare XAUTH reply */
1055 init_internal_addr(&ia
);
1059 /* get user credentials using a plugin function */
1060 if (!xauth_module
.get_secret(&ia
.xauth_secret
))
1062 plog("xauth user credentials not found");
1069 DBG_log("my xauth user name is '%.*s'"
1070 , ia
.xauth_secret
.user_name
.len
1071 , ia
.xauth_secret
.user_name
.ptr
)
1074 DBG_log("my xauth user password is '%.*s'"
1075 , ia
.xauth_secret
.user_password
.len
1076 , ia
.xauth_secret
.user_password
.ptr
)
1078 ia
.xauth_attr_set
= LELEM(XAUTH_USER_NAME
- XAUTH_BASE
)
1079 | LELEM(XAUTH_USER_PASSWORD
- XAUTH_BASE
);
1080 if (xauth_type_present
)
1082 ia
.xauth_attr_set
|= LELEM(XAUTH_TYPE
- XAUTH_BASE
);
1087 ia
.xauth_attr_set
= LELEM(XAUTH_STATUS
- XAUTH_BASE
);
1088 ia
.xauth_status
= XAUTH_STATUS_FAIL
;
1091 plog("sending XAUTH reply");
1093 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_REPLY
,
1094 &ia
, ca_list
, isama_id
);
1095 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1096 if (stat_build
!= STF_OK
)
1102 st
->st_xauth
.started
= TRUE
;
1108 /* send XAUTH reply msg and then delete ISAKMP SA */
1109 free(st
->st_tpacket
.ptr
);
1110 st
->st_tpacket
= chunk_create(md
->reply
.start
, pbs_offset(&md
->reply
));
1111 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
1112 send_packet(st
, "XAUTH reply msg");
1119 * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
1121 * used on the XAUTH server (responder)
1123 stf_status
xauth_inR1(struct msg_digest
*md
)
1125 struct state
*const st
= md
->st
;
1128 stf_status stat
, stat_build
;
1129 linked_list_t
*ca_list
= linked_list_create();
1131 plog("parsing XAUTH reply");
1133 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_REPLY
, &isama_id
, &ia
, ca_list
);
1134 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1140 /* did the client return an XAUTH FAIL status? */
1141 if ((ia
.xauth_attr_set
& LELEM(XAUTH_STATUS
- XAUTH_BASE
)) != LEMPTY
)
1143 plog("received FAIL status in XAUTH reply");
1145 /* client is not able to do XAUTH, delete ISAKMP SA */
1150 /* check XAUTH reply */
1151 if ((ia
.xauth_attr_set
& LELEM(XAUTH_USER_NAME
- XAUTH_BASE
)) == LEMPTY
)
1153 plog("user name attribute is missing in XAUTH reply");
1154 st
->st_xauth
.status
= FALSE
;
1156 else if ((ia
.xauth_attr_set
& LELEM(XAUTH_USER_PASSWORD
- XAUTH_BASE
)) == LEMPTY
)
1158 plog("user password attribute is missing in XAUTH reply");
1159 st
->st_xauth
.status
= FALSE
;
1165 peer
.conn_name
= st
->st_connection
->name
;
1166 addrtot(&md
->sender
, 0, peer
.ip_address
, sizeof(peer
.ip_address
));
1167 snprintf(peer
.id
, sizeof(peer
.id
), "%Y",
1168 md
->st
->st_connection
->spd
.that
.id
);
1171 DBG_log("peer xauth user name is '%.*s'"
1172 , ia
.xauth_secret
.user_name
.len
1173 , ia
.xauth_secret
.user_name
.ptr
)
1176 DBG_log("peer xauth user password is '%.*s'"
1177 , ia
.xauth_secret
.user_password
.len
1178 , ia
.xauth_secret
.user_password
.ptr
)
1180 /* verify the user credentials using a plugin function */
1181 st
->st_xauth
.status
= xauth_module
.verify_secret(&peer
, &ia
.xauth_secret
);
1182 plog("extended authentication %s", st
->st_xauth
.status?
"was successful":"failed");
1185 /* prepare XAUTH set which sends the authentication status */
1186 init_internal_addr(&ia
);
1187 ia
.xauth_attr_set
= LELEM(XAUTH_STATUS
- XAUTH_BASE
);
1188 ia
.xauth_status
= (st
->st_xauth
.status
)? XAUTH_STATUS_OK
: XAUTH_STATUS_FAIL
;
1189 ca_list
= linked_list_create();
1191 plog("sending XAUTH status:");
1193 stat_build
= modecfg_send_msg(st
, ISAKMP_CFG_SET
, &ia
, ca_list
);
1194 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1195 if (stat_build
!= STF_OK
)
1203 * HDR*, HASH, ATTR(STATUS) --> HDR*, HASH, ATTR(ACK)
1205 * used on the XAUTH client (initiator)
1207 stf_status
xauth_inI1(struct msg_digest
*md
)
1209 struct state
*const st
= md
->st
;
1212 stf_status stat
, stat_build
;
1213 linked_list_t
*ca_list
= linked_list_create();
1215 plog("parsing XAUTH status");
1216 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_SET
, &isama_id
, &ia
, ca_list
);
1217 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1220 /* notification payload - not exactly the right choice, but okay */
1221 md
->note
= ISAKMP_ATTRIBUTES_NOT_SUPPORTED
;
1225 st
->st_xauth
.status
= ia
.xauth_status
;
1226 plog("extended authentication %s", st
->st_xauth
.status?
"was successful":"failed");
1228 plog("sending XAUTH ack");
1229 init_internal_addr(&ia
);
1230 stat_build
= modecfg_build_msg(st
, &md
->rbody
, ISAKMP_CFG_ACK
,
1231 &ia
, ca_list
, isama_id
);
1232 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1233 if (stat_build
!= STF_OK
)
1237 if (st
->st_xauth
.status
)
1244 /* send XAUTH ack msg and then delete ISAKMP SA */
1245 free(st
->st_tpacket
.ptr
);
1246 st
->st_tpacket
= chunk_create(md
->reply
.start
, pbs_offset(&md
->reply
));
1247 st
->st_tpacket
= chunk_clone(st
->st_tpacket
);
1248 send_packet(st
, "XAUTH ack msg");
1255 * HDR*, ATTR(STATUS), HASH --> Done
1257 * used on the XAUTH server (responder)
1259 stf_status
xauth_inR2(struct msg_digest
*md
)
1261 struct state
*const st
= md
->st
;
1265 linked_list_t
*ca_list
= linked_list_create();
1267 plog("parsing XAUTH ack");
1269 stat
= modecfg_parse_msg(md
, ISAKMP_CFG_ACK
, &isama_id
, &ia
, ca_list
);
1270 ca_list
->destroy_function(ca_list
, (void *)modecfg_attribute_destroy
);
1276 if (st
->st_xauth
.status
)