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