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