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