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 */
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>
48#include <grp.h>
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>
64#include <resolv.h>
65
66#ifdef HAVE_SHADOW_H
67#include <shadow.h>
68#endif
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"
77#include "fsm.h"
78
79#include "crypto_openssl.h"
80#include "isakmp_var.h"
81#include "isakmp.h"
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"
93#include "vpn_control.h"
94#include "vpn_control_var.h"
95#include "ipsecSessionTracer.h"
96#include "ipsecMessageTracer.h"
97
98
99void
100xauth_sendreq(iph1)
101	phase1_handle_t *iph1;
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 */
112	if (!FSM_STATE_IS_ESTABLISHED(iph1->status)) {
113		plog(ASL_LEVEL_ERR,
114		    "Xauth request while phase 1 is not completed\n");
115		return;
116	}
117
118	if (xst->status != XAUTHST_NOTYET) {
119		plog(ASL_LEVEL_ERR,
120		    "Xauth request whith Xauth state %d\n", xst->status);
121		return;
122	}
123
124	plog(ASL_LEVEL_INFO, "Sending Xauth request\n");
125
126	tlen = sizeof(*attr) +
127	       + sizeof(*typeattr) +
128	       + sizeof(*usrattr) +
129	       + sizeof(*pwdattr);
130
131	if ((buffer = vmalloc(tlen)) == NULL) {
132		plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
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,
156	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
157
158	vfree(buffer);
159
160	xst->status = XAUTHST_REQSENT;
161
162	return;
163}
164
165int
166xauth_attr_reply(iph1, attr, id)
167	phase1_handle_t *iph1;
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) {
177		plog(ASL_LEVEL_ERR,
178		    "Xauth reply but peer did not declare "
179		    "itself as Xauth capable\n");
180		return -1;
181	}
182
183	if (xst->status != XAUTHST_REQSENT) {
184		plog(ASL_LEVEL_ERR,
185		    "Xauth reply while Xauth state is %d\n", xst->status);
186		return -1;
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:
197			plog(ASL_LEVEL_WARNING,
198			    "Unexpected authentication type %d\n",
199			    ntohs(type));
200			return -1;
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:
213		plog(ASL_LEVEL_WARNING,
214		    "ignored Xauth attribute %d\n", type);
215		break;
216	}
217
218	if (outlet != NULL) {
219		alen = ntohs(attr->lorv);
220
221		if ((*outlet = racoon_realloc(*outlet, alen + 1)) == NULL) {
222			plog(ASL_LEVEL_ERR,
223			    "Cannot allocate memory for Xauth Data\n");
224			return -1;
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 */
242		plog(ASL_LEVEL_DEBUG,
243		    "Got username \"%s\", password \"%s\"\n", usr, pwd);
244#endif
245		strlcpy(iph1->mode_cfg->login, usr, sizeof(iph1->mode_cfg->login));
246
247		res = -1;
248		if ((port = isakmp_cfg_getport(iph1)) == -1) {
249			plog(ASL_LEVEL_ERR,
250			    "Port pool depleted\n");
251			goto skip_auth;
252		}
253
254		switch (isakmp_cfg_config.authsource) {
255		case ISAKMP_CFG_AUTH_SYSTEM:
256			res = xauth_login_system(usr, pwd);
257			break;
258
259		default:
260			plog(ASL_LEVEL_ERR,
261			    "Unexpected authentication source\n");
262			res = -1;
263			break;
264		}
265
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
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
282			str = saddrwop2str((struct sockaddr *)iph1->remote);
283
284			plog(ASL_LEVEL_ERR,
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) {
297				plog(ASL_LEVEL_ERR,
298				    "malloc failed, bypass throttling\n");
299				return xauth_reply(iph1, port, id, res);
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 {
313			return xauth_reply(iph1, port, id, res);
314		}
315	}
316
317	return 0;
318}
319
320void
321xauth_reply_stub(args)
322	void *args;
323{
324	struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
325	phase1_handle_t *iph1;
326
327	if ((iph1 = ike_session_getph1byindex(NULL, &xra->index)) != NULL)
328		(void)xauth_reply(iph1, xra->port, xra->id, xra->res);
329	else
330		plog(ASL_LEVEL_ERR,
331		    "Delayed Xauth reply: phase 1 no longer exists.\n");
332
333	racoon_free(xra);
334	return;
335}
336
337int
338xauth_reply(iph1, port, id, res)
339	phase1_handle_t *iph1;
340	int port;
341	int id;
342{
343	struct xauth_state *xst = &iph1->mode_cfg->xauth;
344	char *usr = xst->authdata.generic.usr;
345
346	if (iph1->is_dying) {
347		plog(ASL_LEVEL_INFO,
348			 "dropped login for user \"%s\"\n", usr);
349		return -1;
350	}
351
352	if (res != 0) {
353		if (port != -1)
354			isakmp_cfg_putport(iph1, port);
355
356		plog(ASL_LEVEL_INFO,
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 */
363		if (FSM_STATE_IS_ESTABLISHED(iph1->status))
364			isakmp_info_send_d1(iph1);
365		isakmp_ph1expire(iph1);
366
367		return -1;
368	}
369
370	xst->status = XAUTHST_OK;
371	plog(ASL_LEVEL_INFO,
372	    "login succeeded for user \"%s\"\n", usr);
373
374	xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
375
376	return 0;
377}
378
379void
380xauth_sendstatus(iph1, status, id)
381	phase1_handle_t *iph1;
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) {
394		plog(ASL_LEVEL_ERR, "Cannot allocate buffer\n");
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,
410	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, 0, NULL);
411
412	vfree(buffer);
413
414	return;
415}
416
417
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
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) {
466		plog(ASL_LEVEL_ERR,
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)) {
474			plog(ASL_LEVEL_INFO,
475		                "membership validated\n");
476			return 0;
477		}
478	}
479
480	return -1;
481}
482
483int
484xauth_check(iph1)
485	phase1_handle_t *iph1;
486{
487	struct xauth_state *xst = &iph1->mode_cfg->xauth;
488
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:
498	/* The following are not yet implemented */
499	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
500	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
501		if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
502			plog(ASL_LEVEL_ERR,
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) {
509			plog(ASL_LEVEL_ERR,
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
525int
526group_check(iph1, grp_list, grp_count)
527	phase1_handle_t *iph1;
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) {
538		plog(ASL_LEVEL_ERR,
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) {
552			plog(ASL_LEVEL_ERR,
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
567			default:
568				/* we should never get here */
569				plog(ASL_LEVEL_ERR,
570				    "Unknown group auth source\n");
571				break;
572		}
573
574		if( !res ) {
575			plog(ASL_LEVEL_INFO,
576				"user \"%s\" is a member of group \"%s\"\n",
577				usr,
578				grp_list[grp_index]);
579			break;
580		} else {
581			plog(ASL_LEVEL_INFO,
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
591vchar_t *
592isakmp_xauth_req(iph1, attr)
593	phase1_handle_t *iph1;
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;
601	char* mraw = NULL;
602	vchar_t *mdata = NULL;
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) {
610		plog(ASL_LEVEL_ERR,
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) {
622			plog(ASL_LEVEL_ERR,
623			    "Unexpected long XAUTH_TYPE attribute\n");
624			return NULL;
625		}
626		if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
627			plog(ASL_LEVEL_ERR,
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:
638		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
639			plog(ASL_LEVEL_ERR, "Xauth performed "
640			    "with no login supplied\n");
641			return NULL;
642		}
643
644		dlen = iph1->rmconf->xauth->login->l - 1;
645		iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
646		break;
647
648	case XAUTH_USER_PASSWORD:
649	case XAUTH_PASSCODE:
650		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
651			return NULL;
652
653		skip = sizeof(struct ipsecdoi_id_b);
654		usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
655		if (usr == NULL) {
656			plog(ASL_LEVEL_ERR,
657			    "Cannot allocate memory\n");
658			return NULL;
659		}
660		memset(usr->v, 0, skip);
661		memcpy(usr->v + skip,
662		    iph1->rmconf->xauth->login->v,
663		    iph1->rmconf->xauth->login->l - 1);
664
665		if (iph1->rmconf->xauth->pass) {
666			/* A key given through racoonctl */
667			pwd = iph1->rmconf->xauth->pass;
668		} else {
669			if ((pwd = getpskbyname(usr)) == NULL) {
670				plog(ASL_LEVEL_ERR,
671				    "No password was found for login %s\n",
672				    iph1->rmconf->xauth->login->v);
673				vfree(usr);
674				return NULL;
675			}
676			/* We have to free it before returning */
677			freepwd = 1;
678		}
679		vfree(usr);
680
681		iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
682		dlen = pwd->l - 1;
683
684		break;
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) {
692					plog(ASL_LEVEL_ERR,
693					    "Cannot allocate memory\n");
694					return NULL;
695				}
696				memcpy(mdata->v, mraw, mdata->l);
697				plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
698					binsanitize(mdata->v, mdata->l));
699				vfree(mdata);
700			}
701		}
702		return NULL;
703	default:
704		plog(ASL_LEVEL_WARNING,
705		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
706		return NULL;
707		break;
708	}
709
710	if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
711		plog(ASL_LEVEL_ERR,
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:
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);
734		break;
735	case XAUTH_USER_PASSWORD:
736	case XAUTH_PASSCODE:
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)
752	phase1_handle_t *iph1;
753	struct isakmp_data *attr;
754{
755	int type;
756	vchar_t *buffer = NULL;
757	struct xauth_state *xst;
758	size_t dlen = 0;
759	char* mraw = NULL;
760	vchar_t *mdata = NULL;
761
762	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
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)"));
767		plog(ASL_LEVEL_ERR,
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:
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"),
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");
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 ... */
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)"));
805			plog(ASL_LEVEL_ERR,
806			    "Unexpected XAUTH_STATUS_OK\n");
807			return NULL;
808			break;
809		}
810
811		/* If we got a failure, delete iph1 */
812		if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
813			IPSECSESSIONTRACEREVENT(iph1->parent_session,
814									IPSECSESSIONEVENTCODE_IKEV1_XAUTH_FAIL,
815									CONSTSTR("XAUTH Status is not OK"),
816									CONSTSTR("Xauth Failed (status not ok)"));
817			plog(ASL_LEVEL_ERR,
818			    "Xauth authentication failed\n");
819
820			vpncontrol_notify_ike_failed(VPNCTL_NTYPE_AUTHENTICATION_FAILED, FROM_LOCAL,
821				((struct sockaddr_in*)iph1->remote)->sin_addr.s_addr, 0, NULL);
822
823			iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
824
825			IPSECLOGASLMSG("IPSec Extended Authentication Failed.\n");
826		} else {
827			IPSECSESSIONTRACEREVENT(iph1->parent_session,
828									IPSECSESSIONEVENTCODE_IKEV1_XAUTH_SUCC,
829									CONSTSTR("XAUTH Status is OK"),
830									CONSTSTR(NULL));
831            if (iph1->is_rekey) {
832                xst->status = XAUTHST_OK;
833            }
834
835			IPSECLOGASLMSG("IPSec Extended Authentication Passed.\n");
836		}
837
838
839		/* We acknowledge it */
840		break;
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) {
847					plog(ASL_LEVEL_ERR,
848					    "Cannot allocate memory\n");
849					return NULL;
850				}
851				memcpy(mdata->v, mraw, mdata->l);
852				plog(ASL_LEVEL_NOTICE, "XAUTH Message: '%s'.\n",
853					binsanitize(mdata->v, mdata->l));
854				vfree(mdata);
855			}
856		}
857
858	default:
859		IPSECSESSIONTRACEREVENT(iph1->parent_session,
860								IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
861								CONSTSTR("ignored attribute"),
862								CONSTSTR("Xauth dropped (ignored attribute)"));
863		plog(ASL_LEVEL_WARNING,
864		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
865		return NULL;
866		break;
867	}
868
869	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
870		IPSECSESSIONTRACEREVENT(iph1->parent_session,
871								IPSECSESSIONEVENTCODE_IKEV1_XAUTH_DROP,
872								CONSTSTR("Failed to allocate attribute"),
873								CONSTSTR("Xauth dropped (failed to allocate attribute)"));
874		plog(ASL_LEVEL_ERR,
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:
904		plog(ASL_LEVEL_WARNING,
905		    "Unsupported authtype %d\n", xst->authtype);
906		break;
907
908	default:
909		plog(ASL_LEVEL_WARNING,
910		    "Unexpected authtype %d\n", xst->authtype);
911		break;
912	}
913
914	return;
915}
916
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) {
924			plog(ASL_LEVEL_ERR,
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}
963