0c4f2bd6bbb25cf7c6be9518d8bd64eb1f9cc85a
[strongswan.git] / src / pluto / modecfg.c
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
6 *
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>.
11 *
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
15 * for more details.
16 *
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
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <freeswan.h>
27
28 #include <library.h>
29 #include <hydra.h>
30 #include <attributes/attributes.h>
31 #include <crypto/prfs/prf.h>
32
33 #include "constants.h"
34 #include "defs.h"
35 #include "state.h"
36 #include "demux.h"
37 #include "timer.h"
38 #include "ipsec_doi.h"
39 #include "log.h"
40 #include "crypto.h"
41 #include "modecfg.h"
42 #include "whack.h"
43 #include "xauth.h"
44
45 #define MAX_XAUTH_TRIES 3
46 #define DNS_SERVER_MAX 2
47 #define NBNS_SERVER_MAX 2
48
49 #define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
50 | LELEM(INTERNAL_IP4_NETMASK) \
51 | LELEM(INTERNAL_IP4_DNS) \
52 | LELEM(INTERNAL_IP4_NBNS) \
53 | LELEM(APPLICATION_VERSION) \
54 | LELEM(INTERNAL_IP6_DNS) \
55 | LELEM(INTERNAL_IP6_NBNS) \
56 )
57
58 #define SUPPORTED_UNITY_ATTR_SET ( LELEM(UNITY_BANNER - UNITY_BASE) )
59
60 #define UNITY_BANNER_STR "Welcome to strongSwan - the Linux VPN Solution!\n"
61
62 /*
63 * Addresses assigned (usually via ModeCfg) to the Initiator
64 */
65 typedef struct internal_addr internal_addr_t;
66
67 struct internal_addr
68 {
69 lset_t attr_set;
70 lset_t xauth_attr_set;
71 lset_t unity_attr_set;
72
73 /* ModeCfg variables */
74 ip_address ipaddr;
75 ip_address dns[DNS_SERVER_MAX];
76 ip_address nbns[NBNS_SERVER_MAX];
77
78 char *unity_banner;
79
80 /* XAUTH variables */
81 u_int16_t xauth_type;
82 xauth_t xauth_secret;
83 bool xauth_status;
84 };
85
86 /**
87 * Initialize an internal_addr struct
88 */
89 static void init_internal_addr(internal_addr_t *ia)
90 {
91 int i;
92
93 ia->attr_set = LEMPTY;
94 ia->xauth_attr_set = LEMPTY;
95 ia->xauth_secret.user_name = chunk_empty;
96 ia->xauth_secret.user_password = chunk_empty;
97 ia->xauth_type = XAUTH_TYPE_GENERIC;
98 ia->xauth_status = XAUTH_STATUS_FAIL;
99 ia->unity_attr_set = LEMPTY;
100 ia->unity_banner = NULL;
101
102 anyaddr(AF_INET, &ia->ipaddr);
103
104 /* initialize DNS server information */
105 for (i = 0; i < DNS_SERVER_MAX; i++)
106 {
107 anyaddr(AF_INET, &ia->dns[i]);
108 }
109
110 /* initialize NBNS server information */
111 for (i = 0; i < NBNS_SERVER_MAX; i++)
112 {
113 anyaddr(AF_INET, &ia->nbns[i]);
114 }
115 }
116
117 /**
118 * Get internal IP address for a connection
119 */
120 static void get_internal_addr(connection_t *c, host_t *requested_vip,
121 internal_addr_t *ia)
122 {
123 int dns_idx = 0, nbns_idx = 0;
124 enumerator_t *enumerator;
125 configuration_attribute_type_t type;
126 chunk_t value;
127 host_t *vip = NULL;
128
129 if (isanyaddr(&c->spd.that.host_srcip))
130 {
131 if (c->spd.that.pool)
132 {
133 vip = hydra->attributes->acquire_address(hydra->attributes,
134 c->spd.that.pool, c->spd.that.id,
135 requested_vip);
136 if (vip)
137 {
138 chunk_t addr = vip->get_address(vip);
139
140 plog("assigning virtual IP %H to peer", vip);
141 initaddr(addr.ptr, addr.len, vip->get_family(vip), &ia->ipaddr);
142
143 }
144 }
145 else
146 {
147 plog("no virtual IP found");
148 }
149 }
150 else
151 {
152 ia->ipaddr = c->spd.that.host_srcip;
153 vip = host_create_from_sockaddr((sockaddr_t*)&ia->ipaddr);
154 plog("assigning virtual IP %H to peer", vip);
155 }
156
157 if (!isanyaddr(&ia->ipaddr)) /* We got an IP address, send it */
158 {
159 c->spd.that.host_srcip = ia->ipaddr;
160 c->spd.that.client.addr = ia->ipaddr;
161 c->spd.that.client.maskbits = 32;
162 c->spd.that.has_client = TRUE;
163
164 ia->attr_set = LELEM(INTERNAL_IP4_ADDRESS)
165 | LELEM(INTERNAL_IP4_NETMASK);
166 }
167
168 /* assign attributes from registered providers */
169 enumerator = hydra->attributes->create_responder_enumerator(hydra->attributes,
170 c->spd.that.id, vip);
171 while (enumerator->enumerate(enumerator, &type, &value))
172 {
173 err_t ugh;
174 host_t *server;
175 sa_family_t family = AF_INET;
176
177 switch (type)
178 {
179 case INTERNAL_IP6_DNS:
180 family = AF_INET6;
181 /* fallthrough */
182 case INTERNAL_IP4_DNS:
183 if (dns_idx >= DNS_SERVER_MAX)
184 {
185 plog("exceeded the maximum number of %d DNS servers",
186 DNS_SERVER_MAX);
187 break;
188 }
189 ugh = initaddr(value.ptr, value.len, family, &ia->dns[dns_idx]);
190 if (ugh)
191 {
192 plog("error in DNS server address: %s", ugh);
193 break;
194 }
195 server = host_create_from_chunk(family, value, 0);
196 plog("assigning DNS server %H to peer", server);
197 server->destroy(server);
198
199 /* differentiate between IP4 and IP6 in modecfg_build_msg() */
200 ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
201 dns_idx++;
202 break;
203
204 case INTERNAL_IP6_NBNS:
205 family = AF_INET6;
206 /* fallthrough */
207 case INTERNAL_IP4_NBNS:
208 if (nbns_idx >= NBNS_SERVER_MAX)
209 {
210 plog("exceeded the maximum number of %d NBNS servers",
211 NBNS_SERVER_MAX);
212 break;
213 }
214 ugh = initaddr(value.ptr, value.len, family, &ia->nbns[nbns_idx]);
215 if (ugh)
216 {
217 plog("error in NBNS server address: %s", ugh);
218 break;
219 }
220 server = host_create_from_chunk(family, value, 0);
221 plog("assigning NBNS server %H to peer", server);
222 server->destroy(server);
223
224 /* differentiate between IP4 and IP6 in modecfg_build_msg() */
225 ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
226 nbns_idx++;
227 break;
228
229 default:
230 break;
231 }
232 }
233 enumerator->destroy(enumerator);
234 DESTROY_IF(vip);
235 }
236
237
238 /**
239 * Set srcip and client subnet to internal IP address
240 */
241 static bool set_internal_addr(connection_t *c, internal_addr_t *ia)
242 {
243 if (ia->attr_set & LELEM(INTERNAL_IP4_ADDRESS)
244 && !isanyaddr(&ia->ipaddr))
245 {
246 if (addrbytesptr(&c->spd.this.host_srcip, NULL) == 0
247 || isanyaddr(&c->spd.this.host_srcip)
248 || sameaddr(&c->spd.this.host_srcip, &ia->ipaddr))
249 {
250 char srcip[ADDRTOT_BUF];
251
252 addrtot(&ia->ipaddr, 0, srcip, sizeof(srcip));
253 plog("setting virtual IP source address to %s", srcip);
254 }
255 else
256 {
257 char old_srcip[ADDRTOT_BUF];
258 char new_srcip[ADDRTOT_BUF];
259
260 addrtot(&c->spd.this.host_srcip, 0, old_srcip, sizeof(old_srcip));
261 addrtot(&ia->ipaddr, 0, new_srcip, sizeof(new_srcip));
262 plog("replacing virtual IP source address %s by %s"
263 , old_srcip, new_srcip);
264 }
265
266 /* setting srcip */
267 c->spd.this.host_srcip = ia->ipaddr;
268
269 /* setting client subnet to srcip/32 */
270 addrtosubnet(&ia->ipaddr, &c->spd.this.client);
271 setportof(0, &c->spd.this.client.addr);
272 c->spd.this.has_client = TRUE;
273 return TRUE;
274 }
275 return FALSE;
276 }
277
278 /**
279 * Compute HASH of Mode Config.
280 */
281 static size_t modecfg_hash(u_char *dest, u_char *start, u_char *roof,
282 const struct state *st)
283 {
284 chunk_t msgid_chunk = chunk_from_thing(st->st_msgid);
285 chunk_t msg_chunk = { start, roof - start };
286 size_t prf_block_size;
287 pseudo_random_function_t prf_alg;
288 prf_t *prf;
289
290 prf_alg = oakley_to_prf(st->st_oakley.hash);
291 prf = lib->crypto->create_prf(lib->crypto, prf_alg);
292 prf->set_key(prf, st->st_skeyid_a);
293 prf->get_bytes(prf, msgid_chunk, NULL);
294 prf->get_bytes(prf, msg_chunk, dest);
295 prf_block_size = prf->get_block_size(prf);
296 prf->destroy(prf);
297
298 DBG(DBG_CRYPT,
299 DBG_log("ModeCfg HASH computed:");
300 DBG_dump("", dest, prf_block_size)
301 )
302 return prf_block_size;
303 }
304
305
306 /**
307 * Generate an IKE message containing ModeCfg information (eg: IP, DNS, WINS)
308 */
309 static stf_status modecfg_build_msg(struct state *st, pb_stream *rbody,
310 u_int16_t msg_type,
311 internal_addr_t *ia,
312 u_int16_t ap_id)
313 {
314 u_char *r_hash_start, *r_hashval;
315
316 START_HASH_PAYLOAD(*rbody, ISAKMP_NEXT_ATTR);
317
318 /* ATTR out */
319 {
320 struct isakmp_mode_attr attrh;
321 struct isakmp_attribute attr;
322 pb_stream strattr,attrval;
323 int attr_type, dns_attr_type, nbns_attr_type;
324 int dns_idx, nbns_idx;
325 bool dont_advance;
326 bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
327 bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
328 lset_t attr_set = ia->attr_set;
329
330 attrh.isama_np = ISAKMP_NEXT_NONE;
331 attrh.isama_type = msg_type;
332 attrh.isama_identifier = ap_id;
333
334 if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
335 {
336 return STF_INTERNAL_ERROR;
337 }
338 attr_type = 0;
339 dns_idx = 0;
340 nbns_idx = 0;
341
342 while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
343 {
344 if (attr_set == LEMPTY)
345 {
346 if (is_xauth_attr_set)
347 {
348 attr_set = ia->xauth_attr_set;
349 attr_type = XAUTH_BASE;
350 is_xauth_attr_set = FALSE;
351 }
352 else
353 {
354 attr_set = ia->unity_attr_set;
355 attr_type = UNITY_BASE;
356 is_unity_attr_set = FALSE;
357 }
358 }
359
360 dont_advance = FALSE;
361
362 if (attr_set & 1)
363 {
364 const u_char *byte_ptr;
365 u_int len;
366
367 /* ISAKMP attr out */
368 if (attr_type == XAUTH_TYPE)
369 {
370 attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
371 attr.isaat_lv = ia->xauth_type;
372 }
373 else if (attr_type == XAUTH_STATUS)
374 {
375 attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
376 attr.isaat_lv = ia->xauth_status;
377 }
378 else if (attr_type == INTERNAL_IP4_DNS && !isanyaddr(&ia->dns[dns_idx]))
379 {
380 dns_attr_type = (addrtypeof(&ia->dns[dns_idx]) == AF_INET) ?
381 INTERNAL_IP4_DNS : INTERNAL_IP6_DNS;
382 attr.isaat_af_type = dns_attr_type | ISAKMP_ATTR_AF_TLV;
383
384 }
385 else if (attr_type == INTERNAL_IP4_NBNS && !isanyaddr(&ia->nbns[nbns_idx]))
386 {
387 nbns_attr_type = (addrtypeof(&ia->nbns[nbns_idx]) == AF_INET) ?
388 INTERNAL_IP4_NBNS : INTERNAL_IP6_NBNS;
389 attr.isaat_af_type = nbns_attr_type | ISAKMP_ATTR_AF_TLV;
390
391 }
392 else
393 {
394 attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
395 }
396 out_struct(&attr, &isakmp_modecfg_attribute_desc, &strattr, &attrval);
397
398 switch (attr_type)
399 {
400 case INTERNAL_IP4_ADDRESS:
401 if (!isanyaddr(&ia->ipaddr))
402 {
403 len = addrbytesptr(&ia->ipaddr, &byte_ptr);
404 out_raw(byte_ptr, len, &attrval, "IP4_addr");
405 }
406 break;
407 case INTERNAL_IP4_NETMASK:
408 {
409 u_int mask;
410 #if 0
411 char mask[4],bits[8]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
412 int t,m=st->st_connection->that.host_addr.maskbit;
413 for (t=0; t<4; t++)
414 {
415 if (m < 8)
416 mask[t] = bits[m];
417 else
418 mask[t] = 0xff;
419 m -= 8;
420 }
421 #endif
422 if (st->st_connection->spd.this.client.maskbits == 0)
423 {
424 mask = 0;
425 }
426 else
427 {
428 mask = 0xffffffff * 1;
429 out_raw(&mask, 4, &attrval, "IP4_mask");
430 }
431 }
432 break;
433 case INTERNAL_IP4_SUBNET:
434 {
435 char mask[4];
436 char bits[8] = {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe};
437 int t;
438 int m = st->st_connection->spd.this.client.maskbits;
439
440 for (t = 0; t < 4; t++)
441 {
442 mask[t] = (m < 8) ? bits[m] : 0xff;
443 m -= 8;
444 if (m < 0)
445 {
446 m = 0;
447 }
448 }
449 len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
450 out_raw(byte_ptr, len, &attrval, "IP4_subnet");
451 out_raw(mask, sizeof(mask), &attrval, "IP4_submsk");
452 }
453 break;
454 case INTERNAL_IP4_DNS:
455 case INTERNAL_IP6_DNS:
456 if (!isanyaddr(&ia->dns[dns_idx]))
457 {
458 len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
459 out_raw(byte_ptr, len, &attrval, "IP_dns");
460 }
461 if (dns_idx < DNS_SERVER_MAX && !isanyaddr(&ia->dns[dns_idx]))
462 {
463 dont_advance = TRUE;
464 }
465 break;
466 case INTERNAL_IP4_NBNS:
467 case INTERNAL_IP6_NBNS:
468 if (!isanyaddr(&ia->nbns[nbns_idx]))
469 {
470 len = addrbytesptr(&ia->nbns[nbns_idx++], &byte_ptr);
471 out_raw(byte_ptr, len, &attrval, "IP_nbns");
472 }
473 if (nbns_idx < NBNS_SERVER_MAX && !isanyaddr(&ia->nbns[nbns_idx]))
474 {
475 dont_advance = TRUE;
476 }
477 break;
478 case XAUTH_TYPE:
479 break;
480 case XAUTH_USER_NAME:
481 if (ia->xauth_secret.user_name.ptr != NULL)
482 {
483 out_raw(ia->xauth_secret.user_name.ptr
484 , ia->xauth_secret.user_name.len
485 , &attrval, "xauth_user_name");
486 }
487 break;
488 case XAUTH_USER_PASSWORD:
489 if (ia->xauth_secret.user_password.ptr != NULL)
490 {
491 out_raw(ia->xauth_secret.user_password.ptr
492 , ia->xauth_secret.user_password.len
493 , &attrval, "xauth_user_password");
494 }
495 break;
496 case XAUTH_STATUS:
497 break;
498 case UNITY_BANNER:
499 if (ia->unity_banner != NULL)
500 {
501 out_raw(ia->unity_banner
502 , strlen(ia->unity_banner)
503 , &attrval, "UNITY_BANNER");
504 }
505 break;
506 default:
507 plog("attempt to send unsupported mode cfg attribute %s."
508 , enum_show(&modecfg_attr_names, attr_type));
509 break;
510 }
511 close_output_pbs(&attrval);
512 }
513 if (!dont_advance)
514 {
515 attr_type++;
516 attr_set >>= 1;
517 }
518 }
519 close_message(&strattr);
520 }
521
522 modecfg_hash(r_hashval, r_hash_start, rbody->cur, st);
523 close_message(rbody);
524 encrypt_message(rbody, st);
525 return STF_OK;
526 }
527
528 /**
529 * Send ModeCfg message
530 */
531 static stf_status modecfg_send_msg(struct state *st, int isama_type,
532 internal_addr_t *ia)
533 {
534 pb_stream msg;
535 pb_stream rbody;
536 char buf[BUF_LEN];
537
538 /* set up attr */
539 init_pbs(&msg, buf, sizeof(buf), "ModeCfg msg buffer");
540
541 /* this is the beginning of a new exchange */
542 st->st_msgid = generate_msgid(st);
543 init_phase2_iv(st, &st->st_msgid);
544
545 /* HDR out */
546 {
547 struct isakmp_hdr hdr;
548
549 zero(&hdr); /* default to 0 */
550 hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
551 hdr.isa_np = ISAKMP_NEXT_HASH;
552 hdr.isa_xchg = ISAKMP_XCHG_MODE_CFG;
553 hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
554 memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
555 memcpy(hdr.isa_rcookie, st->st_rcookie, COOKIE_SIZE);
556 hdr.isa_msgid = st->st_msgid;
557
558 if (!out_struct(&hdr, &isakmp_hdr_desc, &msg, &rbody))
559 {
560 return STF_INTERNAL_ERROR;
561 }
562 }
563
564 /* ATTR out */
565 modecfg_build_msg(st, &rbody
566 , isama_type
567 , ia
568 , 0 /* XXX isama_id */
569 );
570
571 free(st->st_tpacket.ptr);
572 st->st_tpacket = chunk_create(msg.start, pbs_offset(&msg));
573 st->st_tpacket = chunk_clone(st->st_tpacket);
574
575 /* Transmit */
576 send_packet(st, "ModeCfg msg");
577
578 if (st->st_event->ev_type != EVENT_RETRANSMIT)
579 {
580 delete_event(st);
581 event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);
582 }
583 return STF_OK;
584 }
585
586 /**
587 * Parse a ModeCfg attribute payload
588 */
589 static stf_status modecfg_parse_attributes(pb_stream *attrs, internal_addr_t *ia)
590 {
591 struct isakmp_attribute attr;
592 pb_stream strattr;
593 err_t ugh;
594 char buf[BUF_LEN];
595 int dns_idx = 0;
596 int nbns_idx = 0;
597
598 while (pbs_left(attrs) >= sizeof(struct isakmp_attribute))
599 {
600 u_int16_t attr_type;
601 u_int16_t attr_len;
602
603 if (!in_struct(&attr, &isakmp_modecfg_attribute_desc, attrs, &strattr))
604 {
605 return STF_FAIL;
606 }
607 attr_type = attr.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK;
608 attr_len = attr.isaat_lv;
609
610 switch (attr_type)
611 {
612 case INTERNAL_IP4_ADDRESS:
613 if (attr_len == 4)
614 {
615 ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->ipaddr);
616 if (ugh != NULL)
617 {
618 plog("received invalid virtual IPv4 address: %s", ugh);
619 }
620 }
621 ia->attr_set |= LELEM(attr_type);
622 break;
623 case INTERNAL_IP4_DNS:
624 if (attr_len == 4 && dns_idx < DNS_SERVER_MAX)
625 {
626 ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->dns[dns_idx]);
627 if (ugh != NULL)
628 {
629 plog("received invalid IPv4 DNS server address: %s", ugh);
630 }
631 else
632 {
633 addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
634 plog("received IPv4 DNS server address %s", buf);
635 dns_idx++;
636 }
637 }
638 ia->attr_set |= LELEM(attr_type);
639 break;
640 case INTERNAL_IP4_NBNS:
641 if (attr_len == 4 && nbns_idx < NBNS_SERVER_MAX)
642 {
643 ugh = initaddr((char *)(strattr.cur), 4, AF_INET, &ia->nbns[nbns_idx]);
644 if (ugh != NULL)
645 {
646 plog("received invalid IPv4 NBNS server address: %s", ugh);
647 }
648 else
649 {
650 addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
651 plog("received IPv4 NBNS server address %s", buf);
652 nbns_idx++;
653 }
654 }
655 ia->attr_set |= LELEM(attr_type);
656 break;
657 case INTERNAL_IP6_DNS:
658 if (attr_len == 16 && dns_idx < DNS_SERVER_MAX)
659 {
660 ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->dns[dns_idx]);
661 if (ugh != NULL)
662 {
663 plog("received invalid IPv6 DNS server address: %s", ugh);
664 }
665 else
666 {
667 addrtot(&ia->dns[dns_idx], 0, buf, BUF_LEN);
668 plog("received IPv6 DNS server address %s", buf);
669 dns_idx++;
670 }
671 }
672 ia->attr_set |= LELEM(attr_type);
673 break;
674 case INTERNAL_IP6_NBNS:
675 if (attr_len == 16 && nbns_idx < NBNS_SERVER_MAX)
676 {
677 ugh = initaddr((char *)(strattr.cur), 16, AF_INET6, &ia->nbns[nbns_idx]);
678 if (ugh != NULL)
679 {
680 plog("received invalid IPv6 NBNS server address: %s", ugh);
681 }
682 else
683 {
684 addrtot(&ia->nbns[nbns_idx], 0, buf, BUF_LEN);
685 plog("received IPv6 NBNS server address %s", buf);
686 nbns_idx++;
687 }
688 }
689 ia->attr_set |= LELEM(attr_type);
690 break;
691 case INTERNAL_IP4_NETMASK:
692 case INTERNAL_IP4_SUBNET:
693 case INTERNAL_ADDRESS_EXPIRY:
694 case INTERNAL_IP4_DHCP:
695 case INTERNAL_IP6_ADDRESS:
696 case INTERNAL_IP6_NETMASK:
697 case INTERNAL_IP6_DHCP:
698 case SUPPORTED_ATTRIBUTES:
699 case INTERNAL_IP6_SUBNET:
700 ia->attr_set |= LELEM(attr_type);
701 break;
702 case APPLICATION_VERSION:
703 if (attr_len > 0)
704 {
705 DBG(DBG_PARSING,
706 DBG_log(" '%.*s'", attr_len, strattr.cur)
707 )
708 }
709 ia->attr_set |= LELEM(attr_type);
710 break;
711 case XAUTH_TYPE:
712 ia->xauth_type = attr.isaat_lv;
713 ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
714 break;
715 case XAUTH_USER_NAME:
716 ia->xauth_secret.user_name = chunk_create(strattr.cur, attr_len);
717 ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
718 break;
719 case XAUTH_USER_PASSWORD:
720 ia->xauth_secret.user_password = chunk_create(strattr.cur, attr_len);
721 ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
722 break;
723 case XAUTH_STATUS:
724 ia->xauth_status = attr.isaat_lv;
725 ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
726 break;
727 case XAUTH_MESSAGE:
728 if (attr_len > 0)
729 {
730 DBG(DBG_PARSING,
731 DBG_log(" '%.*s'", attr_len, strattr.cur)
732 )
733 }
734 /* fall through to set attribute flag */
735 case XAUTH_PASSCODE:
736 case XAUTH_CHALLENGE:
737 case XAUTH_DOMAIN:
738 case XAUTH_NEXT_PIN:
739 case XAUTH_ANSWER:
740 ia->xauth_attr_set |= LELEM(attr_type - XAUTH_BASE);
741 break;
742 case UNITY_DDNS_HOSTNAME:
743 if (attr_len > 0)
744 {
745 DBG(DBG_PARSING,
746 DBG_log(" '%.*s'", attr_len, strattr.cur)
747 )
748 }
749 /* fall through to set attribute flag */
750 case UNITY_BANNER:
751 case UNITY_SAVE_PASSWD:
752 case UNITY_DEF_DOMAIN:
753 case UNITY_SPLITDNS_NAME:
754 case UNITY_SPLIT_INCLUDE:
755 case UNITY_NATT_PORT:
756 case UNITY_LOCAL_LAN:
757 case UNITY_PFS:
758 case UNITY_FW_TYPE:
759 case UNITY_BACKUP_SERVERS:
760 ia->unity_attr_set |= LELEM(attr_type - UNITY_BASE);
761 break;
762 default:
763 plog("unsupported ModeCfg attribute %s received."
764 , enum_show(&modecfg_attr_names, attr_type));
765 break;
766 }
767 }
768 return STF_OK;
769 }
770
771 /**
772 * Parse a ModeCfg message
773 */
774 static stf_status modecfg_parse_msg(struct msg_digest *md, int isama_type,
775 u_int16_t *isama_id, internal_addr_t *ia)
776 {
777 struct state *const st = md->st;
778 struct payload_digest *p;
779 stf_status stat;
780
781 st->st_msgid = md->hdr.isa_msgid;
782
783 CHECK_QUICK_HASH(md, modecfg_hash(hash_val
784 , hash_pbs->roof
785 , md->message_pbs.roof, st)
786 , "MODECFG-HASH", "ISAKMP_CFG_MSG");
787
788 /* process the ModeCfg payloads received */
789 for (p = md->chain[ISAKMP_NEXT_ATTR]; p != NULL; p = p->next)
790 {
791 internal_addr_t ia_candidate;
792
793 init_internal_addr(&ia_candidate);
794
795 if (p->payload.attribute.isama_type == isama_type)
796 {
797 *isama_id = p->payload.attribute.isama_identifier;
798
799 stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
800 if (stat == STF_OK)
801 {
802 /* return with a valid set of attributes */
803 *ia = ia_candidate;
804 return STF_OK;
805 }
806 }
807 else
808 {
809 plog("expected %s, got %s instead (ignored)"
810 , enum_name(&attr_msg_type_names, isama_type)
811 , enum_name(&attr_msg_type_names, p->payload.attribute.isama_type));
812
813 stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
814 }
815 if (stat != STF_OK)
816 {
817 return stat;
818 }
819 }
820 return STF_IGNORE;
821 }
822
823 /**
824 * Send ModeCfg request message from client to server in pull mode
825 */
826 stf_status modecfg_send_request(struct state *st)
827 {
828 connection_t *c = st->st_connection;
829 stf_status stat;
830 internal_addr_t ia;
831
832 init_internal_addr(&ia);
833
834 ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
835 | LELEM(INTERNAL_IP4_NETMASK);
836 ia.ipaddr = c->spd.this.host_srcip;
837
838 plog("sending ModeCfg request");
839 st->st_state = STATE_MODE_CFG_I1;
840 stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
841 if (stat == STF_OK)
842 {
843 st->st_modecfg.started = TRUE;
844 }
845 return stat;
846 }
847
848 /* STATE_MODE_CFG_R0:
849 * HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
850 *
851 * used in ModeCfg pull mode, on the server (responder)
852 */
853 stf_status modecfg_inR0(struct msg_digest *md)
854 {
855 struct state *const st = md->st;
856 u_int16_t isama_id;
857 internal_addr_t ia;
858 bool want_unity_banner;
859 stf_status stat, stat_build;
860 host_t *requested_vip;
861
862 stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
863 if (stat != STF_OK)
864 {
865 return stat;
866 }
867
868 if (ia.attr_set & LELEM(INTERNAL_IP4_ADDRESS))
869 {
870 requested_vip = host_create_from_sockaddr((sockaddr_t*)&ia.ipaddr);
871 }
872 else
873 {
874 requested_vip = host_create_any(AF_INET);
875 }
876 plog("peer requested virtual IP %H", requested_vip);
877
878 want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
879 init_internal_addr(&ia);
880 get_internal_addr(st->st_connection, requested_vip, &ia);
881 requested_vip->destroy(requested_vip);
882
883 if (want_unity_banner)
884 {
885 ia.unity_banner = UNITY_BANNER_STR;
886 ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
887 }
888
889 plog("sending ModeCfg reply");
890
891 stat_build = modecfg_build_msg(st, &md->rbody
892 , ISAKMP_CFG_REPLY
893 , &ia
894 , isama_id);
895 if (stat_build != STF_OK)
896 {
897 return stat_build;
898 }
899 st->st_msgid = 0;
900 return STF_OK;
901 }
902
903 /* STATE_MODE_CFG_I1:
904 * HDR*, HASH, ATTR(REPLY=IP)
905 *
906 * used in ModeCfg pull mode, on the client (initiator)
907 */
908 stf_status modecfg_inI1(struct msg_digest *md)
909 {
910 struct state *const st = md->st;
911 u_int16_t isama_id;
912 internal_addr_t ia;
913 stf_status stat;
914
915 plog("parsing ModeCfg reply");
916
917 stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
918 if (stat != STF_OK)
919 {
920 return stat;
921 }
922 st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
923 st->st_msgid = 0;
924 return STF_OK;
925 }
926
927
928 /**
929 * Send ModeCfg set message from server to client in push mode
930 */
931 stf_status modecfg_send_set(struct state *st)
932 {
933 stf_status stat;
934 internal_addr_t ia;
935 host_t *vip;
936
937 init_internal_addr(&ia);
938 vip = host_create_any(AF_INET);
939 get_internal_addr(st->st_connection, vip, &ia);
940 vip->destroy(vip);
941
942 #ifdef CISCO_QUIRKS
943 ia.unity_banner = UNITY_BANNER_STR;
944 ia.unity_attr_set |= LELEM(UNITY_BANNER - UNITY_BASE);
945 #endif
946
947 plog("sending ModeCfg set");
948 st->st_state = STATE_MODE_CFG_R3;
949 stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
950 if (stat == STF_OK)
951 {
952 st->st_modecfg.started = TRUE;
953 }
954 return stat;
955 }
956
957 /* STATE_MODE_CFG_I0:
958 * HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
959 *
960 * used in ModeCfg push mode, on the client (initiator).
961 */
962 stf_status modecfg_inI0(struct msg_digest *md)
963 {
964 struct state *const st = md->st;
965 u_int16_t isama_id;
966 internal_addr_t ia;
967 lset_t attr_set, unity_attr_set;
968 stf_status stat, stat_build;
969
970 plog("parsing ModeCfg set");
971
972 stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
973 if (stat != STF_OK)
974 {
975 return stat;
976 }
977 st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
978
979 /* prepare ModeCfg ack which sends zero length attributes */
980 attr_set = ia.attr_set;
981 unity_attr_set = ia.unity_attr_set;
982 init_internal_addr(&ia);
983 ia.attr_set = attr_set & SUPPORTED_ATTR_SET;
984 ia.unity_attr_set = unity_attr_set & SUPPORTED_UNITY_ATTR_SET;
985
986 plog("sending ModeCfg ack");
987
988 stat_build = modecfg_build_msg(st, &md->rbody
989 , ISAKMP_CFG_ACK
990 , &ia
991 , isama_id);
992 if (stat_build != STF_OK)
993 {
994 return stat_build;
995 }
996 st->st_msgid = 0;
997 return STF_OK;
998 }
999
1000 /* STATE_MODE_CFG_R3:
1001 * HDR*, HASH, ATTR(ACK,OK)
1002 *
1003 * used in ModeCfg push mode, on the server (responder)
1004 */
1005 stf_status modecfg_inR3(struct msg_digest *md)
1006 {
1007 struct state *const st = md->st;
1008 u_int16_t isama_id;
1009 internal_addr_t ia;
1010 stf_status stat;
1011
1012 plog("parsing ModeCfg ack");
1013
1014 stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
1015 if (stat != STF_OK)
1016 {
1017 return stat;
1018 }
1019 st->st_msgid = 0;
1020 return STF_OK;
1021 }
1022
1023 /**
1024 * Send XAUTH credentials request (username + password)
1025 */
1026 stf_status xauth_send_request(struct state *st)
1027 {
1028 stf_status stat;
1029 internal_addr_t ia;
1030
1031 init_internal_addr(&ia);
1032 ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
1033 | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
1034
1035 plog("sending XAUTH request");
1036 st->st_state = STATE_XAUTH_R1;
1037 stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
1038 if (stat == STF_OK)
1039 {
1040 st->st_xauth.started = TRUE;
1041 }
1042 return stat;
1043 }
1044
1045 /* STATE_XAUTH_I0:
1046 * HDR*, HASH, ATTR(REQ) --> HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD)
1047 *
1048 * used on the XAUTH client (initiator)
1049 */
1050 stf_status xauth_inI0(struct msg_digest *md)
1051 {
1052 struct state *const st = md->st;
1053 u_int16_t isama_id;
1054 internal_addr_t ia;
1055 stf_status stat, stat_build;
1056 bool xauth_type_present;
1057
1058 plog("parsing XAUTH request");
1059
1060 stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
1061 if (stat != STF_OK)
1062 {
1063 return stat;
1064 }
1065
1066 /* check XAUTH attributes */
1067 xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
1068
1069 if (xauth_type_present && ia.xauth_type != XAUTH_TYPE_GENERIC)
1070 {
1071 plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
1072 stat = STF_FAIL;
1073 }
1074 else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
1075 {
1076 plog("user name attribute is missing in XAUTH request");
1077 stat = STF_FAIL;
1078 }
1079 else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
1080 {
1081 plog("user password attribute is missing in XAUTH request");
1082 stat = STF_FAIL;
1083 }
1084
1085 /* prepare XAUTH reply */
1086 init_internal_addr(&ia);
1087
1088 if (stat == STF_OK)
1089 {
1090 /* get user credentials using a plugin function */
1091 if (!xauth_module.get_secret(&ia.xauth_secret))
1092 {
1093 plog("xauth user credentials not found");
1094 stat = STF_FAIL;
1095 }
1096 }
1097 if (stat == STF_OK)
1098 {
1099 DBG(DBG_CONTROL,
1100 DBG_log("my xauth user name is '%.*s'"
1101 , ia.xauth_secret.user_name.len
1102 , ia.xauth_secret.user_name.ptr)
1103 )
1104 DBG(DBG_PRIVATE,
1105 DBG_log("my xauth user password is '%.*s'"
1106 , ia.xauth_secret.user_password.len
1107 , ia.xauth_secret.user_password.ptr)
1108 )
1109 ia.xauth_attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE)
1110 | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
1111 if (xauth_type_present)
1112 {
1113 ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
1114 }
1115 }
1116 else
1117 {
1118 ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
1119 ia.xauth_status = XAUTH_STATUS_FAIL;
1120 }
1121
1122 plog("sending XAUTH reply");
1123
1124 stat_build = modecfg_build_msg(st, &md->rbody
1125 , ISAKMP_CFG_REPLY
1126 , &ia
1127 , isama_id);
1128 if (stat_build != STF_OK)
1129 {
1130 return stat_build;
1131 }
1132 if (stat == STF_OK)
1133 {
1134 st->st_xauth.started = TRUE;
1135 st->st_msgid = 0;
1136 return STF_OK;
1137 }
1138 else
1139 {
1140 /* send XAUTH reply msg and then delete ISAKMP SA */
1141 free(st->st_tpacket.ptr);
1142 st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
1143 st->st_tpacket = chunk_clone(st->st_tpacket);
1144 send_packet(st, "XAUTH reply msg");
1145 delete_state(st);
1146 return STF_IGNORE;
1147 }
1148 }
1149
1150 /* STATE_XAUTH_R1:
1151 * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
1152 *
1153 * used on the XAUTH server (responder)
1154 */
1155 stf_status xauth_inR1(struct msg_digest *md)
1156 {
1157 struct state *const st = md->st;
1158 u_int16_t isama_id;
1159 internal_addr_t ia;
1160 stf_status stat, stat_build;
1161
1162 plog("parsing XAUTH reply");
1163
1164 stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
1165 if (stat != STF_OK)
1166 {
1167 return stat;
1168 }
1169
1170 /* did the client return an XAUTH FAIL status? */
1171 if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
1172 {
1173 plog("received FAIL status in XAUTH reply");
1174
1175 /* client is not able to do XAUTH, delete ISAKMP SA */
1176 delete_state(st);
1177 return STF_IGNORE;
1178 }
1179
1180 /* check XAUTH reply */
1181 if ((ia.xauth_attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE)) == LEMPTY)
1182 {
1183 plog("user name attribute is missing in XAUTH reply");
1184 st->st_xauth.status = FALSE;
1185 }
1186 else if ((ia.xauth_attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE)) == LEMPTY)
1187 {
1188 plog("user password attribute is missing in XAUTH reply");
1189 st->st_xauth.status = FALSE;
1190 }
1191 else
1192 {
1193 xauth_peer_t peer;
1194
1195 peer.conn_name = st->st_connection->name;
1196 addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
1197 snprintf(peer.id, sizeof(peer.id), "%Y",
1198 md->st->st_connection->spd.that.id);
1199
1200 DBG(DBG_CONTROL,
1201 DBG_log("peer xauth user name is '%.*s'"
1202 , ia.xauth_secret.user_name.len
1203 , ia.xauth_secret.user_name.ptr)
1204 )
1205 DBG(DBG_PRIVATE,
1206 DBG_log("peer xauth user password is '%.*s'"
1207 , ia.xauth_secret.user_password.len
1208 , ia.xauth_secret.user_password.ptr)
1209 )
1210 /* verify the user credentials using a plugin function */
1211 st->st_xauth.status = xauth_module.verify_secret(&peer, &ia.xauth_secret);
1212 plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
1213 }
1214
1215 /* prepare XAUTH set which sends the authentication status */
1216 init_internal_addr(&ia);
1217 ia.xauth_attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE);
1218 ia.xauth_status = (st->st_xauth.status)? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
1219
1220 plog("sending XAUTH status:");
1221
1222 stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
1223 if (stat_build != STF_OK)
1224 {
1225 return stat_build;
1226 }
1227 return STF_OK;
1228 }
1229
1230 /* STATE_XAUTH_I1:
1231 * HDR*, HASH, ATTR(STATUS) --> HDR*, HASH, ATTR(ACK)
1232 *
1233 * used on the XAUTH client (initiator)
1234 */
1235 stf_status xauth_inI1(struct msg_digest *md)
1236 {
1237 struct state *const st = md->st;
1238 u_int16_t isama_id;
1239 internal_addr_t ia;
1240 stf_status stat, stat_build;
1241
1242 plog("parsing XAUTH status");
1243 stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
1244 if (stat != STF_OK)
1245 {
1246 /* notification payload - not exactly the right choice, but okay */
1247 md->note = ISAKMP_ATTRIBUTES_NOT_SUPPORTED;
1248 return stat;
1249 }
1250
1251 st->st_xauth.status = ia.xauth_status;
1252 plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
1253
1254 plog("sending XAUTH ack");
1255 init_internal_addr(&ia);
1256 stat_build = modecfg_build_msg(st, &md->rbody
1257 , ISAKMP_CFG_ACK
1258 , &ia
1259 , isama_id);
1260 if (stat_build != STF_OK)
1261 {
1262 return stat_build;
1263 }
1264 if (st->st_xauth.status)
1265 {
1266 st->st_msgid = 0;
1267 return STF_OK;
1268 }
1269 else
1270 {
1271 /* send XAUTH ack msg and then delete ISAKMP SA */
1272 free(st->st_tpacket.ptr);
1273 st->st_tpacket = chunk_create(md->reply.start, pbs_offset(&md->reply));
1274 st->st_tpacket = chunk_clone(st->st_tpacket);
1275 send_packet(st, "XAUTH ack msg");
1276 delete_state(st);
1277 return STF_IGNORE;
1278 }
1279 }
1280
1281 /* STATE_XAUTH_R2:
1282 * HDR*, ATTR(STATUS), HASH --> Done
1283 *
1284 * used on the XAUTH server (responder)
1285 */
1286 stf_status xauth_inR2(struct msg_digest *md)
1287 {
1288 struct state *const st = md->st;
1289 u_int16_t isama_id;
1290 internal_addr_t ia;
1291 stf_status stat;
1292
1293 plog("parsing XAUTH ack");
1294
1295 stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
1296 if (stat != STF_OK)
1297 {
1298 return stat;
1299 }
1300 st->st_msgid = 0;
1301 if (st->st_xauth.status)
1302 {
1303 return STF_OK;
1304 }
1305 else
1306 {
1307 delete_state(st);
1308 return STF_IGNORE;
1309 }
1310 }