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