1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/*	$NetBSD: isakmp_xauth.c,v 1.11.6.2 2009/04/20 13:35:36 tteras Exp $	*/
20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/*
60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 2004-2005 Emmanuel Dreyfus
70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved.
80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without
100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions
110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met:
120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright
130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer.
140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright
150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    notice, this list of conditions and the following disclaimer in the
160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    documentation and/or other materials provided with the distribution.
170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors
180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    may be used to endorse or promote products derived from this software
190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *    without specific prior written permission.
200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *
210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE.
320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */
330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h"
350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h>
370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h>
380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h>
390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/queue.h>
400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h>
420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h>
440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h>
450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h>
460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h>
470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <pwd.h>
480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <grp.h>
490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if TIME_WITH_SYS_TIME
500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h>
510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h>
520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else
530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if HAVE_SYS_TIME_H
540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <sys/time.h>
550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# else
560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#  include <time.h>
570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif
580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h>
600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_UNISTD_H
610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h>
620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h>
640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <resolv.h>
650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SHADOW_H
670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <shadow.h>
680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h"
710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h"
720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h"
730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h"
740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h"
750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h"
760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h"
770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "crypto_openssl.h"
790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h"
800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h"
810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "admin.h"
820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "privsep.h"
830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "evt.h"
840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h"
850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "throttle.h"
860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_inf.h"
880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_xauth.h"
890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_unity.h"
900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_cfg.h"
910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h"
920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ipsec_doi.h"
930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "remoteconf.h"
940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "localconf.h"
950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBRADIUS
970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <radlib.h>
98c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct rad_handle *radius_auth_state = NULL;
1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct rad_handle *radius_acct_state = NULL;
1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBPAM
1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <security/pam_appl.h>
1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic char *PAM_usr = NULL;
1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic char *PAM_pwd = NULL;
1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int PAM_conv(int, const struct pam_message **,
1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang    struct pam_response **, void *);
1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic struct pam_conv PAM_chat = { &PAM_conv, NULL };
1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBLDAP
1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "ldap.h"
1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/inet.h>
1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstruct xauth_ldap_config xauth_ldap_config;
1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_sendreq(iph1)
1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buffer;
1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_attr *attr;
1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *typeattr;
1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *usrattr;
1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *pwdattr;
1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst = &iph1->mode_cfg->xauth;
1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t tlen;
1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Status checks */
132c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	if (iph1->status != PHASE1ST_ESTABLISHED) {
1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth request while phase 1 is not completed\n");
1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xst->status != XAUTHST_NOTYET) {
1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth request whith Xauth state %d\n", xst->status);
1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL, "Sending Xauth request\n");
1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*attr) +
1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       + sizeof(*typeattr) +
1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       + sizeof(*usrattr) +
1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       + sizeof(*pwdattr);
1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buffer = vmalloc(tlen)) == NULL) {
1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr = (struct isakmp_pl_attr *)buffer->v;
1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attr, 0, tlen);
1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->h.len = htons(tlen);
1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->type = ISAKMP_CFG_REQUEST;
1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->id = htons(eay_random());
1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	typeattr = (struct isakmp_data *)(attr + 1);
1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	typeattr->type = htons(XAUTH_TYPE | ISAKMP_GEN_TV);
1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	typeattr->lorv = htons(XAUTH_TYPE_GENERIC);
1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	usrattr = (struct isakmp_data *)(typeattr + 1);
1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	usrattr->type = htons(XAUTH_USER_NAME | ISAKMP_GEN_TLV);
1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	usrattr->lorv = htons(0);
1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pwdattr = (struct isakmp_data *)(usrattr + 1);
1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pwdattr->type = htons(XAUTH_USER_PASSWORD | ISAKMP_GEN_TLV);
1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pwdattr->lorv = htons(0);
1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_cfg_send(iph1, buffer,
1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buffer);
1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xst->status = XAUTHST_REQSENT;
1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_attr_reply(iph1, attr, id)
1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *attr;
1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int id;
1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **outlet = NULL;
1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t alen = 0;
1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst = &iph1->mode_cfg->xauth;
1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth reply but peer did not declare "
1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "itself as Xauth capable\n");
2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xst->status != XAUTHST_REQSENT) {
2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth reply while Xauth state is %d\n", xst->status);
2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (type) {
2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE:
2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (ntohs(attr->lorv)) {
2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case XAUTH_TYPE_GENERIC:
2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xst->authtype = XAUTH_TYPE_GENERIC;
2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_WARNING, LOCATION, NULL,
2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Unexpected authentication type %d\n",
2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ntohs(type));
2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_NAME:
2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		outlet = &xst->authdata.generic.usr;
2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_PASSWORD:
2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		outlet = &xst->authdata.generic.pwd;
2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "ignored Xauth attribute %d\n", type);
2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (outlet != NULL) {
2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		alen = ntohs(attr->lorv);
2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*outlet = racoon_malloc(alen + 1)) == NULL) {
2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot allocate memory for Xauth Data\n");
2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(*outlet, attr + 1, alen);
2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(*outlet)[alen] = '\0';
2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		outlet = NULL;
2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((xst->authdata.generic.usr != NULL) &&
2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	   (xst->authdata.generic.pwd != NULL)) {
2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int port;
2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		int res;
2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *usr = xst->authdata.generic.usr;
2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char *pwd = xst->authdata.generic.pwd;
2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		time_t throttle_delay = 0;
2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if 0	/* Real debug, don't do that at home */
2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_DEBUG, LOCATION, NULL,
2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Got username \"%s\", password \"%s\"\n", usr, pwd);
2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		strncpy(iph1->mode_cfg->login, usr, LOGINLEN);
2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->mode_cfg->login[LOGINLEN] = '\0';
2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		res = -1;
2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((port = isakmp_cfg_getport(iph1)) == -1) {
2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Port pool depleted\n");
2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto skip_auth;
2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (isakmp_cfg_config.authsource) {
2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ISAKMP_CFG_AUTH_SYSTEM:
2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = privsep_xauth_login_system(usr, pwd);
2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBRADIUS
2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ISAKMP_CFG_AUTH_RADIUS:
2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = xauth_login_radius(iph1, usr, pwd);
2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBPAM
2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ISAKMP_CFG_AUTH_PAM:
2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = privsep_xauth_login_pam(iph1->mode_cfg->port,
2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    iph1->remote, usr, pwd);
2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBLDAP
2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case ISAKMP_CFG_AUTH_LDAP:
2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = xauth_login_ldap(iph1, usr, pwd);
2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Unexpected authentication source\n");
2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = -1;
2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * Optional group authentication
3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!res && (isakmp_cfg_config.groupcount))
3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = group_check(iph1,
3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_cfg_config.grouplist,
3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				isakmp_cfg_config.groupcount);
3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * On failure, throttle the connexion for the remote host
3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * in order to make password attacks more difficult.
3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
314c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		throttle_delay = throttle_host(iph1->remote, res) - time(NULL);
3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (throttle_delay > 0) {
3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			char *str;
3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			str = saddrwop2str(iph1->remote);
3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Throttling in action for %s: delay %lds\n",
3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    str, (unsigned long)throttle_delay);
3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			res = -1;
3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			throttle_delay = 0;
3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangskip_auth:
3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (throttle_delay != 0) {
3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			struct xauth_reply_arg *xra;
3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
332c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			if ((xra = racoon_malloc(sizeof(*xra))) == NULL) {
3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "malloc failed, bypass throttling\n");
3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return xauth_reply(iph1, port, id, res);
3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/*
3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * We need to store the ph1, but it might have
3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * disapeared when xauth_reply is called, so
3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 * store the index instead.
3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 */
3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xra->index = iph1->index;
3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xra->port = port;
3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xra->id = id;
3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xra->res = res;
347c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			sched_new(throttle_delay, xauth_reply_stub, xra);
3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return xauth_reply(iph1, port, id, res);
3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
357c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehxauth_reply_stub(args)
358c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	void *args;
3590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
360c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	struct xauth_reply_arg *xra = (struct xauth_reply_arg *)args;
3610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
3620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1 = getph1byindex(&xra->index)) != NULL)
3640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(void)xauth_reply(iph1, xra->port, xra->id, xra->res);
3650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
3660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
3670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Delayed Xauth reply: phase 1 no longer exists.\n");
3680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	racoon_free(xra);
370c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	return;
3710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
3720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
3740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_reply(iph1, port, id, res)
3750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
3760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
3770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int id;
3780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
3790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst = &iph1->mode_cfg->xauth;
3800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr = xst->authdata.generic.usr;
3810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res != 0) {
3830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (port != -1)
3840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_cfg_putport(iph1, port);
3850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
3870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "login failed for user \"%s\"\n", usr);
3880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_sendstatus(iph1, XAUTH_STATUS_FAIL, id);
3900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xst->status = XAUTHST_NOTYET;
3910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Delete Phase 1 SA */
393c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (iph1->status == PHASE1ST_ESTABLISHED)
3940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			isakmp_info_send_d1(iph1);
3950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		remph1(iph1);
3960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		delph1(iph1);
3970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
3980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
3990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xst->status = XAUTHST_OK;
4020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
4030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    "login succeeded for user \"%s\"\n", usr);
4040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_sendstatus(iph1, XAUTH_STATUS_OK, id);
4060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
4080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
4110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_sendstatus(iph1, status, id)
4120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
4130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int status;
4140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int id;
4150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buffer;
4170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_pl_attr *attr;
4180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *stattr;
4190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t tlen;
4200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tlen = sizeof(*attr) +
4220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	       + sizeof(*stattr);
4230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buffer = vmalloc(tlen)) == NULL) {
4250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate buffer\n");
4260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return;
4270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr = (struct isakmp_pl_attr *)buffer->v;
4300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memset(attr, 0, tlen);
4310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->h.len = htons(tlen);
4330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->type = ISAKMP_CFG_SET;
4340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->id = htons(id);
4350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	stattr = (struct isakmp_data *)(attr + 1);
4370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	stattr->type = htons(XAUTH_STATUS | ISAKMP_GEN_TV);
4380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	stattr->lorv = htons(status);
4390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_cfg_send(iph1, buffer,
4410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
4420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vfree(buffer);
4440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
4460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBRADIUS
4490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_radius_init(void)
4510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* For first time use, initialize Radius */
4530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_RADIUS) &&
4540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    (radius_auth_state == NULL)) {
4550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((radius_auth_state = rad_auth_open()) == NULL) {
4560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot init libradius\n");
4580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
461c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (rad_config(radius_auth_state, NULL) != 0) {
462c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
463c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    "Cannot open librarius config file: %s\n",
464c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    rad_strerror(radius_auth_state));
465c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			rad_close(radius_auth_state);
466c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			radius_auth_state = NULL;
467c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return -1;
4680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS) &&
4720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    (radius_acct_state == NULL)) {
4730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((radius_acct_state = rad_acct_open()) == NULL) {
4740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
4750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot init libradius\n");
4760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
4770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
479c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		if (rad_config(radius_acct_state, NULL) != 0) {
480c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			plog(LLV_ERROR, LOCATION, NULL,
481c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    "Cannot open librarius config file: %s\n",
482c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    rad_strerror(radius_acct_state));
483c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			rad_close(radius_acct_state);
484c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			radius_acct_state = NULL;
485c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			return -1;
4860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
4870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
4880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
4900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
4910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
4920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
4930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_login_radius(iph1, usr, pwd)
4940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
4950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
4960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
4970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
4980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
4990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const void *data;
5000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
5010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
5020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rad_create_request(radius_auth_state, RAD_ACCESS_REQUEST) != 0) {
5040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "rad_create_request failed: %s\n",
5060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    rad_strerror(radius_auth_state));
5070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rad_put_string(radius_auth_state, RAD_USER_NAME, usr) != 0) {
5110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "rad_put_string failed: %s\n",
5130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    rad_strerror(radius_auth_state));
5140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (rad_put_string(radius_auth_state, RAD_USER_PASSWORD, pwd) != 0) {
5180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "rad_put_string failed: %s\n",
5200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    rad_strerror(radius_auth_state));
5210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_cfg_radius_common(radius_auth_state, iph1->mode_cfg->port) != 0)
5250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (res = rad_send_request(radius_auth_state)) {
5280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case RAD_ACCESS_ACCEPT:
5290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		while ((type = rad_get_attr(radius_auth_state, &data, &len)) != 0) {
5300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			switch (type) {
5310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case RAD_FRAMED_IP_ADDRESS:
5320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->mode_cfg->addr4 = rad_cvt_addr(data);
5330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->mode_cfg->flags
5340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    |= ISAKMP_CFG_ADDR4_EXTERN;
5350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case RAD_FRAMED_IP_NETMASK:
5380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->mode_cfg->mask4 = rad_cvt_addr(data);
5390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				iph1->mode_cfg->flags
5400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    |= ISAKMP_CFG_MASK4_EXTERN;
5410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
5440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_INFO, LOCATION, NULL,
5450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Unexpected attribute: %d\n", type);
5460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
5470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
5480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
5490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
5510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
5520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case RAD_ACCESS_REJECT:
5540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
5560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case -1:
5580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "rad_send_request failed: %s\n",
5600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    rad_strerror(radius_auth_state));
5610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
5630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
5640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
5650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "rad_send_request returned %d\n", res);
5660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
5670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
5680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
5690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
5710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
5720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
5730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBPAM
5750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangstatic int
5760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih WangPAM_conv(msg_count, msg, rsp, dontcare)
5770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int msg_count;
5780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const struct pam_message **msg;
5790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct pam_response **rsp;
5800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	void *dontcare;
5810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
5820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int i;
5830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int replies = 0;
5840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct pam_response *reply = NULL;
5850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((reply = racoon_malloc(sizeof(*reply) * msg_count)) == NULL)
5870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return PAM_CONV_ERR;
5880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bzero(reply, sizeof(*reply) * msg_count);
5890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
5900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for (i = 0; i < msg_count; i++) {
5910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (msg[i]->msg_style) {
5920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PAM_PROMPT_ECHO_ON:
5930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Send the username, libpam frees resp */
5940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply[i].resp_retcode = PAM_SUCCESS;
5950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((reply[i].resp = strdup(PAM_usr)) == NULL) {
5960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION,
5970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    NULL, "strdup failed\n");
5980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				exit(1);
5990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PAM_PROMPT_ECHO_OFF:
6030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* Send the password, libpam frees resp */
6040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply[i].resp_retcode = PAM_SUCCESS;
6050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((reply[i].resp = strdup(PAM_pwd)) == NULL) {
6060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION,
6070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    NULL, "strdup failed\n");
6080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				exit(1);
6090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
6100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PAM_TEXT_INFO:
6130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case PAM_ERROR_MSG:
6140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply[i].resp_retcode = PAM_SUCCESS;
6150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			reply[i].resp = NULL;
6160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
6190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (reply != NULL)
6200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				racoon_free(reply);
6210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return PAM_CONV_ERR;
6220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
6230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (reply != NULL)
6270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*rsp = reply;
6280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return PAM_SUCCESS;
6300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
6310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
6330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_login_pam(port, raddr, usr, pwd)
6340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int port;
6350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct sockaddr *raddr;
6360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
6370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
6380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
6390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error;
6400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res;
6410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	const void *data;
6420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t len;
6430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
6440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *remote = NULL;
6450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pam_handle_t *pam = NULL;
6460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (isakmp_cfg_config.port_pool == NULL) {
6480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "isakmp_cfg_config.port_pool == NULL\n");
6500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
6510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((error = pam_start("racoon", usr,
6540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    &PAM_chat, &isakmp_cfg_config.port_pool[port].pam)) != 0) {
6550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (isakmp_cfg_config.port_pool[port].pam == NULL) {
6560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "pam_start failed\n");
6570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
6580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
6590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
6600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "pam_start failed: %s\n",
6610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    pam_strerror(isakmp_cfg_config.port_pool[port].pam,
6620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    error));
6630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto out;
6640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
6650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pam = isakmp_cfg_config.port_pool[port].pam;
6670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((remote = strdup(saddrwop2str(raddr))) == NULL) {
6690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "cannot allocate memory: %s\n", strerror(errno));
6710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
6720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
673c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh
6740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((error = pam_set_item(pam, PAM_RHOST, remote)) != 0) {
6750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "pam_set_item failed: %s\n",
6770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pam_strerror(pam, error));
6780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
6790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PAM_usr = usr;
6820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PAM_pwd = pwd;
6830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = pam_authenticate(pam, 0);
6840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PAM_usr = NULL;
6850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	PAM_pwd = NULL;
6860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0) {
6870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "pam_authenticate failed: %s\n",
6890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pam_strerror(pam, error));
6900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
6910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
6930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((error = pam_acct_mgmt(pam, 0)) != 0) {
6940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
6950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "pam_acct_mgmt failed: %s\n",
6960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pam_strerror(pam, error));
6970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
6980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
6990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((error = pam_setcred(pam, 0)) != 0) {
7010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
7020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "pam_setcred failed: %s\n",
7030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    pam_strerror(pam, error));
7040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
7060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (remote != NULL)
7080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free(remote);
7090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
7110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
7130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	pam_end(pam, error);
7140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	isakmp_cfg_config.port_pool[port].pam = NULL;
7150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (remote != NULL)
7160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		free(remote);
7170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
7180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
7200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBLDAP
7220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
723c91307af2622f6625525f3c1f9c954376df950adChia-chi Yehxauth_ldap_init(void)
7240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tmplen;
7260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int error = -1;
7270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.pver = 3;
7290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.host = NULL;
7300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.port = LDAP_PORT;
7310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.base = NULL;
7320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.subtree = 0;
7330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.bind_dn = NULL;
7340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.bind_pw = NULL;
7350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.auth_type = LDAP_AUTH_SIMPLE;
7360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_user = NULL;
7370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_addr = NULL;
7380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_mask = NULL;
7390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_group = NULL;
7400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_member = NULL;
7410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default host */
7430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_HOST);
7440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.host = vmalloc(tmplen);
7450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.host == NULL)
7460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.host->v, LDAP_DFLT_HOST, tmplen);
7480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default user naming attribute */
7500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_USER);
7510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_user = vmalloc(tmplen);
7520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.attr_user == NULL)
7530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.attr_user->v, LDAP_DFLT_USER, tmplen);
7550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default address attribute */
7570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_ADDR);
7580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_addr = vmalloc(tmplen);
7590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.attr_addr == NULL)
7600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.attr_addr->v, LDAP_DFLT_ADDR, tmplen);
7620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default netmask attribute */
7640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_MASK);
7650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_mask = vmalloc(tmplen);
7660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.attr_mask == NULL)
7670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.attr_mask->v, LDAP_DFLT_MASK, tmplen);
7690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default group naming attribute */
7710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_GROUP);
7720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_group = vmalloc(tmplen);
7730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.attr_group == NULL)
7740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.attr_group->v, LDAP_DFLT_GROUP, tmplen);
7760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* set default member attribute */
7780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(LDAP_DFLT_MEMBER);
7790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	xauth_ldap_config.attr_member = vmalloc(tmplen);
7800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.attr_member == NULL)
7810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
7820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	memcpy(xauth_ldap_config.attr_member->v, LDAP_DFLT_MEMBER, tmplen);
7830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	error = 0;
7850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
7860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (error != 0)
7870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL, "cannot allocate memory\n");
7880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return error;
7900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
7910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
7920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
7930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_login_ldap(iph1, usr, pwd)
7940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
7950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
7960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
7970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
7980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int rtn = -1;
7990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res = -1;
8000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAP *ld = NULL;
8010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAPMessage *lr = NULL;
8020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAPMessage *le = NULL;
8030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct berval cred;
8040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct berval **bv = NULL;
8050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval timeout;
8060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *init = NULL;
8070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *filter = NULL;
8080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *atlist[3];
8090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *basedn = NULL;
8100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *userdn = NULL;
8110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tmplen = 0;
8120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ecount = 0;
8130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int scope = LDAP_SCOPE_ONE;
8140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	atlist[0] = NULL;
8160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	atlist[1] = NULL;
8170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	atlist[2] = NULL;
8180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* build our initialization url */
8200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen("ldap://:") + 17;
8210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(xauth_ldap_config.host->v);
8220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	init = racoon_malloc(tmplen);
8230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (init == NULL) {
8240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unable to alloc ldap init url\n");
8260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
8270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(init,"ldap://%s:%d",
8290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.host->v,
8300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.port );
8310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize the ldap handle */
8330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = ldap_initialize(&ld, init);
8340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res != LDAP_SUCCESS) {
8350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_initialize failed: %s\n",
8370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
8380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
8390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize the protocol version */
8420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
8430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&xauth_ldap_config.pver);
8440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
8460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * attempt to bind to the ldap server.
8470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         * default to anonymous bind unless a
8480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * user dn and password has been
8490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * specified in our configuration
8500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
8510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((xauth_ldap_config.bind_dn != NULL)&&
8520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    (xauth_ldap_config.bind_pw != NULL))
8530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
8540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cred.bv_val = xauth_ldap_config.bind_pw->v;
8550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cred.bv_len = strlen( cred.bv_val );
8560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		res = ldap_sasl_bind_s(ld,
8570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xauth_ldap_config.bind_dn->v, NULL, &cred,
8580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL);
8590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
8610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
8620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		res = ldap_sasl_bind_s(ld,
8630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL,
8640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL);
8650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res!=LDAP_SUCCESS) {
8680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_sasl_bind_s (search) failed: %s\n",
8700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
8710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
8720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* build an ldap user search filter */
8750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(xauth_ldap_config.attr_user->v);
8760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += 1;
8770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(usr);
8780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += 1;
8790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	filter = racoon_malloc(tmplen);
8800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (filter == NULL) {
8810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unable to alloc ldap search filter buffer\n");
8830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
8840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(filter, "%s=%s",
8860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.attr_user->v, usr);
8870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
8880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* build our return attribute list */
8890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(xauth_ldap_config.attr_addr->v) + 1;
8900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	atlist[0] = racoon_malloc(tmplen);
8910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen(xauth_ldap_config.attr_mask->v) + 1;
8920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	atlist[1] = racoon_malloc(tmplen);
8930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((atlist[0] == NULL)||(atlist[1] == NULL)) {
8940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
8950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unable to alloc ldap attrib list buffer\n");
8960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
8970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
8980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	strcpy(atlist[0],xauth_ldap_config.attr_addr->v);
8990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	strcpy(atlist[1],xauth_ldap_config.attr_mask->v);
9000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* attempt to locate the user dn */
9020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.base != NULL)
9030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		basedn = xauth_ldap_config.base->v;
9040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.subtree)
9050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		scope = LDAP_SCOPE_SUBTREE;
9060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	timeout.tv_sec = 15;
9070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	timeout.tv_usec = 0;
9080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = ldap_search_ext_s(ld, basedn, scope,
9090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		filter, atlist, 0, NULL, NULL,
9100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&timeout, 2, &lr);
9110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res != LDAP_SUCCESS) {
9120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_search_ext_s failed: %s\n",
9140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
9150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
9160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check the number of ldap entries returned */
9190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ecount = ldap_count_entries(ld, lr);
9200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ecount < 1) {
9210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
9220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no ldap results for filter \'%s\'\n",
9230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 filter);
9240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
9250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ecount > 1) {
9270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
9280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"multiple (%i) ldap results for filter \'%s\'\n",
9290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ecount, filter);
9300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* obtain the dn from the first result */
9330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	le = ldap_first_entry(ld, lr);
9340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (le == NULL) {
9350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_first_entry failed: invalid entry returned\n");
9370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
9380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	userdn = ldap_get_dn(ld, le);
9400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (userdn == NULL) {
9410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
9420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_get_dn failed: invalid string returned\n");
9430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_end;
9440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* cache the user dn in the xauth state */
9470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	iph1->mode_cfg->xauth.udn = racoon_malloc(strlen(userdn)+1);
9480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	strcpy(iph1->mode_cfg->xauth.udn,userdn);
9490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* retrieve modecfg address */
9510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_addr->v);
9520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bv != NULL)	{
9530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char tmpaddr[16];
9540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check for address value */
9550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
9560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
9570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ldap returned invalid modecfg address\n");
9580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_value_free_len(bv);
9590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto ldap_end;
9600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(tmpaddr,bv[0]->bv_val,bv[0]->bv_len);
9620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tmpaddr[bv[0]->bv_len]=0;
9630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->mode_cfg->addr4.s_addr = inet_addr(tmpaddr);
9640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_EXTERN;
9650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
9660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap returned modecfg address %s\n", tmpaddr);
9670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_value_free_len(bv);
9680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* retrieve modecfg netmask */
9710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	bv = ldap_get_values_len(ld, le, xauth_ldap_config.attr_mask->v);
9720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (bv != NULL)	{
9730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		char tmpmask[16];
9740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* sanity check for netmask value */
9750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((bv[0]->bv_len < 7)||(bv[0]->bv_len > 15)) {
9760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_DEBUG, LOCATION, NULL,
9770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"ldap returned invalid modecfg netmask\n");
9780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_value_free_len(bv);
9790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			goto ldap_end;
9800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
9810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(tmpmask,bv[0]->bv_val,bv[0]->bv_len);
9820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		tmpmask[bv[0]->bv_len]=0;
9830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->mode_cfg->mask4.s_addr = inet_addr(tmpmask);
9840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_EXTERN;
9850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_INFO, LOCATION, NULL,
9860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap returned modecfg netmask %s\n", tmpmask);
9870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_value_free_len(bv);
9880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
9890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
9900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
9910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * finally, use the dn and the xauth
9920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * password to check the users given
9930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * credentials by attempting to bind
9940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * to the ldap server
9950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
9960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
9970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"attempting ldap bind for dn \'%s\'\n", userdn);
9980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cred.bv_val = pwd;
9990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	cred.bv_len = strlen( cred.bv_val );
10000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = ldap_sasl_bind_s(ld,
10010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		userdn, NULL, &cred,
10020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		NULL, NULL, NULL);
10030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang        if(res==LDAP_SUCCESS)
10040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		rtn = 0;
10050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangldap_end:
10070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free ldap resources */
10090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (userdn != NULL)
10100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_memfree(userdn);
10110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (atlist[0] != NULL)
10120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(atlist[0]);
10130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (atlist[1] != NULL)
10140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(atlist[1]);
10150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (filter != NULL)
10160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(filter);
10170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (lr != NULL)
10180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_msgfree(lr);
10190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (init != NULL)
10200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(init);
10210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ldap_unbind_ext_s(ld, NULL, NULL);
10230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rtn;
10250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
10260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
10280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_group_ldap(udn, grp)
10290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * udn;
10300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * grp;
10310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
10320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int rtn = -1;
10330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res = -1;
10340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAP *ld = NULL;
10350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAPMessage *lr = NULL;
10360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	LDAPMessage *le = NULL;
10370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct berval cred;
10380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct timeval timeout;
10390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *init = NULL;
10400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *filter = NULL;
10410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *basedn = NULL;
10420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *groupdn = NULL;
10430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int tmplen = 0;
10440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ecount = 0;
10450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int scope = LDAP_SCOPE_ONE;
10460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* build our initialization url */
10480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen("ldap://:") + 17;
10490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(xauth_ldap_config.host->v);
10500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	init = racoon_malloc(tmplen);
10510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (init == NULL) {
10520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unable to alloc ldap init url\n");
10540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
10550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(init,"ldap://%s:%d",
10570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.host->v,
10580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.port );
10590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize the ldap handle */
10610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = ldap_initialize(&ld, init);
10620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res != LDAP_SUCCESS) {
10630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_initialize failed: %s\n",
10650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
10660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
10670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* initialize the protocol version */
10700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
10710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&xauth_ldap_config.pver);
10720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
10740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * attempt to bind to the ldap server.
10750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         * default to anonymous bind unless a
10760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * user dn and password has been
10770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * specified in our configuration
10780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang         */
10790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((xauth_ldap_config.bind_dn != NULL)&&
10800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	    (xauth_ldap_config.bind_pw != NULL))
10810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
10820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cred.bv_val = xauth_ldap_config.bind_pw->v;
10830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		cred.bv_len = strlen( cred.bv_val );
10840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		res = ldap_sasl_bind_s(ld,
10850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			xauth_ldap_config.bind_dn->v, NULL, &cred,
10860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL);
10870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	else
10890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	{
10900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		res = ldap_sasl_bind_s(ld,
10910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL,
10920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			NULL, NULL, NULL);
10930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
10940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
10950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res!=LDAP_SUCCESS) {
10960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
10970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_sasl_bind_s (search) failed: %s\n",
10980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
10990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* build an ldap group search filter */
11030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen = strlen("(&(=)(=))") + 1;
11040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(xauth_ldap_config.attr_group->v);
11050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(grp);
11060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(xauth_ldap_config.attr_member->v);
11070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	tmplen += strlen(udn);
11080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	filter = racoon_malloc(tmplen);
11090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (filter == NULL) {
11100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"unable to alloc ldap search filter buffer\n");
11120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	sprintf(filter, "(&(%s=%s)(%s=%s))",
11150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.attr_group->v, grp,
11160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xauth_ldap_config.attr_member->v, udn);
11170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* attempt to locate the group dn */
11190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.base != NULL)
11200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		basedn = xauth_ldap_config.base->v;
11210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xauth_ldap_config.subtree)
11220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		scope = LDAP_SCOPE_SUBTREE;
11230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	timeout.tv_sec = 15;
11240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	timeout.tv_usec = 0;
11250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	res = ldap_search_ext_s(ld, basedn, scope,
11260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		filter, NULL, 0, NULL, NULL,
11270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		&timeout, 2, &lr);
11280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (res != LDAP_SUCCESS) {
11290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_search_ext_s failed: %s\n",
11310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			ldap_err2string(res));
11320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check the number of ldap entries returned */
11360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ecount = ldap_count_entries(ld, lr);
11370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ecount < 1) {
11380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
11390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"no ldap results for filter \'%s\'\n",
11400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			 filter);
11410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* success */
11450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	rtn = 0;
11460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* obtain the dn from the first result */
11480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	le = ldap_first_entry(ld, lr);
11490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (le == NULL) {
11500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_first_entry failed: invalid entry returned\n");
11520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	groupdn = ldap_get_dn(ld, le);
11550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (groupdn == NULL) {
11560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
11570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"ldap_get_dn failed: invalid string returned\n");
11580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto ldap_group_end;
11590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
11600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	plog(LLV_INFO, LOCATION, NULL,
11620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		"ldap membership group returned \'%s\'\n", groupdn);
11630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangldap_group_end:
11640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* free ldap resources */
11660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (groupdn != NULL)
11670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_memfree(groupdn);
11680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (filter != NULL)
11690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(filter);
11700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (lr != NULL)
11710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ldap_msgfree(lr);
11720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (init != NULL)
11730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(init);
11740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	ldap_unbind_ext_s(ld, NULL, NULL);
11760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return rtn;
11780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
11790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
11810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1182514ffe2b8b4236d53f584fcd8382dd65bc4df532Chia-chi Yeh#ifndef ANDROID_PATCHED
1183514ffe2b8b4236d53f584fcd8382dd65bc4df532Chia-chi Yeh
11840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
11850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_login_system(usr, pwd)
11860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *usr;
11870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *pwd;
11880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
11890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct passwd *pw;
11900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *cryptpwd;
11910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *syscryptpwd;
11920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_SHADOW_H
11930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct spwd *spw;
11940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((spw = getspnam(usr)) == NULL)
11960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
11970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
11980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syscryptpwd = spw->sp_pwdp;
11990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((pw = getpwnam(usr)) == NULL)
12020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifndef HAVE_SHADOW_H
12050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	syscryptpwd = pw->pw_passwd;
12060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
12070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* No root login. Ever. */
12090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (pw->pw_uid == 0)
12100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((cryptpwd = crypt(pwd, syscryptpwd)) == NULL)
12130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (strcmp(cryptpwd, syscryptpwd) == 0)
12160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
12170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
12190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1221514ffe2b8b4236d53f584fcd8382dd65bc4df532Chia-chi Yeh#endif
1222514ffe2b8b4236d53f584fcd8382dd65bc4df532Chia-chi Yeh
12230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
12240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_group_system(usr, grp)
12250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * usr;
12260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * grp;
12270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct group * gr;
12290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * member;
12300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int index = 0;
12310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	gr = getgrnam(grp);
12330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (gr == NULL) {
12340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
12350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"the system group name \'%s\' is unknown\n",
12360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			grp);
12370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return -1;
12380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	while ((member = gr->gr_mem[index++])!=NULL) {
12410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!strcmp(member,usr)) {
12420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
12430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		                "membership validated\n");
12440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return 0;
12450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return -1;
12490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
12520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_check(iph1)
12530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
12550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst = &iph1->mode_cfg->xauth;
12560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/*
12580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 	 * Only the server side (edge device) really check for Xauth
12590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * status. It does it if the chose authmethod is using Xauth.
12600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 * On the client side (roadwarrior), we don't check anything.
12610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	 */
1262c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh	switch (AUTHMETHOD(iph1)) {
12630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
12640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
12650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
12660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* The following are not yet implemented */
12670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
12680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
12690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
12700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
12710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
12720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Hybrid auth negotiated but peer did not "
12740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "announced as Xauth capable\n");
12750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (xst->status != XAUTHST_OK) {
12790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
12800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Hybrid auth negotiated but peer did not "
12810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "succeed Xauth exchange\n");
12820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
12830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
12840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
12860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
12870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
12880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return 0;
12890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
12900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
12910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
12930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
12940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
12950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
12960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wanggroup_check(iph1, grp_list, grp_count)
12970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
12980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char **grp_list;
12990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int grp_count;
13000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int res = -1;
13020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int grp_index = 0;
13030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char * usr = NULL;
13040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* check for presence of modecfg data */
13060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if(iph1->mode_cfg == NULL) {
13080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			"xauth group specified but modecfg not found\n");
13100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return res;
13110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* loop through our group list */
13140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	for(; grp_index < grp_count; grp_index++) {
13160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* check for presence of xauth data */
13180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		usr = iph1->mode_cfg->xauth.authdata.generic.usr;
13200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if(usr == NULL) {
13220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
13230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"xauth group specified but xauth not found\n");
13240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return res;
13250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* call appropriate group validation funtion */
13280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		switch (isakmp_cfg_config.groupsource) {
13300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ISAKMP_CFG_GROUP_SYSTEM:
13320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				res = xauth_group_system(
13330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					usr,
13340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					grp_list[grp_index]);
13350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
13360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBLDAP
13380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			case ISAKMP_CFG_GROUP_LDAP:
13390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				res = xauth_group_ldap(
13400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					iph1->mode_cfg->xauth.udn,
13410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					grp_list[grp_index]);
13420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
13430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
13440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			default:
13460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				/* we should never get here */
13470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
13480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "Unknown group auth source\n");
13490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				break;
13500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if( !res ) {
13530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
13540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"user \"%s\" is a member of group \"%s\"\n",
13550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				usr,
13560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				grp_list[grp_index]);
13570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
13580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
13590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_INFO, LOCATION, NULL,
13600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				"user \"%s\" is not a member of group \"%s\"\n",
13610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				usr,
13620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				grp_list[grp_index]);
13630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
13640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return res;
13670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
13680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
13700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_xauth_req(iph1, attr)
13710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
13720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *attr;
13730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
13740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
13750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t dlen = 0;
13760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int ashort = 0;
13770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int value = 0;
13780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buffer = NULL;
13791c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	char *mraw = NULL, *mdata;
13800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
13810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *usr = NULL;
13820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *pwd = NULL;
13830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t skip = 0;
13840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int freepwd = 0;
13850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
13870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
13880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth mode config request but peer "
13890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "did not declare itself as Xauth capable\n");
13900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
13910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
13920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
13940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
13950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	/* Sanity checks */
13960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(type) {
13970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE:
13980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
13990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Unexpected long XAUTH_TYPE attribute\n");
14010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ntohs(attr->lorv) != XAUTH_TYPE_GENERIC) {
14040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Unsupported Xauth authentication %d\n",
14060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    ntohs(attr->lorv));
14070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		ashort = 1;
14100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dlen = 0;
14110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		value = XAUTH_TYPE_GENERIC;
14120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
14130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_NAME:
14150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login) {
14160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL, "Xauth performed "
14170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "with no login supplied\n");
14180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dlen = iph1->rmconf->xauth->login->l - 1;
14220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf->xauth->state |= XAUTH_SENT_USERNAME;
14230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
14240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1425d30604685e6cc1fa878806ae590dcd1fc9d43f91Chia-chi Yeh#ifdef ANDROID_PATCHED
1426c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh        case XAUTH_PASSCODE:
1427c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
14280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_PASSWORD:
14290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (!iph1->rmconf->xauth || !iph1->rmconf->xauth->login)
14300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		skip = sizeof(struct ipsecdoi_id_b);
14330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		usr = vmalloc(iph1->rmconf->xauth->login->l - 1 + skip);
14340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (usr == NULL) {
14350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
14360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Cannot allocate memory\n");
14370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
14380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memset(usr->v, 0, skip);
14400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(usr->v + skip,
14410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->rmconf->xauth->login->v,
14420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    iph1->rmconf->xauth->login->l - 1);
14430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (iph1->rmconf->xauth->pass) {
14450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* A key given through racoonctl */
14460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			pwd = iph1->rmconf->xauth->pass;
14470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
14480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if ((pwd = getpskbyname(usr)) == NULL) {
14490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_ERROR, LOCATION, NULL,
14500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    "No password was found for login %s\n",
14510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				    iph1->rmconf->xauth->login->v);
14520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				vfree(usr);
14530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				return NULL;
14540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			/* We have to free it before returning */
14560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			freepwd = 1;
14570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(usr);
14590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		iph1->rmconf->xauth->state |= XAUTH_SENT_PASSWORD;
14610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		dlen = pwd->l;
14620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
14640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_MESSAGE:
14650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
14660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dlen = ntohs(attr->lorv);
14670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (dlen > 0) {
14680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				mraw = (char*)(attr + 1);
14691c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				mdata = binsanitize(mraw, dlen);
14701c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				if (mdata == NULL) {
14710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, iph1->remote,
14720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "Cannot allocate memory\n");
14730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return NULL;
14740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
14750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_NOTIFY,LOCATION, iph1->remote,
14760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"XAUTH Message: '%s'.\n",
14771c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh					mdata);
14781c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				racoon_free(mdata);
14790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
14800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
14810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
14830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
14840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
14850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
14860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
14870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buffer = vmalloc(sizeof(*attr) + dlen)) == NULL) {
14900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
14910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory\n");
14920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
14930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
14940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
14950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr = (struct isakmp_data *)buffer->v;
14960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (ashort) {
14970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attr->type = htons(type | ISAKMP_GEN_TV);
14980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		attr->lorv = htons(value);
14990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		goto out;
15000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->type = htons(type | ISAKMP_GEN_TLV);
15030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->lorv = htons(dlen);
15040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	data = (char *)(attr + 1);
15050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(type) {
15070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_NAME:
15080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * iph1->rmconf->xauth->login->v is valid,
15100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * we just checked it in the previous switch case
15110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(data, iph1->rmconf->xauth->login->v, dlen);
15130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
1514d30604685e6cc1fa878806ae590dcd1fc9d43f91Chia-chi Yeh#ifdef ANDROID_PATCHED
1515c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh        case XAUTH_PASSCODE:
1516c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh#endif
15170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_USER_PASSWORD:
15180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		memcpy(data, pwd->v, dlen);
15190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
15200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
15210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
15220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout:
15250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (freepwd)
15260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		vfree(pwd);
15270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buffer;
15290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
15300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t *
15320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_xauth_set(iph1, attr)
15330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct ph1handle *iph1;
15340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct isakmp_data *attr;
15350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
15360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	int type;
15370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	vchar_t *buffer = NULL;
15380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	char *data;
15390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst;
15400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	size_t dlen = 0;
15411c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh	char* mraw = NULL, *mdata;
15420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) {
15440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
15450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Xauth mode config set but peer "
15460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "did not declare itself as Xauth capable\n");
15470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
15480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
15490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
15510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch(type) {
15530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_STATUS:
15540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/*
15550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * We should only receive ISAKMP mode_cfg SET XAUTH_STATUS
15560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 * when running as a client (initiator).
15570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		 */
15580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		xst = &iph1->mode_cfg->xauth;
1559c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		switch(AUTHMETHOD(iph1)) {
15600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
1561c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh		case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
15620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
15630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* Not implemented ... */
15640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
15650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
15660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
15670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
15680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
15690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		default:
15700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
15710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Unexpected XAUTH_STATUS_OK\n");
15720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return NULL;
15730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			break;
15740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* If we got a failure, delete iph1 */
15770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (ntohs(attr->lorv) != XAUTH_STATUS_OK) {
15780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
15790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "Xauth authentication failed\n");
15800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
1581c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			EVT_PUSH(iph1->local, iph1->remote,
1582c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    EVTT_XAUTH_FAILED, NULL);
15830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			iph1->mode_cfg->flags |= ISAKMP_CFG_DELETE_PH1;
15850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		} else {
1586c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			EVT_PUSH(iph1->local, iph1->remote,
1587c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh			    EVTT_XAUTH_SUCCESS, NULL);
15880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
15890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
15910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		/* We acknowledge it */
15920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
15930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_MESSAGE:
15940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((ntohs(attr->type) & ISAKMP_GEN_TV) == 0) {
15950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			dlen = ntohs(attr->lorv);
15960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			if (dlen > 0) {
15970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				mraw = (char*)(attr + 1);
15981c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				mdata = binsanitize(mraw, dlen);
15991c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				if (mdata == NULL) {
16000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					plog(LLV_ERROR, LOCATION, iph1->remote,
16010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					    "Cannot allocate memory\n");
16020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					return NULL;
16030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				}
16040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang				plog(LLV_NOTIFY,LOCATION, iph1->remote,
16050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang					"XAUTH Message: '%s'.\n",
16061c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh					mdata);
16071c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh				racoon_free(mdata);
16080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			}
16090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
16120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
16130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Ignored attribute %s\n", s_isakmp_cfg_type(type));
16140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
16190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_ERROR, LOCATION, NULL,
16200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Cannot allocate memory\n");
16210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		return NULL;
16220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr = (struct isakmp_data *)buffer->v;
16250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->type = htons(type | ISAKMP_GEN_TV);
16260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	attr->lorv = htons(0);
16270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return buffer;
16290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
16330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_rmstate(xst)
16340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_state *xst;
16350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	switch (xst->authtype) {
16370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE_GENERIC:
16380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (xst->authdata.generic.usr)
16390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(xst->authdata.generic.usr);
16400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (xst->authdata.generic.pwd)
16420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			racoon_free(xst->authdata.generic.pwd);
16430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE_CHAP:
16470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE_OTP:
16480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	case XAUTH_TYPE_SKEY:
16490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
16500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Unsupported authtype %d\n", xst->authtype);
16510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	default:
16540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		plog(LLV_WARNING, LOCATION, NULL,
16550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		    "Unexpected authtype %d\n", xst->authtype);
16560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		break;
16570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_LIBLDAP
16600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (xst->udn != NULL)
16610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(xst->udn);
16620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif
16630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
16640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint
16670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_rmconf_used(xauth_rmconf)
16680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_rmconf **xauth_rmconf;
16690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*xauth_rmconf == NULL) {
16710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*xauth_rmconf = racoon_malloc(sizeof(**xauth_rmconf));
16720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if (*xauth_rmconf == NULL) {
16730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			plog(LLV_ERROR, LOCATION, NULL,
16740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			    "xauth_rmconf_used: malloc failed\n");
16750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			return -1;
16760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		}
16770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(*xauth_rmconf)->login = NULL;
16790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(*xauth_rmconf)->pass = NULL;
16800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		(*xauth_rmconf)->state = 0;
16810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return 0;
16840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
16850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvoid
16870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangxauth_rmconf_delete(xauth_rmconf)
16880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	struct xauth_rmconf **xauth_rmconf;
16890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{
16900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	if (*xauth_rmconf != NULL) {
16910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*xauth_rmconf)->login != NULL)
16920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree((*xauth_rmconf)->login);
16930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		if ((*xauth_rmconf)->pass != NULL)
16940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang			vfree((*xauth_rmconf)->pass);
16950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
16960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		racoon_free(*xauth_rmconf);
16970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang		*xauth_rmconf = NULL;
16980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	}
16990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang
17000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang	return;
17010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang}
1702