1/*	$NetBSD: isakmp_xauth.c,v 1.11.6.2 2009/04/20 13:35:36 tteras 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
78#include "crypto_openssl.h"
79#include "isakmp_var.h"
80#include "isakmp.h"
81#include "admin.h"
82#include "privsep.h"
83#include "evt.h"
84#include "handler.h"
85#include "throttle.h"
86#include "remoteconf.h"
87#include "isakmp_inf.h"
88#include "isakmp_xauth.h"
89#include "isakmp_unity.h"
90#include "isakmp_cfg.h"
91#include "strnames.h"
92#include "ipsec_doi.h"
93#include "remoteconf.h"
94#include "localconf.h"
95
96#ifdef HAVE_LIBRADIUS
97#include <radlib.h>
98
99struct rad_handle *radius_auth_state = NULL;
100struct rad_handle *radius_acct_state = NULL;
101#endif
102
103#ifdef HAVE_LIBPAM
104#include <security/pam_appl.h>
105
106static char *PAM_usr = NULL;
107static char *PAM_pwd = NULL;
108static int PAM_conv(int, const struct pam_message **,
109    struct pam_response **, void *);
110static struct pam_conv PAM_chat = { &PAM_conv, NULL };
111#endif
112
113#ifdef HAVE_LIBLDAP
114#include "ldap.h"
115#include <arpa/inet.h>
116struct xauth_ldap_config xauth_ldap_config;
117#endif
118
119void
120xauth_sendreq(iph1)
121	struct ph1handle *iph1;
122{
123	vchar_t *buffer;
124	struct isakmp_pl_attr *attr;
125	struct isakmp_data *typeattr;
126	struct isakmp_data *usrattr;
127	struct isakmp_data *pwdattr;
128	struct xauth_state *xst = &iph1->mode_cfg->xauth;
129	size_t tlen;
130
131	/* Status checks */
132	if (iph1->status != PHASE1ST_ESTABLISHED) {
133		plog(LLV_ERROR, LOCATION, NULL,
134		    "Xauth request while phase 1 is not completed\n");
135		return;
136	}
137
138	if (xst->status != XAUTHST_NOTYET) {
139		plog(LLV_ERROR, LOCATION, NULL,
140		    "Xauth request whith Xauth state %d\n", xst->status);
141		return;
142	}
143
144	plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
145
146	tlen = sizeof(*attr) +
147	       + sizeof(*typeattr) +
148	       + sizeof(*usrattr) +
149	       + sizeof(*pwdattr);
150
151	if ((buffer = vmalloc(tlen)) == NULL) {
152		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
153		return;
154	}
155
156	attr = (struct isakmp_pl_attr *)buffer->v;
157	memset(attr, 0, tlen);
158
159	attr->h.len = htons(tlen);
160	attr->type = ISAKMP_CFG_REQUEST;
161	attr->id = htons(eay_random());
162
163	typeattr = (struct isakmp_data *)(attr + 1);
164	typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
165	typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
166
167	usrattr = (struct isakmp_data *)(typeattr + 1);
168	usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
169	usrattr->lorv = htons(0);
170
171	pwdattr = (struct isakmp_data *)(usrattr + 1);
172	pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
173	pwdattr->lorv = htons(0);
174
175	isakmp_cfg_send(iph1, buffer,
176	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
177
178	vfree(buffer);
179
180	xst->status = XAUTHST_REQSENT;
181
182	return;
183}
184
185int
186xauth_attr_reply(iph1, attr, id)
187	struct ph1handle *iph1;
188	struct isakmp_data *attr;
189	int id;
190{
191	char **outlet = NULL;
192	size_t alen = 0;
193	int type;
194	struct xauth_state *xst = &iph1->mode_cfg->xauth;
195
196	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
197		plog(LLV_ERROR, LOCATION, NULL,
198		    "Xauth reply but peer did not declare "
199		    "itself as Xauth capable\n");
200		return -1;
201	}
202
203	if (xst->status != XAUTHST_REQSENT) {
204		plog(LLV_ERROR, LOCATION, NULL,
205		    "Xauth reply while Xauth state is %d\n", xst->status);
206		return -1;
207	}
208
209	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
210	switch (type) {
211	case XAUTH_TYPE:
212		switch (ntohs(attr->lorv)) {
213		case XAUTH_TYPE_GENERIC:
214			xst->authtype = XAUTH_TYPE_GENERIC;
215			break;
216		default:
217			plog(LLV_WARNING, LOCATION, NULL,
218			    "Unexpected authentication type %d\n",
219			    ntohs(type));
220			return -1;
221		}
222		break;
223
224	case XAUTH_USER_NAME:
225		outlet = &xst->authdata.generic.usr;
226		break;
227
228	case XAUTH_USER_PASSWORD:
229		outlet = &xst->authdata.generic.pwd;
230		break;
231
232	default:
233		plog(LLV_WARNING, LOCATION, NULL,
234		    "ignored Xauth attribute %d\n", type);
235		break;
236	}
237
238	if (outlet != NULL) {
239		alen = ntohs(attr->lorv);
240
241		if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
242			plog(LLV_ERROR, LOCATION, NULL,
243			    "Cannot allocate memory for Xauth Data\n");
244			return -1;
245		}
246
247		memcpy(*outlet, attr + 1, alen);
248		(*outlet)[alen] = '\0';
249		outlet = NULL;
250	}
251
252
253	if ((xst->authdata.generic.usr != NULL) &&
254	   (xst->authdata.generic.pwd != NULL)) {
255		int port;
256		int res;
257		char *usr = xst->authdata.generic.usr;
258		char *pwd = xst->authdata.generic.pwd;
259		time_t throttle_delay = 0;
260
261#if 0	/* Real debug, don't do that at home */
262		plog(LLV_DEBUG, LOCATION, NULL,
263		    "Got username \"%s\", password \"%s\"\n", usr, pwd);
264#endif
265		strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
266		iph1->mode_cfg->login[LOGINLEN] = '\0';
267
268		res = -1;
269		if ((port = isakmp_cfg_getport(iph1)) == -1) {
270			plog(LLV_ERROR, LOCATION, NULL,
271			    "Port pool depleted\n");
272			goto skip_auth;
273		}
274
275		switch (isakmp_cfg_config.authsource) {
276		case ISAKMP_CFG_AUTH_SYSTEM:
277			res = privsep_xauth_login_system(usr, pwd);
278			break;
279#ifdef HAVE_LIBRADIUS
280		case ISAKMP_CFG_AUTH_RADIUS:
281			res = xauth_login_radius(iph1, usr, pwd);
282			break;
283#endif
284#ifdef HAVE_LIBPAM
285		case ISAKMP_CFG_AUTH_PAM:
286			res = privsep_xauth_login_pam(iph1->mode_cfg->port,
287			    iph1->remote, usr, pwd);
288			break;
289#endif
290#ifdef HAVE_LIBLDAP
291		case ISAKMP_CFG_AUTH_LDAP:
292			res = xauth_login_ldap(iph1, usr, pwd);
293			break;
294#endif
295		default:
296			plog(LLV_ERROR, LOCATION, NULL,
297			    "Unexpected authentication source\n");
298			res = -1;
299			break;
300		}
301
302		/*
303		 * Optional group authentication
304		 */
305		if (!res && (isakmp_cfg_config.groupcount))
306			res = group_check(iph1,
307				isakmp_cfg_config.grouplist,
308				isakmp_cfg_config.groupcount);
309
310		/*
311		 * On failure, throttle the connexion for the remote host
312		 * in order to make password attacks more difficult.
313		 */
314		throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
315		if (throttle_delay > 0) {
316			char *str;
317
318			str = saddrwop2str(iph1->remote);
319
320			plog(LLV_ERROR, LOCATION, NULL,
321			    "Throttling in action for %s: delay %lds\n",
322			    str, (unsigned long)throttle_delay);
323			res = -1;
324		} else {
325			throttle_delay = 0;
326		}
327
328skip_auth:
329		if (throttle_delay != 0) {
330			struct xauth_reply_arg *xra;
331
332			if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
333				plog(LLV_ERROR, LOCATION, NULL,
334				    "malloc failed, bypass throttling\n");
335				return xauth_reply(iph1, port, id, res);
336			}
337
338			/*
339			 * We need to store the ph1, but it might have
340			 * disapeared when xauth_reply is called, so
341			 * store the index instead.
342			 */
343			xra->index = iph1->index;
344			xra->port = port;
345			xra->id = id;
346			xra->res = res;
347			sched_new(throttle_delay, xauth_reply_stub, xra);
348		} else {
349			return xauth_reply(iph1, port, id, res);
350		}
351	}
352
353	return 0;
354}
355
356void
357xauth_reply_stub(args)
358	void *args;
359{
360	struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
361	struct ph1handle *iph1;
362
363	if ((iph1 = getph1byindex(&xra->index)) != NULL)
364		(void)xauth_reply(iph1, xra->port, xra->id, xra->res);
365	else
366		plog(LLV_ERROR, LOCATION, NULL,
367		    "Delayed Xauth reply: phase 1 no longer exists.\n");
368
369	racoon_free(xra);
370	return;
371}
372
373int
374xauth_reply(iph1, port, id, res)
375	struct ph1handle *iph1;
376	int port;
377	int id;
378{
379	struct xauth_state *xst = &iph1->mode_cfg->xauth;
380	char *usr = xst->authdata.generic.usr;
381
382	if (res != 0) {
383		if (port != -1)
384			isakmp_cfg_putport(iph1, port);
385
386		plog(LLV_INFO, LOCATION, NULL,
387		    "login failed for user \"%s\"\n", usr);
388
389		xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
390		xst->status = XAUTHST_NOTYET;
391
392		/* Delete Phase 1 SA */
393		if (iph1->status == PHASE1ST_ESTABLISHED)
394			isakmp_info_send_d1(iph1);
395		remph1(iph1);
396		delph1(iph1);
397
398		return -1;
399	}
400
401	xst->status = XAUTHST_OK;
402	plog(LLV_INFO, LOCATION, NULL,
403	    "login succeeded for user \"%s\"\n", usr);
404
405	xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
406
407	return 0;
408}
409
410void
411xauth_sendstatus(iph1, status, id)
412	struct ph1handle *iph1;
413	int status;
414	int id;
415{
416	vchar_t *buffer;
417	struct isakmp_pl_attr *attr;
418	struct isakmp_data *stattr;
419	size_t tlen;
420
421	tlen = sizeof(*attr) +
422	       + sizeof(*stattr);
423
424	if ((buffer = vmalloc(tlen)) == NULL) {
425		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
426		return;
427	}
428
429	attr = (struct isakmp_pl_attr *)buffer->v;
430	memset(attr, 0, tlen);
431
432	attr->h.len = htons(tlen);
433	attr->type = ISAKMP_CFG_SET;
434	attr->id = htons(id);
435
436	stattr = (struct isakmp_data *)(attr + 1);
437	stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
438	stattr->lorv = htons(status);
439
440	isakmp_cfg_send(iph1, buffer,
441	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
442
443	vfree(buffer);
444
445	return;
446}
447
448#ifdef HAVE_LIBRADIUS
449int
450xauth_radius_init(void)
451{
452	/* For first time use, initialize Radius */
453	if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
454	    (radius_auth_state == NULL)) {
455		if ((radius_auth_state = rad_auth_open()) == NULL) {
456			plog(LLV_ERROR, LOCATION, NULL,
457			    "Cannot init libradius\n");
458			return -1;
459		}
460
461		if (rad_config(radius_auth_state, NULL) != 0) {
462			plog(LLV_ERROR, LOCATION, NULL,
463			    "Cannot open librarius config file: %s\n",
464			    rad_strerror(radius_auth_state));
465			rad_close(radius_auth_state);
466			radius_auth_state = NULL;
467			return -1;
468		}
469	}
470
471	if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
472	    (radius_acct_state == NULL)) {
473		if ((radius_acct_state = rad_acct_open()) == NULL) {
474			plog(LLV_ERROR, LOCATION, NULL,
475			    "Cannot init libradius\n");
476			return -1;
477		}
478
479		if (rad_config(radius_acct_state, NULL) != 0) {
480			plog(LLV_ERROR, LOCATION, NULL,
481			    "Cannot open librarius config file: %s\n",
482			    rad_strerror(radius_acct_state));
483			rad_close(radius_acct_state);
484			radius_acct_state = NULL;
485			return -1;
486		}
487	}
488
489	return 0;
490}
491
492int
493xauth_login_radius(iph1, usr, pwd)
494	struct ph1handle *iph1;
495	char *usr;
496	char *pwd;
497{
498	int res;
499	const void *data;
500	size_t len;
501	int type;
502
503	if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
504		plog(LLV_ERROR, LOCATION, NULL,
505		    "rad_create_request failed: %s\n",
506		    rad_strerror(radius_auth_state));
507		return -1;
508	}
509
510	if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
511		plog(LLV_ERROR, LOCATION, NULL,
512		    "rad_put_string failed: %s\n",
513		    rad_strerror(radius_auth_state));
514		return -1;
515	}
516
517	if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
518		plog(LLV_ERROR, LOCATION, NULL,
519		    "rad_put_string failed: %s\n",
520		    rad_strerror(radius_auth_state));
521		return -1;
522	}
523
524	if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
525		return -1;
526
527	switch (res = rad_send_request(radius_auth_state)) {
528	case RAD_ACCESS_ACCEPT:
529		while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
530			switch (type) {
531			case RAD_FRAMED_IP_ADDRESS:
532				iph1->mode_cfg->addr4 = rad_cvt_addr(data);
533				iph1->mode_cfg->flags
534				    |= ISAKMP_CFG_ADDR4_EXTERN;
535				break;
536
537			case RAD_FRAMED_IP_NETMASK:
538				iph1->mode_cfg->mask4 = rad_cvt_addr(data);
539				iph1->mode_cfg->flags
540				    |= ISAKMP_CFG_MASK4_EXTERN;
541				break;
542
543			default:
544				plog(LLV_INFO, LOCATION, NULL,
545				    "Unexpected attribute: %d\n", type);
546				break;
547			}
548		}
549
550		return 0;
551		break;
552
553	case RAD_ACCESS_REJECT:
554		return -1;
555		break;
556
557	case -1:
558		plog(LLV_ERROR, LOCATION, NULL,
559		    "rad_send_request failed: %s\n",
560		    rad_strerror(radius_auth_state));
561		return -1;
562		break;
563	default:
564		plog(LLV_ERROR, LOCATION, NULL,
565		    "rad_send_request returned %d\n", res);
566		return -1;
567		break;
568	}
569
570	return -1;
571}
572#endif
573
574#ifdef HAVE_LIBPAM
575static int
576PAM_conv(msg_count, msg, rsp, dontcare)
577	int msg_count;
578	const struct pam_message **msg;
579	struct pam_response **rsp;
580	void *dontcare;
581{
582	int i;
583	int replies = 0;
584	struct pam_response *reply = NULL;
585
586	if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
587		return PAM_CONV_ERR;
588	bzero(reply, sizeof(*reply) * msg_count);
589
590	for (i = 0; i < msg_count; i++) {
591		switch (msg[i]->msg_style) {
592		case PAM_PROMPT_ECHO_ON:
593			/* Send the username, libpam frees resp */
594			reply[i].resp_retcode = PAM_SUCCESS;
595			if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
596				plog(LLV_ERROR, LOCATION,
597				    NULL, "strdup failed\n");
598				exit(1);
599			}
600			break;
601
602		case PAM_PROMPT_ECHO_OFF:
603			/* Send the password, libpam frees resp */
604			reply[i].resp_retcode = PAM_SUCCESS;
605			if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
606				plog(LLV_ERROR, LOCATION,
607				    NULL, "strdup failed\n");
608				exit(1);
609			}
610			break;
611
612		case PAM_TEXT_INFO:
613		case PAM_ERROR_MSG:
614			reply[i].resp_retcode = PAM_SUCCESS;
615			reply[i].resp = NULL;
616			break;
617
618		default:
619			if (reply != NULL)
620				racoon_free(reply);
621			return PAM_CONV_ERR;
622			break;
623		}
624	}
625
626	if (reply != NULL)
627		*rsp = reply;
628
629	return PAM_SUCCESS;
630}
631
632int
633xauth_login_pam(port, raddr, usr, pwd)
634	int port;
635	struct sockaddr *raddr;
636	char *usr;
637	char *pwd;
638{
639	int error;
640	int res;
641	const void *data;
642	size_t len;
643	int type;
644	char *remote = NULL;
645	pam_handle_t *pam = NULL;
646
647	if (isakmp_cfg_config.port_pool == NULL) {
648		plog(LLV_ERROR, LOCATION, NULL,
649		    "isakmp_cfg_config.port_pool == NULL\n");
650		return -1;
651	}
652
653	if ((error = pam_start("racoon", usr,
654	    &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
655		if (isakmp_cfg_config.port_pool[port].pam == NULL) {
656			plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
657			return -1;
658		} else {
659			plog(LLV_ERROR, LOCATION, NULL,
660			    "pam_start failed: %s\n",
661			    pam_strerror(isakmp_cfg_config.port_pool[port].pam,
662			    error));
663			goto out;
664		}
665	}
666	pam = isakmp_cfg_config.port_pool[port].pam;
667
668	if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
669		plog(LLV_ERROR, LOCATION, NULL,
670		    "cannot allocate memory: %s\n", strerror(errno));
671		goto out;
672	}
673
674	if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
675		plog(LLV_ERROR, LOCATION, NULL,
676		    "pam_set_item failed: %s\n",
677		    pam_strerror(pam, error));
678		goto out;
679	}
680
681	PAM_usr = usr;
682	PAM_pwd = pwd;
683	error = pam_authenticate(pam, 0);
684	PAM_usr = NULL;
685	PAM_pwd = NULL;
686	if (error != 0) {
687		plog(LLV_ERROR, LOCATION, NULL,
688		    "pam_authenticate failed: %s\n",
689		    pam_strerror(pam, error));
690		goto out;
691	}
692
693	if ((error = pam_acct_mgmt(pam, 0)) != 0) {
694		plog(LLV_ERROR, LOCATION, NULL,
695		    "pam_acct_mgmt failed: %s\n",
696		    pam_strerror(pam, error));
697		goto out;
698	}
699
700	if ((error = pam_setcred(pam, 0)) != 0) {
701		plog(LLV_ERROR, LOCATION, NULL,
702		    "pam_setcred failed: %s\n",
703		    pam_strerror(pam, error));
704		goto out;
705	}
706
707	if (remote != NULL)
708		free(remote);
709
710	return 0;
711
712out:
713	pam_end(pam, error);
714	isakmp_cfg_config.port_pool[port].pam = NULL;
715	if (remote != NULL)
716		free(remote);
717	return -1;
718}
719#endif
720
721#ifdef HAVE_LIBLDAP
722int
723xauth_ldap_init(void)
724{
725	int tmplen;
726	int error = -1;
727
728	xauth_ldap_config.pver = 3;
729	xauth_ldap_config.host = NULL;
730	xauth_ldap_config.port = LDAP_PORT;
731	xauth_ldap_config.base = NULL;
732	xauth_ldap_config.subtree = 0;
733	xauth_ldap_config.bind_dn = NULL;
734	xauth_ldap_config.bind_pw = NULL;
735	xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
736	xauth_ldap_config.attr_user = NULL;
737	xauth_ldap_config.attr_addr = NULL;
738	xauth_ldap_config.attr_mask = NULL;
739	xauth_ldap_config.attr_group = NULL;
740	xauth_ldap_config.attr_member = NULL;
741
742	/* set default host */
743	tmplen = strlen(LDAP_DFLT_HOST);
744	xauth_ldap_config.host = vmalloc(tmplen);
745	if (xauth_ldap_config.host == NULL)
746		goto out;
747	memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
748
749	/* set default user naming attribute */
750	tmplen = strlen(LDAP_DFLT_USER);
751	xauth_ldap_config.attr_user = vmalloc(tmplen);
752	if (xauth_ldap_config.attr_user == NULL)
753		goto out;
754	memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
755
756	/* set default address attribute */
757	tmplen = strlen(LDAP_DFLT_ADDR);
758	xauth_ldap_config.attr_addr = vmalloc(tmplen);
759	if (xauth_ldap_config.attr_addr == NULL)
760		goto out;
761	memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
762
763	/* set default netmask attribute */
764	tmplen = strlen(LDAP_DFLT_MASK);
765	xauth_ldap_config.attr_mask = vmalloc(tmplen);
766	if (xauth_ldap_config.attr_mask == NULL)
767		goto out;
768	memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
769
770	/* set default group naming attribute */
771	tmplen = strlen(LDAP_DFLT_GROUP);
772	xauth_ldap_config.attr_group = vmalloc(tmplen);
773	if (xauth_ldap_config.attr_group == NULL)
774		goto out;
775	memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
776
777	/* set default member attribute */
778	tmplen = strlen(LDAP_DFLT_MEMBER);
779	xauth_ldap_config.attr_member = vmalloc(tmplen);
780	if (xauth_ldap_config.attr_member == NULL)
781		goto out;
782	memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
783
784	error = 0;
785out:
786	if (error != 0)
787		plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
788
789	return error;
790}
791
792int
793xauth_login_ldap(iph1, usr, pwd)
794	struct ph1handle *iph1;
795	char *usr;
796	char *pwd;
797{
798	int rtn = -1;
799	int res = -1;
800	LDAP *ld = NULL;
801	LDAPMessage *lr = NULL;
802	LDAPMessage *le = NULL;
803	struct berval cred;
804	struct berval **bv = NULL;
805	struct timeval timeout;
806	char *init = NULL;
807	char *filter = NULL;
808	char *atlist[3];
809	char *basedn = NULL;
810	char *userdn = NULL;
811	int tmplen = 0;
812	int ecount = 0;
813	int scope = LDAP_SCOPE_ONE;
814
815	atlist[0] = NULL;
816	atlist[1] = NULL;
817	atlist[2] = NULL;
818
819	/* build our initialization url */
820	tmplen = strlen("ldap://:") + 17;
821	tmplen += strlen(xauth_ldap_config.host->v);
822	init = racoon_malloc(tmplen);
823	if (init == NULL) {
824		plog(LLV_ERROR, LOCATION, NULL,
825			"unable to alloc ldap init url\n");
826		goto ldap_end;
827	}
828	sprintf(init,"ldap://%s:%d",
829		xauth_ldap_config.host->v,
830		xauth_ldap_config.port );
831
832	/* initialize the ldap handle */
833	res = ldap_initialize(&ld, init);
834	if (res != LDAP_SUCCESS) {
835		plog(LLV_ERROR, LOCATION, NULL,
836			"ldap_initialize failed: %s\n",
837			ldap_err2string(res));
838		goto ldap_end;
839	}
840
841	/* initialize the protocol version */
842	ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
843		&xauth_ldap_config.pver);
844
845	/*
846	 * attempt to bind to the ldap server.
847         * default to anonymous bind unless a
848	 * user dn and password has been
849	 * specified in our configuration
850         */
851	if ((xauth_ldap_config.bind_dn != NULL)&&
852	    (xauth_ldap_config.bind_pw != NULL))
853	{
854		cred.bv_val = xauth_ldap_config.bind_pw->v;
855		cred.bv_len = strlen( cred.bv_val );
856		res = ldap_sasl_bind_s(ld,
857			xauth_ldap_config.bind_dn->v, NULL, &cred,
858			NULL, NULL, NULL);
859	}
860	else
861	{
862		res = ldap_sasl_bind_s(ld,
863			NULL, NULL, NULL,
864			NULL, NULL, NULL);
865	}
866
867	if (res!=LDAP_SUCCESS) {
868		plog(LLV_ERROR, LOCATION, NULL,
869			"ldap_sasl_bind_s (search) failed: %s\n",
870			ldap_err2string(res));
871		goto ldap_end;
872	}
873
874	/* build an ldap user search filter */
875	tmplen = strlen(xauth_ldap_config.attr_user->v);
876	tmplen += 1;
877	tmplen += strlen(usr);
878	tmplen += 1;
879	filter = racoon_malloc(tmplen);
880	if (filter == NULL) {
881		plog(LLV_ERROR, LOCATION, NULL,
882			"unable to alloc ldap search filter buffer\n");
883		goto ldap_end;
884	}
885	sprintf(filter, "%s=%s",
886		xauth_ldap_config.attr_user->v, usr);
887
888	/* build our return attribute list */
889	tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1;
890	atlist[0] = racoon_malloc(tmplen);
891	tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1;
892	atlist[1] = racoon_malloc(tmplen);
893	if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
894		plog(LLV_ERROR, LOCATION, NULL,
895			"unable to alloc ldap attrib list buffer\n");
896		goto ldap_end;
897	}
898	strcpy(atlist[0],xauth_ldap_config.attr_addr->v);
899	strcpy(atlist[1],xauth_ldap_config.attr_mask->v);
900
901	/* attempt to locate the user dn */
902	if (xauth_ldap_config.base != NULL)
903		basedn = xauth_ldap_config.base->v;
904	if (xauth_ldap_config.subtree)
905		scope = LDAP_SCOPE_SUBTREE;
906	timeout.tv_sec = 15;
907	timeout.tv_usec = 0;
908	res = ldap_search_ext_s(ld, basedn, scope,
909		filter, atlist, 0, NULL, NULL,
910		&timeout, 2, &lr);
911	if (res != LDAP_SUCCESS) {
912		plog(LLV_ERROR, LOCATION, NULL,
913			"ldap_search_ext_s failed: %s\n",
914			ldap_err2string(res));
915		goto ldap_end;
916	}
917
918	/* check the number of ldap entries returned */
919	ecount = ldap_count_entries(ld, lr);
920	if (ecount < 1) {
921		plog(LLV_WARNING, LOCATION, NULL,
922			"no ldap results for filter \'%s\'\n",
923			 filter);
924		goto ldap_end;
925	}
926	if (ecount > 1) {
927		plog(LLV_WARNING, LOCATION, NULL,
928			"multiple (%i) ldap results for filter \'%s\'\n",
929			ecount, filter);
930	}
931
932	/* obtain the dn from the first result */
933	le = ldap_first_entry(ld, lr);
934	if (le == NULL) {
935		plog(LLV_ERROR, LOCATION, NULL,
936			"ldap_first_entry failed: invalid entry returned\n");
937		goto ldap_end;
938	}
939	userdn = ldap_get_dn(ld, le);
940	if (userdn == NULL) {
941		plog(LLV_ERROR, LOCATION, NULL,
942			"ldap_get_dn failed: invalid string returned\n");
943		goto ldap_end;
944	}
945
946	/* cache the user dn in the xauth state */
947	iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1);
948	strcpy(iph1->mode_cfg->xauth.udn,userdn);
949
950	/* retrieve modecfg address */
951	bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
952	if (bv != NULL)	{
953		char tmpaddr[16];
954		/* sanity check for address value */
955		if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
956			plog(LLV_DEBUG, LOCATION, NULL,
957				"ldap returned invalid modecfg address\n");
958			ldap_value_free_len(bv);
959			goto ldap_end;
960		}
961		memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
962		tmpaddr[bv[0]->bv_len]=0;
963		iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
964		iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
965		plog(LLV_INFO, LOCATION, NULL,
966			"ldap returned modecfg address %s\n", tmpaddr);
967		ldap_value_free_len(bv);
968	}
969
970	/* retrieve modecfg netmask */
971	bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
972	if (bv != NULL)	{
973		char tmpmask[16];
974		/* sanity check for netmask value */
975		if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
976			plog(LLV_DEBUG, LOCATION, NULL,
977				"ldap returned invalid modecfg netmask\n");
978			ldap_value_free_len(bv);
979			goto ldap_end;
980		}
981		memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
982		tmpmask[bv[0]->bv_len]=0;
983		iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
984		iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
985		plog(LLV_INFO, LOCATION, NULL,
986			"ldap returned modecfg netmask %s\n", tmpmask);
987		ldap_value_free_len(bv);
988	}
989
990	/*
991	 * finally, use the dn and the xauth
992	 * password to check the users given
993	 * credentials by attempting to bind
994	 * to the ldap server
995	 */
996	plog(LLV_INFO, LOCATION, NULL,
997		"attempting ldap bind for dn \'%s\'\n", userdn);
998	cred.bv_val = pwd;
999	cred.bv_len = strlen( cred.bv_val );
1000	res = ldap_sasl_bind_s(ld,
1001		userdn, NULL, &cred,
1002		NULL, NULL, NULL);
1003        if(res==LDAP_SUCCESS)
1004		rtn = 0;
1005
1006ldap_end:
1007
1008	/* free ldap resources */
1009	if (userdn != NULL)
1010		ldap_memfree(userdn);
1011	if (atlist[0] != NULL)
1012		racoon_free(atlist[0]);
1013	if (atlist[1] != NULL)
1014		racoon_free(atlist[1]);
1015	if (filter != NULL)
1016		racoon_free(filter);
1017	if (lr != NULL)
1018		ldap_msgfree(lr);
1019	if (init != NULL)
1020		racoon_free(init);
1021
1022	ldap_unbind_ext_s(ld, NULL, NULL);
1023
1024	return rtn;
1025}
1026
1027int
1028xauth_group_ldap(udn, grp)
1029	char * udn;
1030	char * grp;
1031{
1032	int rtn = -1;
1033	int res = -1;
1034	LDAP *ld = NULL;
1035	LDAPMessage *lr = NULL;
1036	LDAPMessage *le = NULL;
1037	struct berval cred;
1038	struct timeval timeout;
1039	char *init = NULL;
1040	char *filter = NULL;
1041	char *basedn = NULL;
1042	char *groupdn = NULL;
1043	int tmplen = 0;
1044	int ecount = 0;
1045	int scope = LDAP_SCOPE_ONE;
1046
1047	/* build our initialization url */
1048	tmplen = strlen("ldap://:") + 17;
1049	tmplen += strlen(xauth_ldap_config.host->v);
1050	init = racoon_malloc(tmplen);
1051	if (init == NULL) {
1052		plog(LLV_ERROR, LOCATION, NULL,
1053			"unable to alloc ldap init url\n");
1054		goto ldap_group_end;
1055	}
1056	sprintf(init,"ldap://%s:%d",
1057		xauth_ldap_config.host->v,
1058		xauth_ldap_config.port );
1059
1060	/* initialize the ldap handle */
1061	res = ldap_initialize(&ld, init);
1062	if (res != LDAP_SUCCESS) {
1063		plog(LLV_ERROR, LOCATION, NULL,
1064			"ldap_initialize failed: %s\n",
1065			ldap_err2string(res));
1066		goto ldap_group_end;
1067	}
1068
1069	/* initialize the protocol version */
1070	ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
1071		&xauth_ldap_config.pver);
1072
1073	/*
1074	 * attempt to bind to the ldap server.
1075         * default to anonymous bind unless a
1076	 * user dn and password has been
1077	 * specified in our configuration
1078         */
1079	if ((xauth_ldap_config.bind_dn != NULL)&&
1080	    (xauth_ldap_config.bind_pw != NULL))
1081	{
1082		cred.bv_val = xauth_ldap_config.bind_pw->v;
1083		cred.bv_len = strlen( cred.bv_val );
1084		res = ldap_sasl_bind_s(ld,
1085			xauth_ldap_config.bind_dn->v, NULL, &cred,
1086			NULL, NULL, NULL);
1087	}
1088	else
1089	{
1090		res = ldap_sasl_bind_s(ld,
1091			NULL, NULL, NULL,
1092			NULL, NULL, NULL);
1093	}
1094
1095	if (res!=LDAP_SUCCESS) {
1096		plog(LLV_ERROR, LOCATION, NULL,
1097			"ldap_sasl_bind_s (search) failed: %s\n",
1098			ldap_err2string(res));
1099		goto ldap_group_end;
1100	}
1101
1102	/* build an ldap group search filter */
1103	tmplen = strlen("(&(=)(=))") + 1;
1104	tmplen += strlen(xauth_ldap_config.attr_group->v);
1105	tmplen += strlen(grp);
1106	tmplen += strlen(xauth_ldap_config.attr_member->v);
1107	tmplen += strlen(udn);
1108	filter = racoon_malloc(tmplen);
1109	if (filter == NULL) {
1110		plog(LLV_ERROR, LOCATION, NULL,
1111			"unable to alloc ldap search filter buffer\n");
1112		goto ldap_group_end;
1113	}
1114	sprintf(filter, "(&(%s=%s)(%s=%s))",
1115		xauth_ldap_config.attr_group->v, grp,
1116		xauth_ldap_config.attr_member->v, udn);
1117
1118	/* attempt to locate the group dn */
1119	if (xauth_ldap_config.base != NULL)
1120		basedn = xauth_ldap_config.base->v;
1121	if (xauth_ldap_config.subtree)
1122		scope = LDAP_SCOPE_SUBTREE;
1123	timeout.tv_sec = 15;
1124	timeout.tv_usec = 0;
1125	res = ldap_search_ext_s(ld, basedn, scope,
1126		filter, NULL, 0, NULL, NULL,
1127		&timeout, 2, &lr);
1128	if (res != LDAP_SUCCESS) {
1129		plog(LLV_ERROR, LOCATION, NULL,
1130			"ldap_search_ext_s failed: %s\n",
1131			ldap_err2string(res));
1132		goto ldap_group_end;
1133	}
1134
1135	/* check the number of ldap entries returned */
1136	ecount = ldap_count_entries(ld, lr);
1137	if (ecount < 1) {
1138		plog(LLV_WARNING, LOCATION, NULL,
1139			"no ldap results for filter \'%s\'\n",
1140			 filter);
1141		goto ldap_group_end;
1142	}
1143
1144	/* success */
1145	rtn = 0;
1146
1147	/* obtain the dn from the first result */
1148	le = ldap_first_entry(ld, lr);
1149	if (le == NULL) {
1150		plog(LLV_ERROR, LOCATION, NULL,
1151			"ldap_first_entry failed: invalid entry returned\n");
1152		goto ldap_group_end;
1153	}
1154	groupdn = ldap_get_dn(ld, le);
1155	if (groupdn == NULL) {
1156		plog(LLV_ERROR, LOCATION, NULL,
1157			"ldap_get_dn failed: invalid string returned\n");
1158		goto ldap_group_end;
1159	}
1160
1161	plog(LLV_INFO, LOCATION, NULL,
1162		"ldap membership group returned \'%s\'\n", groupdn);
1163ldap_group_end:
1164
1165	/* free ldap resources */
1166	if (groupdn != NULL)
1167		ldap_memfree(groupdn);
1168	if (filter != NULL)
1169		racoon_free(filter);
1170	if (lr != NULL)
1171		ldap_msgfree(lr);
1172	if (init != NULL)
1173		racoon_free(init);
1174
1175	ldap_unbind_ext_s(ld, NULL, NULL);
1176
1177	return rtn;
1178}
1179
1180#endif
1181
1182#ifndef ANDROID_PATCHED
1183
1184int
1185xauth_login_system(usr, pwd)
1186	char *usr;
1187	char *pwd;
1188{
1189	struct passwd *pw;
1190	char *cryptpwd;
1191	char *syscryptpwd;
1192#ifdef HAVE_SHADOW_H
1193	struct spwd *spw;
1194
1195	if ((spw = getspnam(usr)) == NULL)
1196		return -1;
1197
1198	syscryptpwd = spw->sp_pwdp;
1199#endif
1200
1201	if ((pw = getpwnam(usr)) == NULL)
1202		return -1;
1203
1204#ifndef HAVE_SHADOW_H
1205	syscryptpwd = pw->pw_passwd;
1206#endif
1207
1208	/* No root login. Ever. */
1209	if (pw->pw_uid == 0)
1210		return -1;
1211
1212	if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
1213		return -1;
1214
1215	if (strcmp(cryptpwd, syscryptpwd) == 0)
1216		return 0;
1217
1218	return -1;
1219}
1220
1221#endif
1222
1223int
1224xauth_group_system(usr, grp)
1225	char * usr;
1226	char * grp;
1227{
1228	struct group * gr;
1229	char * member;
1230	int index = 0;
1231
1232	gr = getgrnam(grp);
1233	if (gr == NULL) {
1234		plog(LLV_ERROR, LOCATION, NULL,
1235			"the system group name \'%s\' is unknown\n",
1236			grp);
1237		return -1;
1238	}
1239
1240	while ((member = gr->gr_mem[index++])!=NULL) {
1241		if (!strcmp(member,usr)) {
1242			plog(LLV_INFO, LOCATION, NULL,
1243		                "membership validated\n");
1244			return 0;
1245		}
1246	}
1247
1248	return -1;
1249}
1250
1251int
1252xauth_check(iph1)
1253	struct ph1handle *iph1;
1254{
1255	struct xauth_state *xst = &iph1->mode_cfg->xauth;
1256
1257	/*
1258 	 * Only the server side (edge device) really check for Xauth
1259	 * status. It does it if the chose authmethod is using Xauth.
1260	 * On the client side (roadwarrior), we don't check anything.
1261	 */
1262	switch (AUTHMETHOD(iph1)) {
1263	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1264	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1265	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1266	/* The following are not yet implemented */
1267	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1268	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1269	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1270	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1271		if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1272			plog(LLV_ERROR, LOCATION, NULL,
1273			    "Hybrid auth negotiated but peer did not "
1274			    "announced as Xauth capable\n");
1275			return -1;
1276		}
1277
1278		if (xst->status != XAUTHST_OK) {
1279			plog(LLV_ERROR, LOCATION, NULL,
1280			    "Hybrid auth negotiated but peer did not "
1281			    "succeed Xauth exchange\n");
1282			return -1;
1283		}
1284
1285		return 0;
1286		break;
1287	default:
1288		return 0;
1289		break;
1290	}
1291
1292	return 0;
1293}
1294
1295int
1296group_check(iph1, grp_list, grp_count)
1297	struct ph1handle *iph1;
1298	char **grp_list;
1299	int grp_count;
1300{
1301	int res = -1;
1302	int grp_index = 0;
1303	char * usr = NULL;
1304
1305	/* check for presence of modecfg data */
1306
1307	if(iph1->mode_cfg == NULL) {
1308		plog(LLV_ERROR, LOCATION, NULL,
1309			"xauth group specified but modecfg not found\n");
1310		return res;
1311	}
1312
1313	/* loop through our group list */
1314
1315	for(; grp_index < grp_count; grp_index++) {
1316
1317		/* check for presence of xauth data */
1318
1319		usr = iph1->mode_cfg->xauth.authdata.generic.usr;
1320
1321		if(usr == NULL) {
1322			plog(LLV_ERROR, LOCATION, NULL,
1323				"xauth group specified but xauth not found\n");
1324			return res;
1325		}
1326
1327		/* call appropriate group validation funtion */
1328
1329		switch (isakmp_cfg_config.groupsource) {
1330
1331			case ISAKMP_CFG_GROUP_SYSTEM:
1332				res = xauth_group_system(
1333					usr,
1334					grp_list[grp_index]);
1335				break;
1336
1337#ifdef HAVE_LIBLDAP
1338			case ISAKMP_CFG_GROUP_LDAP:
1339				res = xauth_group_ldap(
1340					iph1->mode_cfg->xauth.udn,
1341					grp_list[grp_index]);
1342				break;
1343#endif
1344
1345			default:
1346				/* we should never get here */
1347				plog(LLV_ERROR, LOCATION, NULL,
1348				    "Unknown group auth source\n");
1349				break;
1350		}
1351
1352		if( !res ) {
1353			plog(LLV_INFO, LOCATION, NULL,
1354				"user \"%s\" is a member of group \"%s\"\n",
1355				usr,
1356				grp_list[grp_index]);
1357			break;
1358		} else {
1359			plog(LLV_INFO, LOCATION, NULL,
1360				"user \"%s\" is not a member of group \"%s\"\n",
1361				usr,
1362				grp_list[grp_index]);
1363		}
1364	}
1365
1366	return res;
1367}
1368
1369vchar_t *
1370isakmp_xauth_req(iph1, attr)
1371	struct ph1handle *iph1;
1372	struct isakmp_data *attr;
1373{
1374	int type;
1375	size_t dlen = 0;
1376	int ashort = 0;
1377	int value = 0;
1378	vchar_t *buffer = NULL;
1379	char *mraw = NULL, *mdata;
1380	char *data;
1381	vchar_t *usr = NULL;
1382	vchar_t *pwd = NULL;
1383	size_t skip = 0;
1384	int freepwd = 0;
1385
1386	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1387		plog(LLV_ERROR, LOCATION, NULL,
1388		    "Xauth mode config request but peer "
1389		    "did not declare itself as Xauth capable\n");
1390		return NULL;
1391	}
1392
1393	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1394
1395	/* Sanity checks */
1396	switch(type) {
1397	case XAUTH_TYPE:
1398		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1399			plog(LLV_ERROR, LOCATION, NULL,
1400			    "Unexpected long XAUTH_TYPE attribute\n");
1401			return NULL;
1402		}
1403		if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
1404			plog(LLV_ERROR, LOCATION, NULL,
1405			    "Unsupported Xauth authentication %d\n",
1406			    ntohs(attr->lorv));
1407			return NULL;
1408		}
1409		ashort = 1;
1410		dlen = 0;
1411		value = XAUTH_TYPE_GENERIC;
1412		break;
1413
1414	case XAUTH_USER_NAME:
1415		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
1416			plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
1417			    "with no login supplied\n");
1418			return NULL;
1419		}
1420
1421		dlen = iph1->rmconf->xauth->login->l - 1;
1422		iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
1423		break;
1424
1425#ifdef ANDROID_PATCHED
1426        case XAUTH_PASSCODE:
1427#endif
1428	case XAUTH_USER_PASSWORD:
1429		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
1430			return NULL;
1431
1432		skip = sizeof(struct ipsecdoi_id_b);
1433		usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
1434		if (usr == NULL) {
1435			plog(LLV_ERROR, LOCATION, NULL,
1436			    "Cannot allocate memory\n");
1437			return NULL;
1438		}
1439		memset(usr->v, 0, skip);
1440		memcpy(usr->v + skip,
1441		    iph1->rmconf->xauth->login->v,
1442		    iph1->rmconf->xauth->login->l - 1);
1443
1444		if (iph1->rmconf->xauth->pass) {
1445			/* A key given through racoonctl */
1446			pwd = iph1->rmconf->xauth->pass;
1447		} else {
1448			if ((pwd = getpskbyname(usr)) == NULL) {
1449				plog(LLV_ERROR, LOCATION, NULL,
1450				    "No password was found for login %s\n",
1451				    iph1->rmconf->xauth->login->v);
1452				vfree(usr);
1453				return NULL;
1454			}
1455			/* We have to free it before returning */
1456			freepwd = 1;
1457		}
1458		vfree(usr);
1459
1460		iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
1461		dlen = pwd->l;
1462
1463		break;
1464	case XAUTH_MESSAGE:
1465		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1466			dlen = ntohs(attr->lorv);
1467			if (dlen > 0) {
1468				mraw = (char*)(attr + 1);
1469				mdata = binsanitize(mraw, dlen);
1470				if (mdata == NULL) {
1471					plog(LLV_ERROR, LOCATION, iph1->remote,
1472					    "Cannot allocate memory\n");
1473					return NULL;
1474				}
1475				plog(LLV_NOTIFY,LOCATION, iph1->remote,
1476					"XAUTH Message: '%s'.\n",
1477					mdata);
1478				racoon_free(mdata);
1479			}
1480		}
1481		return NULL;
1482	default:
1483		plog(LLV_WARNING, LOCATION, NULL,
1484		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
1485		return NULL;
1486		break;
1487	}
1488
1489	if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
1490		plog(LLV_ERROR, LOCATION, NULL,
1491		    "Cannot allocate memory\n");
1492		goto out;
1493	}
1494
1495	attr = (struct isakmp_data *)buffer->v;
1496	if (ashort) {
1497		attr->type = htons(type | ISAKMP_GEN_TV);
1498		attr->lorv = htons(value);
1499		goto out;
1500	}
1501
1502	attr->type = htons(type | ISAKMP_GEN_TLV);
1503	attr->lorv = htons(dlen);
1504	data = (char *)(attr + 1);
1505
1506	switch(type) {
1507	case XAUTH_USER_NAME:
1508		/*
1509		 * iph1->rmconf->xauth->login->v is valid,
1510		 * we just checked it in the previous switch case
1511		 */
1512		memcpy(data, iph1->rmconf->xauth->login->v, dlen);
1513		break;
1514#ifdef ANDROID_PATCHED
1515        case XAUTH_PASSCODE:
1516#endif
1517	case XAUTH_USER_PASSWORD:
1518		memcpy(data, pwd->v, dlen);
1519		break;
1520	default:
1521		break;
1522	}
1523
1524out:
1525	if (freepwd)
1526		vfree(pwd);
1527
1528	return buffer;
1529}
1530
1531vchar_t *
1532isakmp_xauth_set(iph1, attr)
1533	struct ph1handle *iph1;
1534	struct isakmp_data *attr;
1535{
1536	int type;
1537	vchar_t *buffer = NULL;
1538	char *data;
1539	struct xauth_state *xst;
1540	size_t dlen = 0;
1541	char* mraw = NULL, *mdata;
1542
1543	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1544		plog(LLV_ERROR, LOCATION, NULL,
1545		    "Xauth mode config set but peer "
1546		    "did not declare itself as Xauth capable\n");
1547		return NULL;
1548	}
1549
1550	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1551
1552	switch(type) {
1553	case XAUTH_STATUS:
1554		/*
1555		 * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
1556		 * when running as a client (initiator).
1557		 */
1558		xst = &iph1->mode_cfg->xauth;
1559		switch(AUTHMETHOD(iph1)) {
1560		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1561		case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
1562		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
1563		/* Not implemented ... */
1564		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
1565		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
1566		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
1567		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
1568			break;
1569		default:
1570			plog(LLV_ERROR, LOCATION, NULL,
1571			    "Unexpected XAUTH_STATUS_OK\n");
1572			return NULL;
1573			break;
1574		}
1575
1576		/* If we got a failure, delete iph1 */
1577		if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
1578			plog(LLV_ERROR, LOCATION, NULL,
1579			    "Xauth authentication failed\n");
1580
1581			EVT_PUSH(iph1->local, iph1->remote,
1582			    EVTT_XAUTH_FAILED, NULL);
1583
1584			iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
1585		} else {
1586			EVT_PUSH(iph1->local, iph1->remote,
1587			    EVTT_XAUTH_SUCCESS, NULL);
1588		}
1589
1590
1591		/* We acknowledge it */
1592		break;
1593	case XAUTH_MESSAGE:
1594		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
1595			dlen = ntohs(attr->lorv);
1596			if (dlen > 0) {
1597				mraw = (char*)(attr + 1);
1598				mdata = binsanitize(mraw, dlen);
1599				if (mdata == NULL) {
1600					plog(LLV_ERROR, LOCATION, iph1->remote,
1601					    "Cannot allocate memory\n");
1602					return NULL;
1603				}
1604				plog(LLV_NOTIFY,LOCATION, iph1->remote,
1605					"XAUTH Message: '%s'.\n",
1606					mdata);
1607				racoon_free(mdata);
1608			}
1609		}
1610
1611	default:
1612		plog(LLV_WARNING, LOCATION, NULL,
1613		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
1614		return NULL;
1615		break;
1616	}
1617
1618	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1619		plog(LLV_ERROR, LOCATION, NULL,
1620		    "Cannot allocate memory\n");
1621		return NULL;
1622	}
1623
1624	attr = (struct isakmp_data *)buffer->v;
1625	attr->type = htons(type | ISAKMP_GEN_TV);
1626	attr->lorv = htons(0);
1627
1628	return buffer;
1629}
1630
1631
1632void
1633xauth_rmstate(xst)
1634	struct xauth_state *xst;
1635{
1636	switch (xst->authtype) {
1637	case XAUTH_TYPE_GENERIC:
1638		if (xst->authdata.generic.usr)
1639			racoon_free(xst->authdata.generic.usr);
1640
1641		if (xst->authdata.generic.pwd)
1642			racoon_free(xst->authdata.generic.pwd);
1643
1644		break;
1645
1646	case XAUTH_TYPE_CHAP:
1647	case XAUTH_TYPE_OTP:
1648	case XAUTH_TYPE_SKEY:
1649		plog(LLV_WARNING, LOCATION, NULL,
1650		    "Unsupported authtype %d\n", xst->authtype);
1651		break;
1652
1653	default:
1654		plog(LLV_WARNING, LOCATION, NULL,
1655		    "Unexpected authtype %d\n", xst->authtype);
1656		break;
1657	}
1658
1659#ifdef HAVE_LIBLDAP
1660	if (xst->udn != NULL)
1661		racoon_free(xst->udn);
1662#endif
1663	return;
1664}
1665
1666int
1667xauth_rmconf_used(xauth_rmconf)
1668	struct xauth_rmconf **xauth_rmconf;
1669{
1670	if (*xauth_rmconf == NULL) {
1671		*xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
1672		if (*xauth_rmconf == NULL) {
1673			plog(LLV_ERROR, LOCATION, NULL,
1674			    "xauth_rmconf_used: malloc failed\n");
1675			return -1;
1676		}
1677
1678		(*xauth_rmconf)->login = NULL;
1679		(*xauth_rmconf)->pass = NULL;
1680		(*xauth_rmconf)->state = 0;
1681	}
1682
1683	return 0;
1684}
1685
1686void
1687xauth_rmconf_delete(xauth_rmconf)
1688	struct xauth_rmconf **xauth_rmconf;
1689{
1690	if (*xauth_rmconf != NULL) {
1691		if ((*xauth_rmconf)->login != NULL)
1692			vfree((*xauth_rmconf)->login);
1693		if ((*xauth_rmconf)->pass != NULL)
1694			vfree((*xauth_rmconf)->pass);
1695
1696		racoon_free(*xauth_rmconf);
1697		*xauth_rmconf = NULL;
1698	}
1699
1700	return;
1701}
1702