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