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