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