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