]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_xauth.c
ipsec-326.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_xauth.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp_xauth.c,v 1.11.6.1 2007/08/07 04:49:24 manu Exp $ */
2
3/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
52b7d2ce
A
4
5/*
6 * Copyright (C) 2004-2005 Emmanuel Dreyfus
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39#include <sys/queue.h>
40
41#include <netinet/in.h>
42
43#include <stdlib.h>
44#include <stdio.h>
45#include <string.h>
46#include <errno.h>
47#include <pwd.h>
d1e348cf 48#include <grp.h>
52b7d2ce
A
49#if TIME_WITH_SYS_TIME
50# include <sys/time.h>
51# include <time.h>
52#else
53# if HAVE_SYS_TIME_H
54# include <sys/time.h>
55# else
56# include <time.h>
57# endif
58#endif
59#include <netdb.h>
60#ifdef HAVE_UNISTD_H
61#include <unistd.h>
62#endif
63#include <ctype.h>
d1e348cf
A
64
65#ifdef HAVE_SHADOW_H
66#include <shadow.h>
67#endif
52b7d2ce
A
68
69#include "var.h"
70#include "misc.h"
71#include "vmbuf.h"
72#include "plog.h"
73#include "sockmisc.h"
74#include "schedule.h"
75#include "debug.h"
65c25746 76#include "fsm.h"
52b7d2ce
A
77
78#include "crypto_openssl.h"
79#include "isakmp_var.h"
80#include "isakmp.h"
52b7d2ce
A
81#include "handler.h"
82#include "throttle.h"
83#include "remoteconf.h"
84#include "isakmp_inf.h"
85#include "isakmp_xauth.h"
86#include "isakmp_unity.h"
87#include "isakmp_cfg.h"
88#include "strnames.h"
89#include "ipsec_doi.h"
90#include "remoteconf.h"
91#include "localconf.h"
d1e348cf
A
92#include "vpn_control.h"
93#include "vpn_control_var.h"
94#include "ipsecSessionTracer.h"
95#include "ipsecMessageTracer.h"
52b7d2ce 96
52b7d2ce
A
97
98void
99xauth_sendreq(iph1)
65c25746 100 phase1_handle_t *iph1;
52b7d2ce
A
101{
102 vchar_t *buffer;
103 struct isakmp_pl_attr *attr;
104 struct isakmp_data *typeattr;
105 struct isakmp_data *usrattr;
106 struct isakmp_data *pwdattr;
107 struct xauth_state *xst = &iph1->mode_cfg->xauth;
108 size_t tlen;
109
110 /* Status checks */
65c25746
A
111 if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
112 plog(ASL_LEVEL_ERR,
52b7d2ce
A
113 "Xauth request while phase 1 is not completed\n");
114 return;
115 }
116
117 if (xst->status != XAUTHST_NOTYET) {
65c25746 118 plog(ASL_LEVEL_ERR,
52b7d2ce
A
119 "Xauth request whith Xauth state %d\n", xst->status);
120 return;
121 }
122
7ebaebe2 123 plog(ASL_LEVEL_NOTICE, "Sending Xauth request\n");
52b7d2ce
A
124
125 tlen = sizeof(*attr) +
126 + sizeof(*typeattr) +
127 + sizeof(*usrattr) +
128 + sizeof(*pwdattr);
129
130 if ((buffer = vmalloc(tlen)) == NULL) {
65c25746 131 plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
52b7d2ce
A
132 return;
133 }
134
135 attr = (struct isakmp_pl_attr *)buffer->v;
136 memset(attr, 0, tlen);
137
138 attr->h.len = htons(tlen);
139 attr->type = ISAKMP_CFG_REQUEST;
140 attr->id = htons(eay_random());
141
142 typeattr = (struct isakmp_data *)(attr + 1);
143 typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
144 typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
145
146 usrattr = (struct isakmp_data *)(typeattr + 1);
147 usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
148 usrattr->lorv = htons(0);
149
150 pwdattr = (struct isakmp_data *)(usrattr + 1);
151 pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
152 pwdattr->lorv = htons(0);
153
154 isakmp_cfg_send(iph1, buffer,
d1e348cf 155 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
52b7d2ce
A
156
157 vfree(buffer);
158
159 xst->status = XAUTHST_REQSENT;
160
161 return;
162}
163
d1e348cf 164int
52b7d2ce 165xauth_attr_reply(iph1, attr, id)
65c25746 166 phase1_handle_t *iph1;
52b7d2ce
A
167 struct isakmp_data *attr;
168 int id;
169{
170 char **outlet = NULL;
171 size_t alen = 0;
172 int type;
173 struct xauth_state *xst = &iph1->mode_cfg->xauth;
174
175 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
65c25746 176 plog(ASL_LEVEL_ERR,
52b7d2ce
A
177 "Xauth reply but peer did not declare "
178 "itself as Xauth capable\n");
d1e348cf 179 return -1;
52b7d2ce
A
180 }
181
182 if (xst->status != XAUTHST_REQSENT) {
65c25746 183 plog(ASL_LEVEL_ERR,
52b7d2ce 184 "Xauth reply while Xauth state is %d\n", xst->status);
d1e348cf 185 return -1;
52b7d2ce
A
186 }
187
188 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
189 switch (type) {
190 case XAUTH_TYPE:
191 switch (ntohs(attr->lorv)) {
192 case XAUTH_TYPE_GENERIC:
193 xst->authtype = XAUTH_TYPE_GENERIC;
194 break;
195 default:
65c25746 196 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
197 "Unexpected authentication type %d\n",
198 ntohs(type));
d1e348cf 199 return -1;
52b7d2ce
A
200 }
201 break;
202
203 case XAUTH_USER_NAME:
204 outlet = &xst->authdata.generic.usr;
205 break;
206
207 case XAUTH_USER_PASSWORD:
208 outlet = &xst->authdata.generic.pwd;
209 break;
210
211 default:
65c25746 212 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
213 "ignored Xauth attribute %d\n", type);
214 break;
215 }
216
217 if (outlet != NULL) {
218 alen = ntohs(attr->lorv);
219
d1e348cf 220 if ((*outlet = racoon_realloc(*outlet, alen + 1)) == NULL) {
65c25746 221 plog(ASL_LEVEL_ERR,
52b7d2ce 222 "Cannot allocate memory for Xauth Data\n");
d1e348cf 223 return -1;
52b7d2ce
A
224 }
225
226 memcpy(*outlet, attr + 1, alen);
227 (*outlet)[alen] = '\0';
228 outlet = NULL;
229 }
230
231
232 if ((xst->authdata.generic.usr != NULL) &&
233 (xst->authdata.generic.pwd != NULL)) {
234 int port;
235 int res;
236 char *usr = xst->authdata.generic.usr;
237 char *pwd = xst->authdata.generic.pwd;
238 time_t throttle_delay = 0;
239
240#if 0 /* Real debug, don't do that at home */
65c25746 241 plog(ASL_LEVEL_DEBUG,
52b7d2ce
A
242 "Got username \"%s\", password \"%s\"\n", usr, pwd);
243#endif
d1e348cf 244 strlcpy(iph1->mode_cfg->login, usr, sizeof(iph1->mode_cfg->login));
52b7d2ce
A
245
246 res = -1;
247 if ((port = isakmp_cfg_getport(iph1)) == -1) {
65c25746 248 plog(ASL_LEVEL_ERR,
52b7d2ce
A
249 "Port pool depleted\n");
250 goto skip_auth;
251 }
252
253 switch (isakmp_cfg_config.authsource) {
254 case ISAKMP_CFG_AUTH_SYSTEM:
e8d9021d 255 res = xauth_login_system(usr, pwd);
52b7d2ce 256 break;
65c25746 257
52b7d2ce 258 default:
65c25746 259 plog(ASL_LEVEL_ERR,
52b7d2ce
A
260 "Unexpected authentication source\n");
261 res = -1;
262 break;
263 }
264
d1e348cf
A
265 /*
266 * Optional group authentication
267 */
268 if (!res && (isakmp_cfg_config.groupcount))
269 res = group_check(iph1,
270 isakmp_cfg_config.grouplist,
271 isakmp_cfg_config.groupcount);
272
52b7d2ce
A
273 /*
274 * On failure, throttle the connexion for the remote host
275 * in order to make password attacks more difficult.
276 */
277 throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
278 if (throttle_delay > 0) {
279 char *str;
280
85f41bec 281 str = saddrwop2str((struct sockaddr *)iph1->remote);
52b7d2ce 282
65c25746 283 plog(ASL_LEVEL_ERR,
52b7d2ce
A
284 "Throttling in action for %s: delay %lds\n",
285 str, (unsigned long)throttle_delay);
286 res = -1;
287 } else {
288 throttle_delay = 0;
289 }
290
291skip_auth:
292 if (throttle_delay != 0) {
293 struct xauth_reply_arg *xra;
294
295 if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
65c25746 296 plog(ASL_LEVEL_ERR,
52b7d2ce 297 "malloc failed, bypass throttling\n");
d1e348cf 298 return xauth_reply(iph1, port, id, res);
52b7d2ce
A
299 }
300
301 /*
302 * We need to store the ph1, but it might have
303 * disapeared when xauth_reply is called, so
304 * store the index instead.
305 */
306 xra->index = iph1->index;
307 xra->port = port;
308 xra->id = id;
309 xra->res = res;
310 sched_new(throttle_delay, xauth_reply_stub, xra);
311 } else {
d1e348cf 312 return xauth_reply(iph1, port, id, res);
52b7d2ce
A
313 }
314 }
315
d1e348cf 316 return 0;
52b7d2ce
A
317}
318
319void
320xauth_reply_stub(args)
321 void *args;
322{
323 struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
65c25746 324 phase1_handle_t *iph1;
52b7d2ce 325
65c25746 326 if ((iph1 = ike_session_getph1byindex(NULL, &xra->index)) != NULL)
d1e348cf 327 (void)xauth_reply(iph1, xra->port, xra->id, xra->res);
52b7d2ce 328 else
65c25746 329 plog(ASL_LEVEL_ERR,
52b7d2ce
A
330 "Delayed Xauth reply: phase 1 no longer exists.\n");
331
332 racoon_free(xra);
333 return;
334}
335
d1e348cf 336int
52b7d2ce 337xauth_reply(iph1, port, id, res)
65c25746 338 phase1_handle_t *iph1;
52b7d2ce
A
339 int port;
340 int id;
341{
342 struct xauth_state *xst = &iph1->mode_cfg->xauth;
343 char *usr = xst->authdata.generic.usr;
344
e8d9021d 345 if (iph1->is_dying) {
7ebaebe2 346 plog(ASL_LEVEL_NOTICE,
e8d9021d
A
347 "dropped login for user \"%s\"\n", usr);
348 return -1;
349 }
350
52b7d2ce
A
351 if (res != 0) {
352 if (port != -1)
353 isakmp_cfg_putport(iph1, port);
354
7ebaebe2 355 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
356 "login failed for user \"%s\"\n", usr);
357
358 xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
359 xst->status = XAUTHST_NOTYET;
360
361 /* Delete Phase 1 SA */
65c25746 362 if (FSM_STATE_IS_ESTABLISHED(iph1->status))
52b7d2ce 363 isakmp_info_send_d1(iph1);
47612122 364 isakmp_ph1expire(iph1);
52b7d2ce 365
d1e348cf 366 return -1;
52b7d2ce
A
367 }
368
369 xst->status = XAUTHST_OK;
7ebaebe2 370 plog(ASL_LEVEL_NOTICE,
52b7d2ce
A
371 "login succeeded for user \"%s\"\n", usr);
372
373 xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
374
d1e348cf 375 return 0;
52b7d2ce
A
376}
377
378void
379xauth_sendstatus(iph1, status, id)
65c25746 380 phase1_handle_t *iph1;
52b7d2ce
A
381 int status;
382 int id;
383{
384 vchar_t *buffer;
385 struct isakmp_pl_attr *attr;
386 struct isakmp_data *stattr;
387 size_t tlen;
388
389 tlen = sizeof(*attr) +
390 + sizeof(*stattr);
391
392 if ((buffer = vmalloc(tlen)) == NULL) {
65c25746 393 plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
52b7d2ce
A
394 return;
395 }
396
397 attr = (struct isakmp_pl_attr *)buffer->v;
398 memset(attr, 0, tlen);
399
400 attr->h.len = htons(tlen);
401 attr->type = ISAKMP_CFG_SET;
402 attr->id = htons(id);
403
404 stattr = (struct isakmp_data *)(attr + 1);
405 stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
406 stattr->lorv = htons(status);
407
408 isakmp_cfg_send(iph1, buffer,
d1e348cf 409 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
52b7d2ce
A
410
411 vfree(buffer);
412
413 return;
414}
415
d1e348cf 416
52b7d2ce
A
417int
418xauth_login_system(usr, pwd)
419 char *usr;
420 char *pwd;
421{
422 struct passwd *pw;
423 char *cryptpwd;
424 char *syscryptpwd;
425#ifdef HAVE_SHADOW_H
426 struct spwd *spw;
427
428 if ((spw = getspnam(usr)) == NULL)
429 return -1;
430
431 syscryptpwd = spw->sp_pwdp;
432#endif
433
434 if ((pw = getpwnam(usr)) == NULL)
435 return -1;
436
437#ifndef HAVE_SHADOW_H
438 syscryptpwd = pw->pw_passwd;
439#endif
440
441 /* No root login. Ever. */
442 if (pw->pw_uid == 0)
443 return -1;
444
445 if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
446 return -1;
447
448 if (strcmp(cryptpwd, syscryptpwd) == 0)
449 return 0;
450
451 return -1;
452}
453
d1e348cf
A
454int
455xauth_group_system(usr, grp)
456 char * usr;
457 char * grp;
458{
459 struct group * gr;
460 char * member;
461 int index = 0;
462
463 gr = getgrnam(grp);
464 if (gr == NULL) {
65c25746 465 plog(ASL_LEVEL_ERR,
d1e348cf
A
466 "the system group name \'%s\' is unknown\n",
467 grp);
468 return -1;
469 }
470
471 while ((member = gr->gr_mem[index++])!=NULL) {
472 if (!strcmp(member,usr)) {
7ebaebe2 473 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
474 "membership validated\n");
475 return 0;
476 }
477 }
478
479 return -1;
480}
481
52b7d2ce
A
482int
483xauth_check(iph1)
65c25746 484 phase1_handle_t *iph1;
52b7d2ce
A
485{
486 struct xauth_state *xst = &iph1->mode_cfg->xauth;
487
d1e348cf
A
488 /*
489 * Only the server side (edge device) really check for Xauth
490 * status. It does it if the chose authmethod is using Xauth.
491 * On the client side (roadwarrior), we don't check anything.
492 */
493 switch (AUTHMETHOD(iph1)) {
494 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
495 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
496 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
52b7d2ce 497 /* The following are not yet implemented */
d1e348cf
A
498 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
499 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
52b7d2ce 500 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
65c25746 501 plog(ASL_LEVEL_ERR,
52b7d2ce
A
502 "Hybrid auth negotiated but peer did not "
503 "announced as Xauth capable\n");
504 return -1;
505 }
506
507 if (xst->status != XAUTHST_OK) {
65c25746 508 plog(ASL_LEVEL_ERR,
52b7d2ce
A
509 "Hybrid auth negotiated but peer did not "
510 "succeed Xauth exchange\n");
511 return -1;
512 }
513
514 return 0;
515 break;
516 default:
517 return 0;
518 break;
519 }
520
521 return 0;
522}
523
d1e348cf
A
524int
525group_check(iph1, grp_list, grp_count)
65c25746 526 phase1_handle_t *iph1;
d1e348cf
A
527 char **grp_list;
528 int grp_count;
529{
530 int res = -1;
531 int grp_index = 0;
532 char * usr = NULL;
533
534 /* check for presence of modecfg data */
535
536 if(iph1->mode_cfg == NULL) {
65c25746 537 plog(ASL_LEVEL_ERR,
d1e348cf
A
538 "xauth group specified but modecfg not found\n");
539 return res;
540 }
541
542 /* loop through our group list */
543
544 for(; grp_index < grp_count; grp_index++) {
545
546 /* check for presence of xauth data */
547
548 usr = iph1->mode_cfg->xauth.authdata.generic.usr;
549
550 if(usr == NULL) {
65c25746 551 plog(ASL_LEVEL_ERR,
d1e348cf
A
552 "xauth group specified but xauth not found\n");
553 return res;
554 }
555
556 /* call appropriate group validation funtion */
557
558 switch (isakmp_cfg_config.groupsource) {
559
560 case ISAKMP_CFG_GROUP_SYSTEM:
561 res = xauth_group_system(
562 usr,
563 grp_list[grp_index]);
564 break;
565
d1e348cf
A
566 default:
567 /* we should never get here */
65c25746 568 plog(ASL_LEVEL_ERR,
d1e348cf
A
569 "Unknown group auth source\n");
570 break;
571 }
572
573 if( !res ) {
7ebaebe2 574 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
575 "user \"%s\" is a member of group \"%s\"\n",
576 usr,
577 grp_list[grp_index]);
578 break;
579 } else {
7ebaebe2 580 plog(ASL_LEVEL_NOTICE,
d1e348cf
A
581 "user \"%s\" is not a member of group \"%s\"\n",
582 usr,
583 grp_list[grp_index]);
584 }
585 }
586
587 return res;
588}
589
52b7d2ce
A
590vchar_t *
591isakmp_xauth_req(iph1, attr)
65c25746 592 phase1_handle_t *iph1;
52b7d2ce
A
593 struct isakmp_data *attr;
594{
595 int type;
596 size_t dlen = 0;
597 int ashort = 0;
598 int value = 0;
599 vchar_t *buffer = NULL;
d1e348cf
A
600 char* mraw = NULL;
601 vchar_t *mdata = NULL;
52b7d2ce
A
602 char *data;
603 vchar_t *usr = NULL;
604 vchar_t *pwd = NULL;
605 size_t skip = 0;
606 int freepwd = 0;
607
608 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
65c25746 609 plog(ASL_LEVEL_ERR,
52b7d2ce
A
610 "Xauth mode config request but peer "
611 "did not declare itself as Xauth capable\n");
612 return NULL;
613 }
614
615 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
616
617 /* Sanity checks */
618 switch(type) {
619 case XAUTH_TYPE:
620 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
65c25746 621 plog(ASL_LEVEL_ERR,
52b7d2ce
A
622 "Unexpected long XAUTH_TYPE attribute\n");
623 return NULL;
624 }
625 if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
65c25746 626 plog(ASL_LEVEL_ERR,
52b7d2ce
A
627 "Unsupported Xauth authentication %d\n",
628 ntohs(attr->lorv));
629 return NULL;
630 }
631 ashort = 1;
632 dlen = 0;
633 value = XAUTH_TYPE_GENERIC;
634 break;
635
636 case XAUTH_USER_NAME:
d1e348cf 637 if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
65c25746 638 plog(ASL_LEVEL_ERR, "Xauth performed "
52b7d2ce
A
639 "with no login supplied\n");
640 return NULL;
641 }
642
d1e348cf
A
643 dlen = iph1->rmconf->xauth->login->l - 1;
644 iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
52b7d2ce
A
645 break;
646
647 case XAUTH_USER_PASSWORD:
d1e348cf
A
648 case XAUTH_PASSCODE:
649 if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
52b7d2ce
A
650 return NULL;
651
652 skip = sizeof(struct ipsecdoi_id_b);
d1e348cf
A
653 usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
654 if (usr == NULL) {
65c25746 655 plog(ASL_LEVEL_ERR,
52b7d2ce
A
656 "Cannot allocate memory\n");
657 return NULL;
658 }
52b7d2ce
A
659 memset(usr->v, 0, skip);
660 memcpy(usr->v + skip,
d1e348cf
A
661 iph1->rmconf->xauth->login->v,
662 iph1->rmconf->xauth->login->l - 1);
52b7d2ce 663
d1e348cf 664 if (iph1->rmconf->xauth->pass) {
52b7d2ce 665 /* A key given through racoonctl */
d1e348cf 666 pwd = iph1->rmconf->xauth->pass;
52b7d2ce
A
667 } else {
668 if ((pwd = getpskbyname(usr)) == NULL) {
65c25746 669 plog(ASL_LEVEL_ERR,
52b7d2ce 670 "No password was found for login %s\n",
d1e348cf 671 iph1->rmconf->xauth->login->v);
52b7d2ce
A
672 vfree(usr);
673 return NULL;
674 }
675 /* We have to free it before returning */
676 freepwd = 1;
677 }
678 vfree(usr);
679
d1e348cf
A
680 iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
681 dlen = pwd->l - 1;
52b7d2ce
A
682
683 break;
d1e348cf
A
684
685 case XAUTH_MESSAGE:
686 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
687 dlen = ntohs(attr->lorv);
688 if (dlen > 0) {
689 mraw = (char*)(attr + 1);
690 if ((mdata = vmalloc(dlen)) == NULL) {
65c25746 691 plog(ASL_LEVEL_ERR,
d1e348cf
A
692 "Cannot allocate memory\n");
693 return NULL;
694 }
695 memcpy(mdata->v, mraw, mdata->l);
65c25746 696 plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
d1e348cf
A
697 binsanitize(mdata->v, mdata->l));
698 vfree(mdata);
699 }
700 }
701 return NULL;
52b7d2ce 702 default:
65c25746 703 plog(ASL_LEVEL_WARNING,
d1e348cf 704 "Ignored attribute %s\n", s_isakmp_cfg_type(type));
52b7d2ce
A
705 return NULL;
706 break;
707 }
708
709 if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
65c25746 710 plog(ASL_LEVEL_ERR,
52b7d2ce
A
711 "Cannot allocate memory\n");
712 goto out;
713 }
714
715 attr = (struct isakmp_data *)buffer->v;
716 if (ashort) {
717 attr->type = htons(type | ISAKMP_GEN_TV);
718 attr->lorv = htons(value);
719 goto out;
720 }
721
722 attr->type = htons(type | ISAKMP_GEN_TLV);
723 attr->lorv = htons(dlen);
724 data = (char *)(attr + 1);
725
726 switch(type) {
727 case XAUTH_USER_NAME:
d1e348cf
A
728 /*
729 * iph1->rmconf->xauth->login->v is valid,
730 * we just checked it in the previous switch case
731 */
732 memcpy(data, iph1->rmconf->xauth->login->v, dlen);
52b7d2ce
A
733 break;
734 case XAUTH_USER_PASSWORD:
d1e348cf 735 case XAUTH_PASSCODE:
52b7d2ce
A
736 memcpy(data, pwd->v, dlen);
737 break;
738 default:
739 break;
740 }
741
742out:
743 if (freepwd)
744 vfree(pwd);
745
746 return buffer;
747}
748
749vchar_t *
750isakmp_xauth_set(iph1, attr)
65c25746 751 phase1_handle_t *iph1;
52b7d2ce
A
752 struct isakmp_data *attr;
753{
754 int type;
755 vchar_t *buffer = NULL;
d1e348cf
A
756 struct xauth_state *xst;
757 size_t dlen = 0;
758 char* mraw = NULL;
759 vchar_t *mdata = NULL;
52b7d2ce
A
760
761 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
d1e348cf
A
762 IPSECSESSIONTRACEREVENT(iph1->parent_session,
763 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
764 CONSTSTR("XAUTH is not supported by peer"),
765 CONSTSTR("XAUTH dropped (not supported by peer)"));
65c25746 766 plog(ASL_LEVEL_ERR,
52b7d2ce
A
767 "Xauth mode config set but peer "
768 "did not declare itself as Xauth capable\n");
769 return NULL;
770 }
771
772 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
773
774 switch(type) {
775 case XAUTH_STATUS:
d1e348cf
A
776 /*
777 * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
778 * when running as a client (initiator).
779 */
780 xst = &iph1->mode_cfg->xauth;
781 switch(AUTHMETHOD(iph1)) {
782 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
783 if (!iph1->is_rekey) {
784 IPSECSESSIONTRACEREVENT(iph1->parent_session,
785 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
786 CONSTSTR("Unexpected XAUTH Status"),
65c25746
A
787 CONSTSTR("Xauth dropped (unexpected Xauth status)... not a Phase 1 rekey"));
788 plog(ASL_LEVEL_ERR,
789 "Unexpected XAUTH_STATUS_OK... not a Phase 1 rekey\n");
d1e348cf
A
790 return NULL;
791 }
792 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
793 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
794 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
795 /* Not implemented ... */
d1e348cf
A
796 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
797 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
798 break;
799 default:
800 IPSECSESSIONTRACEREVENT(iph1->parent_session,
801 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
802 CONSTSTR("Unexpected XAUTH Status"),
803 CONSTSTR("Xauth dropped (unexpected Xauth status)"));
65c25746 804 plog(ASL_LEVEL_ERR,
d1e348cf
A
805 "Unexpected XAUTH_STATUS_OK\n");
806 return NULL;
807 break;
808 }
809
52b7d2ce
A
810 /* If we got a failure, delete iph1 */
811 if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
d1e348cf
A
812 IPSECSESSIONTRACEREVENT(iph1->parent_session,
813 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL,
814 CONSTSTR("XAUTH Status is not OK"),
815 CONSTSTR("Xauth Failed (status not ok)"));
65c25746 816 plog(ASL_LEVEL_ERR,
52b7d2ce 817 "Xauth authentication failed\n");
d06a7ccb 818
d1e348cf 819 vpncontrol_notify_ike_failed(VPNCTL_NTYPE_AUTHENTICATION_FAILED, FROM_LOCAL,
d06a7ccb 820 iph1_get_remote_v4_address(iph1), 0, NULL);
52b7d2ce
A
821
822 iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
e8d9021d
A
823
824 IPSECLOGASLMSG("IPSec Extended Authentication Failed.\n");
52b7d2ce 825 } else {
d1e348cf
A
826 IPSECSESSIONTRACEREVENT(iph1->parent_session,
827 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC,
828 CONSTSTR("XAUTH Status is OK"),
829 CONSTSTR(NULL));
d1e348cf
A
830 if (iph1->is_rekey) {
831 xst->status = XAUTHST_OK;
832 }
e8d9021d
A
833
834 IPSECLOGASLMSG("IPSec Extended Authentication Passed.\n");
52b7d2ce
A
835 }
836
837
838 /* We acknowledge it */
839 break;
d1e348cf
A
840 case XAUTH_MESSAGE:
841 if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
842 dlen = ntohs(attr->lorv);
843 if (dlen > 0) {
844 mraw = (char*)(attr + 1);
845 if ((mdata = vmalloc(dlen)) == NULL) {
65c25746 846 plog(ASL_LEVEL_ERR,
d1e348cf
A
847 "Cannot allocate memory\n");
848 return NULL;
849 }
850 memcpy(mdata->v, mraw, mdata->l);
65c25746 851 plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
d1e348cf
A
852 binsanitize(mdata->v, mdata->l));
853 vfree(mdata);
854 }
855 }
856
52b7d2ce 857 default:
d1e348cf
A
858 IPSECSESSIONTRACEREVENT(iph1->parent_session,
859 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
860 CONSTSTR("ignored attribute"),
861 CONSTSTR("Xauth dropped (ignored attribute)"));
65c25746 862 plog(ASL_LEVEL_WARNING,
d1e348cf 863 "Ignored attribute %s\n", s_isakmp_cfg_type(type));
52b7d2ce
A
864 return NULL;
865 break;
866 }
867
868 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
d1e348cf
A
869 IPSECSESSIONTRACEREVENT(iph1->parent_session,
870 IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
871 CONSTSTR("Failed to allocate attribute"),
872 CONSTSTR("Xauth dropped (failed to allocate attribute)"));
65c25746 873 plog(ASL_LEVEL_ERR,
52b7d2ce
A
874 "Cannot allocate memory\n");
875 return NULL;
876 }
877
878 attr = (struct isakmp_data *)buffer->v;
879 attr->type = htons(type | ISAKMP_GEN_TV);
880 attr->lorv = htons(0);
881
882 return buffer;
883}
884
885
886void
887xauth_rmstate(xst)
888 struct xauth_state *xst;
889{
890 switch (xst->authtype) {
891 case XAUTH_TYPE_GENERIC:
892 if (xst->authdata.generic.usr)
893 racoon_free(xst->authdata.generic.usr);
894
895 if (xst->authdata.generic.pwd)
896 racoon_free(xst->authdata.generic.pwd);
897
898 break;
899
900 case XAUTH_TYPE_CHAP:
901 case XAUTH_TYPE_OTP:
902 case XAUTH_TYPE_SKEY:
65c25746 903 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
904 "Unsupported authtype %d\n", xst->authtype);
905 break;
906
907 default:
65c25746 908 plog(ASL_LEVEL_WARNING,
52b7d2ce
A
909 "Unexpected authtype %d\n", xst->authtype);
910 break;
911 }
912
913 return;
914}
915
d1e348cf
A
916int
917xauth_rmconf_used(xauth_rmconf)
918 struct xauth_rmconf **xauth_rmconf;
919{
920 if (*xauth_rmconf == NULL) {
921 *xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
922 if (*xauth_rmconf == NULL) {
65c25746 923 plog(ASL_LEVEL_ERR,
d1e348cf
A
924 "xauth_rmconf_used: malloc failed\n");
925 return -1;
926 }
927
928 (*xauth_rmconf)->login = NULL;
929 (*xauth_rmconf)->pass = NULL;
930 (*xauth_rmconf)->state = 0;
931 } else {
932 if ((*xauth_rmconf)->login) {
933 vfree((*xauth_rmconf)->login);
934 (*xauth_rmconf)->login = NULL;
935 }
936 if ((*xauth_rmconf)->pass != NULL) {
937 vfree((*xauth_rmconf)->pass);
938 (*xauth_rmconf)->pass = NULL;
939 }
940 (*xauth_rmconf)->state = 0;
941 }
942
943 return 0;
944}
945
946void
947xauth_rmconf_delete(xauth_rmconf)
948 struct xauth_rmconf **xauth_rmconf;
949{
950 if (*xauth_rmconf != NULL) {
951 if ((*xauth_rmconf)->login != NULL)
952 vfree((*xauth_rmconf)->login);
953 if ((*xauth_rmconf)->pass != NULL)
954 vfree((*xauth_rmconf)->pass);
955
956 racoon_free(*xauth_rmconf);
957 *xauth_rmconf = NULL;
958 }
959
960 return;
961}