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