File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / isakmp_cfg.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /*	$NetBSD: isakmp_cfg.c,v 1.24 2010/09/21 13:14:17 vanhu Exp $	*/
    2: 
    3: /* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
    4: 
    5: /*
    6:  * Copyright (C) 2004-2006 Emmanuel Dreyfus
    7:  * All rights reserved.
    8:  * 
    9:  * Redistribution and use in source and binary forms, with or without
   10:  * modification, are permitted provided that the following conditions
   11:  * are met:
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer.
   14:  * 2. Redistributions in binary form must reproduce the above copyright
   15:  *    notice, this list of conditions and the following disclaimer in the
   16:  *    documentation and/or other materials provided with the distribution.
   17:  * 3. Neither the name of the project nor the names of its contributors
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  * 
   21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  */
   33: 
   34: #include "config.h"
   35: 
   36: #include <sys/types.h>
   37: #include <sys/param.h>
   38: #include <sys/socket.h>
   39: #include <sys/queue.h>
   40: 
   41: #include <utmpx.h>
   42: #if defined(__APPLE__) && defined(__MACH__)
   43: #include <util.h>
   44: #endif
   45: 
   46: #ifdef __FreeBSD__
   47: # include <libutil.h>
   48: #endif
   49: #ifdef __NetBSD__
   50: #  include <util.h>
   51: #endif
   52: 
   53: #include <netinet/in.h>
   54: #include <arpa/inet.h>
   55: 
   56: #include <stdlib.h>
   57: #include <stdio.h>
   58: #include <string.h>
   59: #include <errno.h>
   60: #if TIME_WITH_SYS_TIME
   61: # include <sys/time.h>
   62: # include <time.h>
   63: #else
   64: # if HAVE_SYS_TIME_H
   65: #  include <sys/time.h>
   66: # else
   67: #  include <time.h>
   68: # endif
   69: #endif
   70: #include <netdb.h>
   71: #ifdef HAVE_UNISTD_H
   72: #include <unistd.h>
   73: #endif
   74: #if HAVE_STDINT_H
   75: #include <stdint.h>
   76: #endif
   77: #include <ctype.h>
   78: #include <resolv.h>
   79: 
   80: #ifdef HAVE_LIBRADIUS
   81: #include <sys/utsname.h>
   82: #include <radlib.h>
   83: #endif
   84: 
   85: #include "var.h"
   86: #include "misc.h"
   87: #include "vmbuf.h"
   88: #include "plog.h"
   89: #include "sockmisc.h"
   90: #include "schedule.h"
   91: #include "debug.h"
   92: 
   93: #include "isakmp_var.h"
   94: #include "isakmp.h"
   95: #include "handler.h"
   96: #include "evt.h"
   97: #include "throttle.h"
   98: #include "remoteconf.h"
   99: #include "crypto_openssl.h"
  100: #include "isakmp_inf.h"
  101: #include "isakmp_xauth.h"
  102: #include "isakmp_unity.h"
  103: #include "isakmp_cfg.h"
  104: #include "strnames.h"
  105: #include "admin.h"
  106: #include "privsep.h"
  107: 
  108: struct isakmp_cfg_config isakmp_cfg_config;
  109: 
  110: static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
  111: static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
  112: #if 0
  113: static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
  114: #endif
  115: static vchar_t *isakmp_cfg_addr4(struct ph1handle *, 
  116: 				 struct isakmp_data *, in_addr_t *);
  117: static vchar_t *isakmp_cfg_addrnet4(struct ph1handle *, 
  118: 				 struct isakmp_data *, in_addr_t *, in_addr_t *);
  119: static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
  120: static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
  121: 				      struct isakmp_data *, in_addr_t *, int);
  122: static void isakmp_cfg_appendaddr4(struct isakmp_data *, 
  123: 				   struct in_addr *, int *, int);
  124: static void isakmp_cfg_getstring(struct isakmp_data *,char *);
  125: void isakmp_cfg_iplist_to_str(char *, int, void *, int);
  126: 
  127: #define ISAKMP_CFG_LOGIN	1
  128: #define ISAKMP_CFG_LOGOUT	2
  129: static int isakmp_cfg_accounting(struct ph1handle *, int);
  130: #ifdef HAVE_LIBRADIUS
  131: static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
  132: #endif
  133: 
  134: /* 
  135:  * Handle an ISAKMP config mode packet
  136:  * We expect HDR, HASH, ATTR
  137:  */
  138: void
  139: isakmp_cfg_r(iph1, msg)
  140: 	struct ph1handle *iph1;
  141: 	vchar_t *msg;
  142: {
  143: 	struct isakmp *packet;
  144: 	struct isakmp_gen *ph;
  145: 	int tlen;
  146: 	char *npp;
  147: 	int np;
  148: 	vchar_t *dmsg;
  149: 	struct isakmp_ivm *ivm;
  150: 
  151: 	/* Check that the packet is long enough to have a header */
  152: 	if (msg->l < sizeof(*packet)) {
  153: 	     plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
  154: 	     return;
  155: 	}
  156: 
  157: 	packet = (struct isakmp *)msg->v;
  158: 
  159: 	/* Is it encrypted? It should be encrypted */
  160: 	if ((packet->flags & ISAKMP_FLAG_E) == 0) {
  161: 		plog(LLV_ERROR, LOCATION, NULL, 
  162: 		    "User credentials sent in cleartext!\n");
  163: 		return;
  164: 	}
  165: 
  166: 	/* 
  167: 	 * Decrypt the packet. If this is the beginning of a new
  168: 	 * exchange, reinitialize the IV
  169: 	 */
  170: 	if (iph1->mode_cfg->ivm == NULL ||
  171: 	    iph1->mode_cfg->last_msgid != packet->msgid )
  172: 		iph1->mode_cfg->ivm = 
  173: 		    isakmp_cfg_newiv(iph1, packet->msgid);
  174: 	ivm = iph1->mode_cfg->ivm;
  175: 
  176: 	dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
  177: 	if (dmsg == NULL) {
  178: 		plog(LLV_ERROR, LOCATION, NULL, 
  179: 		    "failed to decrypt message\n");
  180: 		return;
  181: 	}
  182: 
  183: 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
  184: 	plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
  185: 
  186: 	/* Now work with the decrypted packet */
  187: 	packet = (struct isakmp *)dmsg->v;
  188: 	tlen = dmsg->l - sizeof(*packet);
  189: 	ph = (struct isakmp_gen *)(packet + 1);
  190: 
  191: 	np = packet->np;
  192: 	while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
  193: 		/* Check that the payload header fits in the packet */
  194: 		if (tlen < sizeof(*ph)) {
  195: 			 plog(LLV_WARNING, LOCATION, NULL, 
  196: 			      "Short payload header\n");
  197: 			 goto out;
  198: 		}
  199: 
  200: 		/* Check that the payload fits in the packet */
  201: 		if (tlen < ntohs(ph->len)) {
  202: 			plog(LLV_WARNING, LOCATION, NULL, 
  203: 			      "Short payload\n");
  204: 			goto out;
  205: 		}
  206: 		
  207: 		plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
  208: 		plogdump(LLV_DEBUG, ph, ntohs(ph->len));
  209: 
  210: 		switch(np) {
  211: 		case ISAKMP_NPTYPE_HASH: {
  212: 			vchar_t *check;
  213: 			vchar_t *payload;
  214: 			size_t plen;
  215: 			struct isakmp_gen *nph;
  216: 
  217: 			plen = ntohs(ph->len);
  218: 			nph = (struct isakmp_gen *)((char *)ph + plen);
  219: 			plen = ntohs(nph->len);
  220: 
  221: 			if ((payload = vmalloc(plen)) == NULL) {
  222: 				plog(LLV_ERROR, LOCATION, NULL, 
  223: 				    "Cannot allocate memory\n");
  224: 				goto out;
  225: 			}
  226: 			memcpy(payload->v, nph, plen);
  227: 
  228: 			if ((check = oakley_compute_hash1(iph1, 
  229: 			    packet->msgid, payload)) == NULL) {
  230: 				plog(LLV_ERROR, LOCATION, NULL, 
  231: 				    "Cannot compute hash\n");
  232: 				vfree(payload);
  233: 				goto out;
  234: 			}
  235: 
  236: 			if (memcmp(ph + 1, check->v, check->l) != 0) {
  237: 				plog(LLV_ERROR, LOCATION, NULL, 
  238: 				    "Hash verification failed\n");
  239: 				vfree(payload);
  240: 				vfree(check);
  241: 				goto out;
  242: 			}
  243: 			vfree(payload);
  244: 			vfree(check);
  245: 			break;
  246: 		}
  247: 		case ISAKMP_NPTYPE_ATTR: {
  248: 			struct isakmp_pl_attr *attrpl;
  249: 
  250: 			attrpl = (struct isakmp_pl_attr *)ph;
  251: 			isakmp_cfg_attr_r(iph1, packet->msgid, attrpl);
  252: 
  253: 			break;
  254: 		}
  255: 		default:
  256: 			 plog(LLV_WARNING, LOCATION, NULL, 
  257: 			      "Unexpected next payload %d\n", np);
  258: 			 /* Skip to the next payload */
  259: 			 break;
  260: 		}
  261: 
  262: 		/* Move to the next payload */
  263: 		np = ph->np;
  264: 		tlen -= ntohs(ph->len);
  265: 		npp = (char *)ph;
  266: 		ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
  267: 	}
  268: 
  269: out:
  270: 	vfree(dmsg);
  271: }
  272: 
  273: int
  274: isakmp_cfg_attr_r(iph1, msgid, attrpl) 
  275: 	struct ph1handle *iph1;
  276: 	u_int32_t msgid;
  277: 	struct isakmp_pl_attr *attrpl;
  278: {
  279: 	int type = attrpl->type;
  280: 
  281: 	plog(LLV_DEBUG, LOCATION, NULL,
  282: 	     "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
  283: 	switch (type) {
  284: 	case ISAKMP_CFG_ACK:
  285: 		/* ignore, but this is the time to reinit the IV */
  286: 		oakley_delivm(iph1->mode_cfg->ivm);
  287: 		iph1->mode_cfg->ivm = NULL;
  288: 		return 0;
  289: 		break;
  290: 
  291: 	case ISAKMP_CFG_REPLY:
  292: 		return isakmp_cfg_reply(iph1, attrpl);
  293: 		break;
  294: 
  295: 	case ISAKMP_CFG_REQUEST:
  296: 		iph1->msgid = msgid;
  297: 		return isakmp_cfg_request(iph1, attrpl);
  298: 		break;
  299: 
  300: 	case ISAKMP_CFG_SET:
  301: 		iph1->msgid = msgid;
  302: 		return isakmp_cfg_set(iph1, attrpl);
  303: 		break;
  304: 
  305: 	default:
  306: 		plog(LLV_WARNING, LOCATION, NULL,
  307: 		     "Unepected configuration exchange type %d\n", type);
  308: 		return -1;
  309: 		break;
  310: 	}
  311: 
  312: 	return 0;
  313: }
  314: 
  315: int
  316: isakmp_cfg_reply(iph1, attrpl)
  317: 	struct ph1handle *iph1;
  318: 	struct isakmp_pl_attr *attrpl;
  319: {
  320: 	struct isakmp_data *attr;
  321: 	int tlen;
  322: 	size_t alen;
  323: 	char *npp;
  324: 	int type;
  325: 	struct sockaddr_in *sin;
  326: 	int error;
  327: 
  328: 	tlen = ntohs(attrpl->h.len);
  329: 	attr = (struct isakmp_data *)(attrpl + 1);
  330: 	tlen -= sizeof(*attrpl);
  331: 	
  332: 	while (tlen > 0) {
  333: 		type = ntohs(attr->type);
  334: 
  335: 		/* Handle short attributes */
  336: 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
  337: 			type &= ~ISAKMP_GEN_MASK;
  338: 
  339: 			plog(LLV_DEBUG, LOCATION, NULL,
  340: 			     "Short attribute %s = %d\n", 
  341: 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
  342: 
  343: 			switch (type) {
  344: 			case XAUTH_TYPE:
  345: 				if ((error = xauth_attr_reply(iph1, 
  346: 				    attr, ntohs(attrpl->id))) != 0)
  347: 					return error;
  348: 				break;
  349: 
  350: 			default:
  351: 				plog(LLV_WARNING, LOCATION, NULL,
  352: 				     "Ignored short attribute %s\n",
  353: 				     s_isakmp_cfg_type(type));
  354: 				break;
  355: 			}
  356: 
  357: 			tlen -= sizeof(*attr);
  358: 			attr++;
  359: 			continue;
  360: 		}
  361: 
  362: 		type = ntohs(attr->type);
  363: 		alen = ntohs(attr->lorv);
  364: 
  365: 		/* Check that the attribute fit in the packet */
  366: 		if (tlen < alen) {
  367: 			plog(LLV_ERROR, LOCATION, NULL,
  368: 			     "Short attribute %s\n",
  369: 			     s_isakmp_cfg_type(type));
  370: 			return -1;
  371: 		}
  372: 
  373: 		plog(LLV_DEBUG, LOCATION, NULL,
  374: 		     "Attribute %s, len %zu\n", 
  375: 		     s_isakmp_cfg_type(type), alen);
  376: 
  377: 		switch(type) {
  378: 		case XAUTH_TYPE:
  379: 		case XAUTH_USER_NAME:
  380: 		case XAUTH_USER_PASSWORD:
  381: 		case XAUTH_PASSCODE:
  382: 		case XAUTH_MESSAGE:
  383: 		case XAUTH_CHALLENGE:
  384: 		case XAUTH_DOMAIN:
  385: 		case XAUTH_STATUS:
  386: 		case XAUTH_NEXT_PIN:
  387: 		case XAUTH_ANSWER:
  388: 			if ((error = xauth_attr_reply(iph1, 
  389: 			    attr, ntohs(attrpl->id))) != 0)
  390: 				return error;
  391: 			break;
  392: 		case INTERNAL_IP4_ADDRESS:
  393: 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
  394: 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
  395: 			break;
  396: 		case INTERNAL_IP4_NETMASK:
  397: 			isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
  398: 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
  399: 			break;
  400: 		case INTERNAL_IP4_DNS:
  401: 			isakmp_cfg_appendaddr4(attr, 
  402: 			    &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
  403: 			    &iph1->mode_cfg->dns4_index, MAXNS);
  404: 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
  405: 			break;
  406: 		case INTERNAL_IP4_NBNS:
  407: 			isakmp_cfg_appendaddr4(attr, 
  408: 			    &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
  409: 			    &iph1->mode_cfg->wins4_index, MAXNS);
  410: 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
  411: 			break;
  412: 		case UNITY_DEF_DOMAIN:
  413: 			isakmp_cfg_getstring(attr, 
  414: 			    iph1->mode_cfg->default_domain);
  415: 			iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
  416: 			break;
  417: 		case UNITY_SPLIT_INCLUDE:
  418: 		case UNITY_LOCAL_LAN:
  419: 		case UNITY_SPLITDNS_NAME:
  420: 		case UNITY_BANNER:
  421: 		case UNITY_SAVE_PASSWD:
  422: 		case UNITY_NATT_PORT:
  423: 		case UNITY_PFS:
  424: 		case UNITY_FW_TYPE:
  425: 		case UNITY_BACKUP_SERVERS:
  426: 		case UNITY_DDNS_HOSTNAME:
  427: 			isakmp_unity_reply(iph1, attr);
  428: 			break;
  429: 		case INTERNAL_IP4_SUBNET:
  430: 		case INTERNAL_ADDRESS_EXPIRY:
  431: 		default:
  432: 			plog(LLV_WARNING, LOCATION, NULL,
  433: 			     "Ignored attribute %s\n",
  434: 			     s_isakmp_cfg_type(type));
  435: 			break;
  436: 		}
  437: 
  438: 		npp = (char *)attr;
  439: 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
  440: 		tlen -= (sizeof(*attr) + alen);
  441: 	}
  442: 
  443: 	/* 
  444: 	 * Call the SA up script hook now that we have the configuration
  445: 	 * It is done at the end of phase 1 if ISAKMP mode config is not
  446: 	 * requested.
  447: 	 */
  448: 	
  449: 	if ((iph1->status == PHASE1ST_ESTABLISHED) && 
  450: 	    iph1->rmconf->mode_cfg) {
  451: 		switch (iph1->approval->authmethod) {
  452: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
  453: 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
  454: 		/* Unimplemented */
  455: 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I: 
  456: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I: 
  457: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
  458: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 
  459: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 
  460: 			script_hook(iph1, SCRIPT_PHASE1_UP);
  461: 			break;
  462: 		default:
  463: 			break;
  464: 		}
  465: 	}
  466: 		
  467: 
  468: #ifdef ENABLE_ADMINPORT
  469: 	{
  470: 		vchar_t *buf;
  471: 
  472: 		alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
  473: 		if ((buf = vmalloc(alen)) == NULL) {
  474: 			plog(LLV_WARNING, LOCATION, NULL, 
  475: 			    "Cannot allocate memory: %s\n", strerror(errno));
  476: 		} else {
  477: 			memcpy(buf->v, attrpl + 1, buf->l);
  478: 			evt_phase1(iph1, EVT_PHASE1_MODE_CFG, buf);
  479: 			vfree(buf);
  480: 		}
  481: 	}
  482: #endif
  483: 
  484: 	return 0;
  485: }
  486: 
  487: int
  488: isakmp_cfg_request(iph1, attrpl)
  489: 	struct ph1handle *iph1;
  490: 	struct isakmp_pl_attr *attrpl;
  491: {
  492: 	struct isakmp_data *attr;
  493: 	int tlen;
  494: 	size_t alen;
  495: 	char *npp;
  496: 	vchar_t *payload;
  497: 	struct isakmp_pl_attr *reply;
  498: 	vchar_t *reply_attr;
  499: 	int type;
  500: 	int error = -1;
  501: 
  502: 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
  503: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  504: 		return -1;
  505: 	}
  506: 	memset(payload->v, 0, sizeof(*reply));
  507: 
  508: 	tlen = ntohs(attrpl->h.len);
  509: 	attr = (struct isakmp_data *)(attrpl + 1);
  510: 	tlen -= sizeof(*attrpl);
  511: 	
  512: 	while (tlen > 0) {
  513: 		reply_attr = NULL;
  514: 		type = ntohs(attr->type);
  515: 
  516: 		/* Handle short attributes */
  517: 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
  518: 			type &= ~ISAKMP_GEN_MASK;
  519: 
  520: 			plog(LLV_DEBUG, LOCATION, NULL,
  521: 			     "Short attribute %s = %d\n", 
  522: 			     s_isakmp_cfg_type(type), ntohs(attr->lorv));
  523: 
  524: 			switch (type) {
  525: 			case XAUTH_TYPE:
  526: 				reply_attr = isakmp_xauth_req(iph1, attr);
  527: 				break;
  528: 			default:
  529: 				plog(LLV_WARNING, LOCATION, NULL,
  530: 				     "Ignored short attribute %s\n",
  531: 				     s_isakmp_cfg_type(type));
  532: 				break;
  533: 			}
  534: 
  535: 			tlen -= sizeof(*attr);
  536: 			attr++;
  537: 
  538: 			if (reply_attr != NULL) {
  539: 				payload = buffer_cat(payload, reply_attr);
  540: 				vfree(reply_attr);
  541: 			}
  542: 
  543: 			continue;
  544: 		}
  545: 
  546: 		type = ntohs(attr->type);
  547: 		alen = ntohs(attr->lorv);
  548: 
  549: 		/* Check that the attribute fit in the packet */
  550: 		if (tlen < alen) {
  551: 			plog(LLV_ERROR, LOCATION, NULL,
  552: 			     "Short attribute %s\n",
  553: 			     s_isakmp_cfg_type(type));
  554: 			goto end;
  555: 		}
  556: 
  557: 		plog(LLV_DEBUG, LOCATION, NULL,
  558: 		     "Attribute %s, len %zu\n",
  559: 		     s_isakmp_cfg_type(type), alen);
  560: 
  561: 		switch(type) {
  562: 		case INTERNAL_IP4_ADDRESS:
  563: 		case INTERNAL_IP4_NETMASK:
  564: 		case INTERNAL_IP4_DNS:
  565: 		case INTERNAL_IP4_NBNS:
  566: 		case INTERNAL_IP4_SUBNET:
  567: 			reply_attr = isakmp_cfg_net(iph1, attr);
  568: 			break;
  569: 
  570: 		case XAUTH_TYPE:
  571: 		case XAUTH_USER_NAME:
  572: 		case XAUTH_USER_PASSWORD:
  573: 		case XAUTH_PASSCODE:
  574: 		case XAUTH_MESSAGE:
  575: 		case XAUTH_CHALLENGE:
  576: 		case XAUTH_DOMAIN:
  577: 		case XAUTH_STATUS:
  578: 		case XAUTH_NEXT_PIN:
  579: 		case XAUTH_ANSWER:
  580: 			reply_attr = isakmp_xauth_req(iph1, attr);
  581: 			break;
  582: 
  583: 		case APPLICATION_VERSION:
  584: 			reply_attr = isakmp_cfg_string(iph1, 
  585: 			    attr, ISAKMP_CFG_RACOON_VERSION);
  586: 			break;
  587: 
  588: 		case UNITY_BANNER:
  589: 		case UNITY_PFS:
  590: 		case UNITY_SAVE_PASSWD:
  591: 		case UNITY_DEF_DOMAIN:
  592: 		case UNITY_DDNS_HOSTNAME:
  593: 		case UNITY_FW_TYPE:
  594: 		case UNITY_SPLITDNS_NAME:
  595: 		case UNITY_SPLIT_INCLUDE:
  596: 		case UNITY_LOCAL_LAN:
  597: 		case UNITY_NATT_PORT:
  598: 		case UNITY_BACKUP_SERVERS:
  599: 			reply_attr = isakmp_unity_req(iph1, attr);
  600: 			break;
  601: 
  602: 		case INTERNAL_ADDRESS_EXPIRY:
  603: 		default:
  604: 			plog(LLV_WARNING, LOCATION, NULL,
  605: 			     "Ignored attribute %s\n",
  606: 			     s_isakmp_cfg_type(type));
  607: 			break;
  608: 		}
  609: 
  610: 		npp = (char *)attr;
  611: 		attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
  612: 		tlen -= (sizeof(*attr) + alen);
  613: 
  614: 		if (reply_attr != NULL) {
  615: 			payload = buffer_cat(payload, reply_attr);
  616: 			vfree(reply_attr);
  617: 		}
  618: 
  619: 	}
  620: 
  621: 	reply = (struct isakmp_pl_attr *)payload->v;
  622: 	reply->h.len = htons(payload->l);
  623: 	reply->type = ISAKMP_CFG_REPLY;
  624: 	reply->id = attrpl->id;
  625: 
  626: 	plog(LLV_DEBUG, LOCATION, NULL, 
  627: 		    "Sending MODE_CFG REPLY\n");
  628: 
  629: 	error = isakmp_cfg_send(iph1, payload, 
  630: 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
  631: 
  632: 	if (iph1->status == PHASE1ST_ESTABLISHED) {
  633: 		switch (iph1->approval->authmethod) {
  634: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
  635: 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
  636: 		/* Unimplemented */
  637: 		case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R: 
  638: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R: 
  639: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
  640: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 
  641: 		case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 
  642: 			script_hook(iph1, SCRIPT_PHASE1_UP);
  643: 			break;
  644: 		default:
  645: 			break;
  646: 		}
  647: 	}
  648: 	
  649: end:
  650: 	vfree(payload);
  651: 
  652: 	return error;
  653: }
  654: 
  655: int
  656: isakmp_cfg_set(iph1, attrpl)
  657: 	struct ph1handle *iph1;
  658: 	struct isakmp_pl_attr *attrpl;
  659: {
  660: 	struct isakmp_data *attr;
  661: 	int tlen;
  662: 	size_t alen;
  663: 	char *npp;
  664: 	vchar_t *payload;
  665: 	struct isakmp_pl_attr *reply;
  666: 	vchar_t *reply_attr;
  667: 	int type;
  668: 	int error = -1;
  669: 
  670: 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
  671: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  672: 		return -1;
  673: 	}
  674: 	memset(payload->v, 0, sizeof(*reply));
  675: 
  676: 	tlen = ntohs(attrpl->h.len);
  677: 	attr = (struct isakmp_data *)(attrpl + 1);
  678: 	tlen -= sizeof(*attrpl);
  679: 	
  680: 	/* 
  681: 	 * We should send ack for the attributes we accepted 
  682: 	 */
  683: 	while (tlen > 0) {
  684: 		reply_attr = NULL;
  685: 		type = ntohs(attr->type);
  686: 
  687: 		plog(LLV_DEBUG, LOCATION, NULL,
  688: 		     "Attribute %s\n", 
  689: 		     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
  690: 		
  691: 		switch (type & ~ISAKMP_GEN_MASK) {
  692: 		case XAUTH_STATUS:
  693: 			reply_attr = isakmp_xauth_set(iph1, attr);
  694: 			break;
  695: 		default:
  696: 			plog(LLV_DEBUG, LOCATION, NULL,
  697: 			     "Unexpected SET attribute %s\n", 
  698: 		     	     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
  699: 			break;
  700: 		}
  701: 
  702: 		if (reply_attr != NULL) {
  703: 			payload = buffer_cat(payload, reply_attr);
  704: 			vfree(reply_attr);
  705: 		}
  706: 
  707: 		/* 
  708: 		 * Move to next attribute. If we run out of the packet, 
  709: 		 * tlen becomes negative and we exit. 
  710: 		 */
  711: 		if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
  712: 			tlen -= sizeof(*attr);
  713: 			attr++;
  714: 		} else {
  715: 			alen = ntohs(attr->lorv);
  716: 			tlen -= (sizeof(*attr) + alen);
  717: 			npp = (char *)attr;
  718: 			attr = (struct isakmp_data *)
  719: 			    (npp + sizeof(*attr) + alen);
  720: 		}
  721: 	}
  722: 
  723: 	reply = (struct isakmp_pl_attr *)payload->v;
  724: 	reply->h.len = htons(payload->l);
  725: 	reply->type = ISAKMP_CFG_ACK;
  726: 	reply->id = attrpl->id;
  727: 
  728: 	plog(LLV_DEBUG, LOCATION, NULL,
  729: 		     "Sending MODE_CFG ACK\n");
  730: 
  731: 	error = isakmp_cfg_send(iph1, payload, 
  732: 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0);
  733: 
  734: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
  735: 		if (iph1->status == PHASE1ST_ESTABLISHED ||
  736: 		    iph1->status == PHASE1ST_DYING)
  737: 			isakmp_info_send_d1(iph1);
  738: 		remph1(iph1);
  739: 		delph1(iph1);
  740: 		iph1 = NULL;
  741: 	}
  742: end:
  743: 	vfree(payload);
  744: 
  745: 	/* 
  746: 	 * If required, request ISAKMP mode config information
  747: 	 */
  748: 	if ((iph1 != NULL) && (iph1->rmconf->mode_cfg) && (error == 0))
  749: 		error = isakmp_cfg_getconfig(iph1);
  750: 
  751: 	return error;
  752: }
  753: 
  754: 
  755: static vchar_t *
  756: buffer_cat(s, append)
  757: 	vchar_t *s;
  758: 	vchar_t *append;
  759: {
  760: 	vchar_t *new;
  761: 
  762: 	new = vmalloc(s->l + append->l);
  763: 	if (new == NULL) {
  764: 		plog(LLV_ERROR, LOCATION, NULL, 
  765: 		    "Cannot allocate memory\n");
  766: 		return s;
  767: 	}
  768: 
  769: 	memcpy(new->v, s->v, s->l);
  770: 	memcpy(new->v + s->l, append->v, append->l);
  771: 
  772: 	vfree(s);
  773: 	return new;
  774: }
  775: 
  776: static vchar_t *
  777: isakmp_cfg_net(iph1, attr)
  778: 	struct ph1handle *iph1;
  779: 	struct isakmp_data *attr;
  780: {
  781: 	int type;
  782: 	int confsource;
  783: 	in_addr_t addr4;
  784: 
  785: 	type = ntohs(attr->type);
  786: 
  787: 	/* 
  788: 	 * Don't give an address to a peer that did not succeed Xauth
  789: 	 */
  790: 	if (xauth_check(iph1) != 0) {
  791: 		plog(LLV_ERROR, LOCATION, NULL,
  792: 		    "Attempt to start phase config whereas Xauth failed\n");
  793: 		return NULL;
  794: 	}
  795: 
  796: 	confsource = isakmp_cfg_config.confsource;
  797: 	/*
  798: 	 * If we have to fall back to a local
  799: 	 * configuration source, we will jump
  800: 	 * back to this point.
  801: 	 */
  802: retry_source:
  803: 
  804: 	switch(type) {
  805: 	case INTERNAL_IP4_ADDRESS:
  806: 		switch(confsource) {
  807: #ifdef HAVE_LIBLDAP
  808: 		case ISAKMP_CFG_CONF_LDAP:
  809: 			if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
  810: 			    break;
  811: 			plog(LLV_INFO, LOCATION, NULL, 
  812: 			    "No IP from LDAP, using local pool\n");
  813: 			/* FALLTHROUGH */
  814: 			confsource = ISAKMP_CFG_CONF_LOCAL;
  815: 			goto retry_source;
  816: #endif
  817: #ifdef HAVE_LIBRADIUS
  818: 		case ISAKMP_CFG_CONF_RADIUS:
  819: 			if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
  820: 			    && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
  821: 			    /*
  822: 			     * -2 is 255.255.255.254, RADIUS uses that
  823: 			     * to instruct the NAS to use a local pool
  824: 			     */
  825: 			    break;
  826: 			plog(LLV_INFO, LOCATION, NULL, 
  827: 			    "No IP from RADIUS, using local pool\n");
  828: 			/* FALLTHROUGH */
  829: 			confsource = ISAKMP_CFG_CONF_LOCAL;
  830: 			goto retry_source;
  831: #endif
  832: 		case ISAKMP_CFG_CONF_LOCAL:
  833: 			if (isakmp_cfg_getport(iph1) == -1) {
  834: 				plog(LLV_ERROR, LOCATION, NULL, 
  835: 				    "Port pool depleted\n");
  836: 				break;
  837: 			}
  838: 
  839: 			iph1->mode_cfg->addr4.s_addr = 
  840: 			    htonl(ntohl(isakmp_cfg_config.network4) 
  841: 			    + iph1->mode_cfg->port);
  842: 			iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
  843: 			break;
  844: 
  845: 		default:
  846: 			plog(LLV_ERROR, LOCATION, NULL, 
  847: 			    "Unexpected confsource\n");
  848: 		}
  849: 			
  850: 		if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
  851: 			plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
  852: 
  853: 		return isakmp_cfg_addr4(iph1, 
  854: 		    attr, &iph1->mode_cfg->addr4.s_addr);
  855: 		break;
  856: 
  857: 	case INTERNAL_IP4_NETMASK:
  858: 		switch(confsource) {
  859: #ifdef HAVE_LIBLDAP
  860: 		case ISAKMP_CFG_CONF_LDAP:
  861: 			if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
  862: 				break;
  863: 			plog(LLV_INFO, LOCATION, NULL, 
  864: 			    "No mask from LDAP, using local pool\n");
  865: 			/* FALLTHROUGH */
  866: 			confsource = ISAKMP_CFG_CONF_LOCAL;
  867: 			goto retry_source;
  868: #endif
  869: #ifdef HAVE_LIBRADIUS
  870: 		case ISAKMP_CFG_CONF_RADIUS:
  871: 			if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
  872: 				break;
  873: 			plog(LLV_INFO, LOCATION, NULL, 
  874: 			    "No mask from RADIUS, using local pool\n");
  875: 			/* FALLTHROUGH */
  876: 			confsource = ISAKMP_CFG_CONF_LOCAL;
  877: 			goto retry_source;
  878: #endif
  879: 		case ISAKMP_CFG_CONF_LOCAL:
  880: 			iph1->mode_cfg->mask4.s_addr 
  881: 			    = isakmp_cfg_config.netmask4;
  882: 			iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
  883: 			break;
  884: 
  885: 		default:
  886: 			plog(LLV_ERROR, LOCATION, NULL, 
  887: 			    "Unexpected confsource\n");
  888: 		}
  889: 		return isakmp_cfg_addr4(iph1, attr, 
  890: 		    &iph1->mode_cfg->mask4.s_addr);
  891: 		break;
  892: 
  893: 	case INTERNAL_IP4_DNS:
  894: 		return isakmp_cfg_addr4_list(iph1, 
  895: 		    attr, &isakmp_cfg_config.dns4[0], 
  896: 		    isakmp_cfg_config.dns4_index);
  897: 		break;
  898: 
  899: 	case INTERNAL_IP4_NBNS:
  900: 		return isakmp_cfg_addr4_list(iph1, 
  901: 		    attr, &isakmp_cfg_config.nbns4[0], 
  902: 		    isakmp_cfg_config.nbns4_index);
  903: 		break;
  904: 
  905: 	case INTERNAL_IP4_SUBNET:
  906: 		if(isakmp_cfg_config.splitnet_count > 0){
  907: 			return isakmp_cfg_addrnet4(iph1, attr,
  908: 						    &isakmp_cfg_config.splitnet_list->network.addr4.s_addr,
  909: 						    &isakmp_cfg_config.splitnet_list->network.mask4.s_addr);
  910: 		}else{
  911: 			plog(LLV_INFO, LOCATION, NULL,
  912: 			     "%s requested but no splitnet in configuration\n",
  913: 			     s_isakmp_cfg_type(type));
  914: 		}
  915: 		break;
  916: 
  917: 	default:
  918: 		plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
  919: 		break;
  920: 	}
  921: 	return NULL;
  922: }
  923: 
  924: #if 0
  925: static vchar_t *
  926: isakmp_cfg_void(iph1, attr)
  927: 	struct ph1handle *iph1;
  928: 	struct isakmp_data *attr;
  929: {
  930: 	vchar_t *buffer;
  931: 	struct isakmp_data *new;
  932: 
  933: 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
  934: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  935: 		return NULL;
  936: 	}
  937: 
  938: 	new = (struct isakmp_data *)buffer->v;
  939: 
  940: 	new->type = attr->type;
  941: 	new->lorv = htons(0);
  942: 
  943: 	return buffer;
  944: }
  945: #endif
  946: 
  947: vchar_t *
  948: isakmp_cfg_copy(iph1, attr)
  949: 	struct ph1handle *iph1;
  950: 	struct isakmp_data *attr;
  951: {
  952: 	vchar_t *buffer;
  953: 	size_t len = 0;
  954: 
  955: 	if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
  956: 		len = ntohs(attr->lorv);
  957: 
  958: 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
  959: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  960: 		return NULL;
  961: 	}
  962: 
  963: 	memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
  964: 
  965: 	return buffer;
  966: }
  967: 
  968: vchar_t *
  969: isakmp_cfg_short(iph1, attr, value)
  970: 	struct ph1handle *iph1;
  971: 	struct isakmp_data *attr;
  972: 	int value;
  973: {
  974: 	vchar_t *buffer;
  975: 	struct isakmp_data *new;
  976: 	int type;
  977: 
  978: 	if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
  979: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  980: 		return NULL;
  981: 	}
  982: 
  983: 	new = (struct isakmp_data *)buffer->v;
  984: 	type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
  985: 
  986: 	new->type = htons(type | ISAKMP_GEN_TV);
  987: 	new->lorv = htons(value);
  988: 
  989: 	return buffer;
  990: }
  991: 
  992: vchar_t *
  993: isakmp_cfg_varlen(iph1, attr, string, len)
  994: 	struct ph1handle *iph1;
  995: 	struct isakmp_data *attr;
  996: 	char *string;
  997: 	size_t len;
  998: {
  999: 	vchar_t *buffer;
 1000: 	struct isakmp_data *new;
 1001: 	char *data;
 1002: 
 1003: 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
 1004: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
 1005: 		return NULL;
 1006: 	}
 1007: 
 1008: 	new = (struct isakmp_data *)buffer->v;
 1009: 
 1010: 	new->type = attr->type;
 1011: 	new->lorv = htons(len);
 1012: 	data = (char *)(new + 1);
 1013: 
 1014: 	memcpy(data, string, len);
 1015: 	
 1016: 	return buffer;
 1017: }
 1018: vchar_t *
 1019: isakmp_cfg_string(iph1, attr, string)
 1020: 	struct ph1handle *iph1;
 1021: 	struct isakmp_data *attr;
 1022: 	char *string;
 1023: {
 1024: 	size_t len = strlen(string);
 1025: 	return isakmp_cfg_varlen(iph1, attr, string, len);
 1026: }
 1027: 
 1028: static vchar_t *
 1029: isakmp_cfg_addr4(iph1, attr, addr)
 1030: 	struct ph1handle *iph1;
 1031: 	struct isakmp_data *attr;
 1032: 	in_addr_t *addr;
 1033: {
 1034: 	vchar_t *buffer;
 1035: 	struct isakmp_data *new;
 1036: 	size_t len;
 1037: 
 1038: 	len = sizeof(*addr);
 1039: 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
 1040: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
 1041: 		return NULL;
 1042: 	}
 1043: 
 1044: 	new = (struct isakmp_data *)buffer->v;
 1045: 
 1046: 	new->type = attr->type;
 1047: 	new->lorv = htons(len);
 1048: 	memcpy(new + 1, addr, len);
 1049: 	
 1050: 	return buffer;
 1051: }
 1052: 
 1053: static vchar_t *
 1054: isakmp_cfg_addrnet4(iph1, attr, addr, mask)
 1055: 	struct ph1handle *iph1;
 1056: 	struct isakmp_data *attr;
 1057: 	in_addr_t *addr;
 1058: 	in_addr_t *mask;
 1059: {
 1060: 	vchar_t *buffer;
 1061: 	struct isakmp_data *new;
 1062: 	size_t len;
 1063: 	in_addr_t netbuff[2];
 1064: 
 1065: 	len = sizeof(netbuff);
 1066: 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
 1067: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
 1068: 		return NULL;
 1069: 	}
 1070: 
 1071: 	new = (struct isakmp_data *)buffer->v;
 1072: 
 1073: 	new->type = attr->type;
 1074: 	new->lorv = htons(len);
 1075: 	netbuff[0]=*addr;
 1076: 	netbuff[1]=*mask;
 1077: 	memcpy(new + 1, netbuff, len);
 1078: 	
 1079: 	return buffer;
 1080: }
 1081: 
 1082: 
 1083: static vchar_t *
 1084: isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
 1085: 	struct ph1handle *iph1;
 1086: 	struct isakmp_data *attr;
 1087: 	in_addr_t *addr;
 1088: 	int nbr;
 1089: {
 1090: 	int error = -1;
 1091: 	vchar_t *buffer = NULL;
 1092: 	vchar_t *bufone = NULL;
 1093: 	struct isakmp_data *new;
 1094: 	size_t len;
 1095: 	int i;
 1096: 
 1097: 	len = sizeof(*addr);
 1098: 	if ((buffer = vmalloc(0)) == NULL) {
 1099: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
 1100: 		goto out;
 1101: 	}
 1102: 	for(i = 0; i < nbr; i++) {
 1103: 		if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
 1104: 			plog(LLV_ERROR, LOCATION, NULL, 
 1105: 			    "Cannot allocate memory\n");
 1106: 			goto out;
 1107: 		}
 1108: 		new = (struct isakmp_data *)bufone->v;
 1109: 		new->type = attr->type;
 1110: 		new->lorv = htons(len);
 1111: 		memcpy(new + 1, &addr[i], len);
 1112: 		new += (len + sizeof(*attr));
 1113: 		buffer = buffer_cat(buffer, bufone);
 1114: 		vfree(bufone);
 1115: 	}
 1116: 
 1117: 	error = 0;
 1118: 
 1119: out:
 1120: 	if ((error != 0) && (buffer != NULL)) {
 1121: 		vfree(buffer);
 1122: 		buffer = NULL;
 1123: 	}
 1124: 
 1125: 	return buffer;
 1126: }
 1127: 
 1128: struct isakmp_ivm *
 1129: isakmp_cfg_newiv(iph1, msgid)
 1130: 	struct ph1handle *iph1;
 1131: 	u_int32_t msgid;
 1132: {
 1133: 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
 1134: 
 1135: 	if (ics == NULL) {
 1136: 		plog(LLV_ERROR, LOCATION, NULL,
 1137: 		    "isakmp_cfg_newiv called without mode config state\n");
 1138: 		return NULL;
 1139: 	}
 1140: 
 1141: 	if (ics->ivm != NULL)
 1142: 		oakley_delivm(ics->ivm);
 1143: 
 1144: 	ics->ivm = oakley_newiv2(iph1, msgid);
 1145: 	ics->last_msgid = msgid;
 1146: 
 1147: 	return ics->ivm;
 1148: }
 1149: 
 1150: /* Derived from isakmp_info_send_common */
 1151: int
 1152: isakmp_cfg_send(iph1, payload, np, flags, new_exchange)
 1153: 	struct ph1handle *iph1;
 1154: 	vchar_t *payload;
 1155: 	u_int32_t np;
 1156: 	int flags;
 1157: 	int new_exchange;
 1158: {
 1159: 	struct ph2handle *iph2 = NULL;
 1160: 	vchar_t *hash = NULL;
 1161: 	struct isakmp *isakmp;
 1162: 	struct isakmp_gen *gen;
 1163: 	char *p;
 1164: 	int tlen;
 1165: 	int error = -1;
 1166: 	struct isakmp_cfg_state *ics = iph1->mode_cfg;
 1167: 
 1168: 	/* Check if phase 1 is established */
 1169: 	if ((iph1->status < PHASE1ST_ESTABLISHED) ||
 1170: 	    (iph1->local == NULL) ||
 1171: 	    (iph1->remote == NULL)) {
 1172: 		plog(LLV_ERROR, LOCATION, NULL, 
 1173: 		    "ISAKMP mode config exchange with immature phase 1\n");
 1174: 		goto end;
 1175: 	}
 1176: 
 1177: 	/* add new entry to isakmp status table */
 1178: 	iph2 = newph2();
 1179: 	if (iph2 == NULL)
 1180: 		goto end;
 1181: 
 1182: 	iph2->dst = dupsaddr(iph1->remote);
 1183: 	if (iph2->dst == NULL) {
 1184: 		delph2(iph2);
 1185: 		goto end;
 1186: 	}
 1187: 	iph2->src = dupsaddr(iph1->local);
 1188: 	if (iph2->src == NULL) {
 1189: 		delph2(iph2);
 1190: 		goto end;
 1191: 	}
 1192: 
 1193: 	iph2->side = INITIATOR;
 1194: 	iph2->status = PHASE2ST_START;
 1195: 
 1196: 	if (new_exchange)
 1197: 		iph2->msgid = isakmp_newmsgid2(iph1);
 1198: 	else
 1199: 		iph2->msgid = iph1->msgid;
 1200: 
 1201: 	/* get IV and HASH(1) if skeyid_a was generated. */
 1202: 	if (iph1->skeyid_a != NULL) {
 1203: 		if (new_exchange) {
 1204: 			if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
 1205: 				delph2(iph2);
 1206: 				goto end;
 1207: 			}
 1208: 		}
 1209: 
 1210: 		/* generate HASH(1) */
 1211: 		hash = oakley_compute_hash1(iph1, iph2->msgid, payload);
 1212: 		if (hash == NULL) {
 1213: 			delph2(iph2);
 1214: 			goto end;
 1215: 		}
 1216: 
 1217: 		/* initialized total buffer length */
 1218: 		tlen = hash->l;
 1219: 		tlen += sizeof(*gen);
 1220: 	} else {
 1221: 		/* IKE-SA is not established */
 1222: 		hash = NULL;
 1223: 
 1224: 		/* initialized total buffer length */
 1225: 		tlen = 0;
 1226: 	}
 1227: 	if ((flags & ISAKMP_FLAG_A) == 0)
 1228: 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
 1229: 	else
 1230: 		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
 1231: 
 1232: 	insph2(iph2);
 1233: 	bindph12(iph1, iph2);
 1234: 
 1235: 	tlen += sizeof(*isakmp) + payload->l;
 1236: 
 1237: 	/* create buffer for isakmp payload */
 1238: 	iph2->sendbuf = vmalloc(tlen);
 1239: 	if (iph2->sendbuf == NULL) { 
 1240: 		plog(LLV_ERROR, LOCATION, NULL,
 1241: 			"failed to get buffer to send.\n");
 1242: 		goto err;
 1243: 	}
 1244: 
 1245: 	/* create isakmp header */
 1246: 	isakmp = (struct isakmp *)iph2->sendbuf->v;
 1247: 	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
 1248: 	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
 1249: 	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
 1250: 	isakmp->v = iph1->version;
 1251: 	isakmp->etype = ISAKMP_ETYPE_CFG;
 1252: 	isakmp->flags = iph2->flags;
 1253: 	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
 1254: 	isakmp->len = htonl(tlen);
 1255: 	p = (char *)(isakmp + 1);
 1256: 
 1257: 	/* create HASH payload */
 1258: 	if (hash != NULL) {
 1259: 		gen = (struct isakmp_gen *)p;
 1260: 		gen->np = np & 0xff;
 1261: 		gen->len = htons(sizeof(*gen) + hash->l);
 1262: 		p += sizeof(*gen);
 1263: 		memcpy(p, hash->v, hash->l);
 1264: 		p += hash->l;
 1265: 	}
 1266: 
 1267: 	/* add payload */
 1268: 	memcpy(p, payload->v, payload->l);
 1269: 	p += payload->l;
 1270: 
 1271: #ifdef HAVE_PRINT_ISAKMP_C
 1272: 	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
 1273: #endif
 1274: 	
 1275: 	plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
 1276: 	plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
 1277: 
 1278: 	/* encoding */
 1279: 	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
 1280: 		vchar_t *tmp;
 1281: 
 1282: 		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, 
 1283: 			ics->ivm->ive, ics->ivm->iv);
 1284: 		VPTRINIT(iph2->sendbuf);
 1285: 		if (tmp == NULL)
 1286: 			goto err;
 1287: 		iph2->sendbuf = tmp;
 1288: 	}
 1289: 
 1290: 	/* HDR*, HASH(1), ATTR */
 1291: 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
 1292: 		VPTRINIT(iph2->sendbuf);
 1293: 		goto err;
 1294: 	}
 1295: 
 1296: 	plog(LLV_DEBUG, LOCATION, NULL,
 1297: 		"sendto mode config %s.\n", s_isakmp_nptype(np));
 1298: 
 1299: 	/*
 1300: 	 * XXX We might need to resend the message...
 1301: 	 */
 1302: 
 1303: 	error = 0;
 1304: 	VPTRINIT(iph2->sendbuf);
 1305: 
 1306: err:
 1307: 	if (iph2->sendbuf != NULL)
 1308: 		vfree(iph2->sendbuf);
 1309: 
 1310: 	remph2(iph2);
 1311: 	delph2(iph2);
 1312: end:
 1313: 	if (hash)
 1314: 		vfree(hash);
 1315: 	return error;
 1316: }
 1317: 
 1318: 
 1319: void 
 1320: isakmp_cfg_rmstate(iph1)
 1321: 	struct ph1handle *iph1;
 1322: {
 1323: 	struct isakmp_cfg_state *state = iph1->mode_cfg;
 1324: 
 1325: 	if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
 1326: 		plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
 1327: 
 1328: 	if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
 1329: 		isakmp_cfg_putport(iph1, state->port);	
 1330: 
 1331: 	/* Delete the IV if it's still there */
 1332: 	if(iph1->mode_cfg->ivm) {
 1333: 		oakley_delivm(iph1->mode_cfg->ivm);
 1334: 		iph1->mode_cfg->ivm = NULL;
 1335: 	}
 1336: 
 1337: 	/* Free any allocated splitnet lists */
 1338: 	if(iph1->mode_cfg->split_include != NULL)
 1339: 		splitnet_list_free(iph1->mode_cfg->split_include,
 1340: 			&iph1->mode_cfg->include_count);
 1341: 	if(iph1->mode_cfg->split_local != NULL)
 1342: 		splitnet_list_free(iph1->mode_cfg->split_local,
 1343: 			&iph1->mode_cfg->local_count);
 1344: 
 1345: 	xauth_rmstate(&state->xauth);
 1346: 
 1347: 	racoon_free(state);
 1348: 	iph1->mode_cfg = NULL;
 1349: 
 1350: 	return;
 1351: }
 1352: 
 1353: struct isakmp_cfg_state *
 1354: isakmp_cfg_mkstate(void) 
 1355: {
 1356: 	struct isakmp_cfg_state *state;
 1357: 
 1358: 	if ((state = racoon_malloc(sizeof(*state))) == NULL) {
 1359: 		plog(LLV_ERROR, LOCATION, NULL,
 1360: 		    "Cannot allocate memory for mode config state\n");
 1361: 		return NULL;
 1362: 	}
 1363: 	memset(state, 0, sizeof(*state));
 1364: 
 1365: 	return state;
 1366: }
 1367: 
 1368: int 
 1369: isakmp_cfg_getport(iph1)
 1370: 	struct ph1handle *iph1;
 1371: {
 1372: 	unsigned int i;
 1373: 	size_t size = isakmp_cfg_config.pool_size;
 1374: 
 1375: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
 1376: 		return iph1->mode_cfg->port;
 1377: 
 1378: 	if (isakmp_cfg_config.port_pool == NULL) {
 1379: 		plog(LLV_ERROR, LOCATION, NULL,
 1380: 		    "isakmp_cfg_config.port_pool == NULL\n");
 1381: 		return -1;
 1382: 	}
 1383: 
 1384: 	for (i = 0; i < size; i++) {
 1385: 		if (isakmp_cfg_config.port_pool[i].used == 0)
 1386: 			break;
 1387: 	}
 1388: 
 1389: 	if (i == size) {
 1390: 		plog(LLV_ERROR, LOCATION, NULL, 
 1391: 		    "No more addresses available\n");
 1392: 			return -1;
 1393: 	}
 1394: 
 1395: 	isakmp_cfg_config.port_pool[i].used = 1;
 1396: 
 1397: 	plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
 1398: 
 1399: 	iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
 1400: 	iph1->mode_cfg->port = i;
 1401: 
 1402: 	return i;
 1403: }
 1404: 
 1405: int 
 1406: isakmp_cfg_putport(iph1, index)
 1407: 	struct ph1handle *iph1;
 1408: 	unsigned int index;
 1409: {
 1410: 	if (isakmp_cfg_config.port_pool == NULL) {
 1411: 		plog(LLV_ERROR, LOCATION, NULL, 
 1412: 		    "isakmp_cfg_config.port_pool == NULL\n");
 1413: 		return -1;
 1414: 	}
 1415: 
 1416: 	if (isakmp_cfg_config.port_pool[index].used == 0) {
 1417: 		plog(LLV_ERROR, LOCATION, NULL, 
 1418: 		    "Attempt to release an unallocated address (port %d)\n",
 1419: 		    index);
 1420: 		return -1;
 1421: 	}
 1422: 
 1423: #ifdef HAVE_LIBPAM
 1424: 	/* Cleanup PAM status associated with the port */
 1425: 	if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
 1426: 		privsep_cleanup_pam(index);
 1427: #endif
 1428: 	isakmp_cfg_config.port_pool[index].used = 0;
 1429: 	iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
 1430: 
 1431: 	plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
 1432: 
 1433: 	return 0;
 1434: }
 1435: 
 1436: #ifdef HAVE_LIBPAM
 1437: void
 1438: cleanup_pam(port)
 1439: 	int port;
 1440: {
 1441: 	if (isakmp_cfg_config.port_pool[port].pam != NULL) {
 1442: 		pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
 1443: 		isakmp_cfg_config.port_pool[port].pam = NULL;
 1444: 	}
 1445: 
 1446: 	return;
 1447: }
 1448: #endif
 1449: 
 1450: /* Accounting, only for RADIUS or PAM */
 1451: static int
 1452: isakmp_cfg_accounting(iph1, inout)
 1453: 	struct ph1handle *iph1;
 1454: 	int inout;
 1455: {
 1456: #ifdef HAVE_LIBPAM
 1457: 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
 1458: 		return privsep_accounting_pam(iph1->mode_cfg->port, 
 1459: 		    inout);
 1460: #endif 
 1461: #ifdef HAVE_LIBRADIUS
 1462: 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
 1463: 		return isakmp_cfg_accounting_radius(iph1, inout);
 1464: #endif
 1465: 	if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
 1466: 		return privsep_accounting_system(iph1->mode_cfg->port,
 1467: 			iph1->remote, iph1->mode_cfg->login, inout);
 1468: 	return 0;
 1469: }
 1470: 
 1471: #ifdef HAVE_LIBPAM
 1472: int 
 1473: isakmp_cfg_accounting_pam(port, inout)
 1474: 	int port;
 1475: 	int inout;
 1476: {
 1477: 	int error = 0;
 1478: 	pam_handle_t *pam;
 1479: 
 1480: 	if (isakmp_cfg_config.port_pool == NULL) {
 1481: 		plog(LLV_ERROR, LOCATION, NULL, 
 1482: 		    "isakmp_cfg_config.port_pool == NULL\n");
 1483: 		return -1;
 1484: 	}
 1485: 	
 1486: 	pam = isakmp_cfg_config.port_pool[port].pam;
 1487: 	if (pam == NULL) {
 1488: 		plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
 1489: 		return -1;
 1490: 	}
 1491: 
 1492: 	switch (inout) {
 1493: 	case ISAKMP_CFG_LOGIN:
 1494: 		error = pam_open_session(pam, 0);
 1495: 		break;
 1496: 	case ISAKMP_CFG_LOGOUT:
 1497: 		error = pam_close_session(pam, 0);
 1498: 		pam_end(pam, error);
 1499: 		isakmp_cfg_config.port_pool[port].pam = NULL;
 1500: 		break;
 1501: 	default:
 1502: 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
 1503: 		break;
 1504: 	}
 1505: 	
 1506: 	if (error != 0) {
 1507: 		plog(LLV_ERROR, LOCATION, NULL,
 1508: 		    "pam_open_session/pam_close_session failed: %s\n",
 1509: 		    pam_strerror(pam, error)); 
 1510: 		return -1;
 1511:         }
 1512: 
 1513: 	return 0;
 1514: }
 1515: #endif /* HAVE_LIBPAM */
 1516: 
 1517: #ifdef HAVE_LIBRADIUS
 1518: static int
 1519: isakmp_cfg_accounting_radius(iph1, inout)
 1520: 	struct ph1handle *iph1;
 1521: 	int inout;
 1522: {
 1523: 	if (rad_create_request(radius_acct_state, 
 1524: 	    RAD_ACCOUNTING_REQUEST) != 0) {
 1525: 		plog(LLV_ERROR, LOCATION, NULL,
 1526: 		    "rad_create_request failed: %s\n",
 1527: 		    rad_strerror(radius_acct_state));
 1528: 		return -1;
 1529: 	}
 1530: 
 1531: 	if (rad_put_string(radius_acct_state, RAD_USER_NAME, 
 1532: 	    iph1->mode_cfg->login) != 0) {
 1533: 		plog(LLV_ERROR, LOCATION, NULL,
 1534: 		    "rad_put_string failed: %s\n",
 1535: 		    rad_strerror(radius_acct_state));
 1536: 		return -1;
 1537: 	}
 1538: 
 1539: 	switch (inout) {
 1540: 	case ISAKMP_CFG_LOGIN:
 1541: 		inout = RAD_START;
 1542: 		break;
 1543: 	case ISAKMP_CFG_LOGOUT:
 1544: 		inout = RAD_STOP;
 1545: 		break;
 1546: 	default:
 1547: 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
 1548: 		break;
 1549: 	}
 1550: 
 1551: 	if (rad_put_addr(radius_acct_state, 
 1552: 	    RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
 1553: 		plog(LLV_ERROR, LOCATION, NULL,
 1554: 		    "rad_put_addr failed: %s\n",
 1555: 		    rad_strerror(radius_acct_state));
 1556: 		return -1;
 1557: 	}
 1558: 
 1559: 	if (rad_put_addr(radius_acct_state, 
 1560: 	    RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
 1561: 		plog(LLV_ERROR, LOCATION, NULL,
 1562: 		    "rad_put_addr failed: %s\n",
 1563: 		    rad_strerror(radius_acct_state));
 1564: 		return -1;
 1565: 	}
 1566: 
 1567: 	if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
 1568: 		plog(LLV_ERROR, LOCATION, NULL,
 1569: 		    "rad_put_int failed: %s\n",
 1570: 		    rad_strerror(radius_acct_state));
 1571: 		return -1;
 1572: 	}
 1573: 
 1574: 	if (isakmp_cfg_radius_common(radius_acct_state, 
 1575: 	    iph1->mode_cfg->port) != 0)
 1576: 		return -1;
 1577: 
 1578: 	if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
 1579: 		plog(LLV_ERROR, LOCATION, NULL,
 1580: 		    "rad_send_request failed: %s\n",
 1581: 		    rad_strerror(radius_acct_state));
 1582: 		return -1;
 1583: 	}
 1584: 
 1585: 	return 0;
 1586: }
 1587: #endif /* HAVE_LIBRADIUS */
 1588: 
 1589: /*
 1590:  * Attributes common to all RADIUS requests
 1591:  */
 1592: #ifdef HAVE_LIBRADIUS
 1593: int
 1594: isakmp_cfg_radius_common(radius_state, port)
 1595: 	struct rad_handle *radius_state;
 1596: 	int port;
 1597: { 
 1598: 	struct utsname name;
 1599: 	static struct hostent *host = NULL;
 1600: 	struct in_addr nas_addr;
 1601: 
 1602: 	/* 
 1603: 	 * Find our own IP by resolving our nodename
 1604: 	 */
 1605: 	if (host == NULL) {
 1606: 		if (uname(&name) != 0) {
 1607: 			plog(LLV_ERROR, LOCATION, NULL,
 1608: 			    "uname failed: %s\n", strerror(errno));
 1609: 			return -1;
 1610: 		}
 1611: 
 1612: 		if ((host = gethostbyname(name.nodename)) == NULL) {
 1613: 			plog(LLV_ERROR, LOCATION, NULL,
 1614: 			    "gethostbyname failed: %s\n", strerror(errno));
 1615: 			return -1;
 1616: 		}
 1617: 	}
 1618: 
 1619: 	memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
 1620: 	if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
 1621: 		plog(LLV_ERROR, LOCATION, NULL,
 1622: 		    "rad_put_addr failed: %s\n",
 1623: 		    rad_strerror(radius_state));
 1624: 		return -1;
 1625: 	}
 1626: 
 1627: 	if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
 1628: 		plog(LLV_ERROR, LOCATION, NULL,
 1629: 		    "rad_put_int failed: %s\n",
 1630: 		    rad_strerror(radius_state));
 1631: 		return -1;
 1632: 	}
 1633: 
 1634: 	if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
 1635: 		plog(LLV_ERROR, LOCATION, NULL,
 1636: 		    "rad_put_int failed: %s\n",
 1637: 		    rad_strerror(radius_state));
 1638: 		return -1;
 1639: 	}
 1640: 
 1641: 	if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
 1642: 		plog(LLV_ERROR, LOCATION, NULL,
 1643: 		    "rad_put_int failed: %s\n",
 1644: 		    rad_strerror(radius_state));
 1645: 		return -1;
 1646: 	}
 1647: 	
 1648: 	return 0;
 1649: }
 1650: #endif
 1651: 
 1652: /*
 1653: 	Logs the user into the utmp system files.
 1654: */
 1655: 
 1656: int
 1657: isakmp_cfg_accounting_system(port, raddr, usr, inout)
 1658: 	int port;
 1659: 	struct sockaddr *raddr;
 1660: 	char *usr;
 1661: 	int inout;
 1662: {
 1663: 	int error = 0;
 1664: 	struct utmpx ut;
 1665: 	char addr[NI_MAXHOST];
 1666: 	
 1667: 	if (usr == NULL || usr[0]=='\0') {
 1668: 		plog(LLV_ERROR, LOCATION, NULL,
 1669: 			"system accounting : no login found\n");
 1670: 		return -1;
 1671: 	}
 1672: 
 1673: 	memset(&ut, 0, sizeof ut);
 1674: 	gettimeofday((struct timeval *)&ut.ut_tv, NULL);
 1675: 	snprintf(ut.ut_id, sizeof ut.ut_id, TERMSPEC, port);
 1676: 
 1677: 	switch (inout) {
 1678: 	case ISAKMP_CFG_LOGIN:
 1679: 		ut.ut_type = USER_PROCESS;
 1680: 		strncpy(ut.ut_user, usr, sizeof ut.ut_user);
 1681: 
 1682: 		GETNAMEINFO_NULL(raddr, addr);
 1683: 		strncpy(ut.ut_host, addr, sizeof ut.ut_host);
 1684: 
 1685: 		plog(LLV_INFO, LOCATION, NULL,
 1686: 			"Accounting : '%s' logging on '%s' from %s.\n",
 1687: 			ut.ut_user, ut.ut_id, addr);
 1688: 
 1689: 		pututxline(&ut);
 1690: 
 1691: 		break;
 1692: 	case ISAKMP_CFG_LOGOUT:	
 1693: 		ut.ut_type = DEAD_PROCESS;
 1694: 
 1695: 		plog(LLV_INFO, LOCATION, NULL,
 1696: 			"Accounting : '%s' unlogging from '%s'.\n",
 1697: 			usr, ut.ut_id);
 1698: 
 1699: 		pututxline(&ut);
 1700: 
 1701: 		break;
 1702: 	default:
 1703: 		plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
 1704: 		break;
 1705: 	}
 1706: 
 1707: 	return 0;
 1708: }
 1709: 	
 1710: int 
 1711: isakmp_cfg_getconfig(iph1)
 1712: 	struct ph1handle *iph1;
 1713: {
 1714: 	vchar_t *buffer;
 1715: 	struct isakmp_pl_attr *attrpl;
 1716: 	struct isakmp_data *attr;
 1717: 	size_t len;
 1718: 	int error;
 1719: 	int attrcount;
 1720: 	int i;
 1721: 	int attrlist[] = {
 1722: 		INTERNAL_IP4_ADDRESS,
 1723: 		INTERNAL_IP4_NETMASK,
 1724: 		INTERNAL_IP4_DNS,
 1725: 		INTERNAL_IP4_NBNS,
 1726: 		UNITY_BANNER,
 1727: 		UNITY_DEF_DOMAIN,
 1728: 		UNITY_SPLITDNS_NAME,
 1729: 		UNITY_SPLIT_INCLUDE,
 1730: 		UNITY_LOCAL_LAN,
 1731: 		APPLICATION_VERSION,
 1732: 	};
 1733: 
 1734: 	attrcount = sizeof(attrlist) / sizeof(*attrlist);
 1735: 	len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
 1736: 	    
 1737: 	if ((buffer = vmalloc(len)) == NULL) {
 1738: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
 1739: 		return -1;
 1740: 	}
 1741: 
 1742: 	attrpl = (struct isakmp_pl_attr *)buffer->v;
 1743: 	attrpl->h.len = htons(len);
 1744: 	attrpl->type = ISAKMP_CFG_REQUEST;
 1745: 	attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
 1746: 
 1747: 	attr = (struct isakmp_data *)(attrpl + 1);
 1748: 
 1749: 	for (i = 0; i < attrcount; i++) {
 1750: 		attr->type = htons(attrlist[i]);
 1751: 		attr->lorv = htons(0);
 1752: 		attr++;
 1753: 	}
 1754: 
 1755: 	plog(LLV_DEBUG, LOCATION, NULL, 
 1756: 		    "Sending MODE_CFG REQUEST\n");
 1757: 
 1758: 	error = isakmp_cfg_send(iph1, buffer,
 1759: 	    ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1);
 1760: 
 1761: 	vfree(buffer);
 1762: 
 1763: 	return error;
 1764: }
 1765: 
 1766: static void
 1767: isakmp_cfg_getaddr4(attr, ip)
 1768: 	struct isakmp_data *attr;
 1769: 	struct in_addr *ip;
 1770: {
 1771: 	size_t alen = ntohs(attr->lorv);
 1772: 	in_addr_t *addr;
 1773: 
 1774: 	if (alen != sizeof(*ip)) {
 1775: 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
 1776: 		return;
 1777: 	}
 1778: 
 1779: 	addr = (in_addr_t *)(attr + 1);
 1780: 	ip->s_addr = *addr;
 1781: 
 1782: 	return;
 1783: }
 1784: 
 1785: static void
 1786: isakmp_cfg_appendaddr4(attr, ip, num, max)
 1787: 	struct isakmp_data *attr;
 1788: 	struct in_addr *ip;
 1789: 	int *num;
 1790: 	int max;
 1791: {
 1792: 	size_t alen = ntohs(attr->lorv);
 1793: 	in_addr_t *addr;
 1794: 
 1795: 	if (alen != sizeof(*ip)) {
 1796: 		plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
 1797: 		return;
 1798: 	}
 1799: 	if (*num == max) {
 1800: 		plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
 1801: 		return;
 1802: 	}
 1803: 
 1804: 	addr = (in_addr_t *)(attr + 1);
 1805: 	ip->s_addr = *addr;
 1806: 	(*num)++;
 1807: 
 1808: 	return;
 1809: }
 1810: 
 1811: static void
 1812: isakmp_cfg_getstring(attr, str)
 1813: 	struct isakmp_data *attr;
 1814: 	char *str;
 1815: {
 1816: 	size_t alen = ntohs(attr->lorv);
 1817: 	char *src;
 1818: 	src = (char *)(attr + 1);
 1819: 
 1820: 	memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
 1821: 
 1822: 	return;
 1823: }
 1824: 
 1825: #define IP_MAX 40
 1826: 
 1827: void
 1828: isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
 1829: 	char *dest;
 1830: 	int count;
 1831: 	void *addr;
 1832: 	int withmask;
 1833: {
 1834: 	int i;
 1835: 	int p;
 1836: 	int l;
 1837: 	struct unity_network tmp;
 1838: 	for(i = 0, p = 0; i < count; i++) {
 1839: 		if(withmask == 1)
 1840: 			l = sizeof(struct unity_network);
 1841: 		else
 1842: 			l = sizeof(struct in_addr);
 1843: 		memcpy(&tmp, addr, l);
 1844: 		addr += l;
 1845: 		if((uint32_t)tmp.addr4.s_addr == 0)
 1846: 			break;
 1847: 	
 1848: 		inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
 1849: 		p += strlen(dest + p);
 1850: 		if(withmask == 1) {
 1851: 			dest[p] = '/';
 1852: 			p++;
 1853: 			inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
 1854: 			p += strlen(dest + p);
 1855: 		}
 1856: 		dest[p] = ' ';
 1857: 		p++;
 1858: 	}
 1859: 	if(p > 0)
 1860: 		dest[p-1] = '\0';
 1861: 	else
 1862: 		dest[0] = '\0';
 1863: }
 1864: 
 1865: int
 1866: isakmp_cfg_setenv(iph1, envp, envc)
 1867: 	struct ph1handle *iph1; 
 1868: 	char ***envp;
 1869: 	int *envc;
 1870: {
 1871: 	char addrstr[IP_MAX];
 1872: 	char addrlist[IP_MAX * MAXNS + MAXNS];
 1873: 	char *splitlist = addrlist;
 1874: 	char *splitlist_cidr;
 1875: 	char defdom[MAXPATHLEN + 1];
 1876: 	int cidr, tmp;
 1877: 	char cidrstr[4];
 1878: 	int i, p;
 1879: 	int test;
 1880: 
 1881: 	plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
 1882: 
 1883: 	/* 
 1884: 	 * Internal IPv4 address, either if 
 1885: 	 * we are a client or a server.
 1886: 	 */
 1887: 	if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
 1888: #ifdef HAVE_LIBLDAP
 1889: 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
 1890: #endif
 1891: #ifdef HAVE_LIBRADIUS
 1892: 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
 1893: #endif
 1894: 	    (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
 1895: 		inet_ntop(AF_INET, &iph1->mode_cfg->addr4, 
 1896: 		    addrstr, IP_MAX);
 1897: 	} else
 1898: 		addrstr[0] = '\0';
 1899: 
 1900: 	if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
 1901: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
 1902: 		return -1;
 1903: 	}
 1904: 
 1905: 	if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
 1906: 		if (script_env_append(envp, envc, "XAUTH_USER", 
 1907: 		    iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
 1908: 			plog(LLV_ERROR, LOCATION, NULL, 
 1909: 			    "Cannot set XAUTH_USER\n");
 1910: 			return -1;
 1911: 		}
 1912: 	}
 1913: 
 1914: 	/* Internal IPv4 mask */
 1915: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) 
 1916: 		inet_ntop(AF_INET, &iph1->mode_cfg->mask4, 
 1917: 		    addrstr, IP_MAX);
 1918: 	else
 1919: 		addrstr[0] = '\0';
 1920: 
 1921: 	/* 	
 1922: 	 * During several releases, documentation adverised INTERNAL_NETMASK4
 1923: 	 * while code was using INTERNAL_MASK4. We now do both.
 1924: 	 */
 1925: 
 1926: 	if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) { 
 1927: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
 1928: 		return -1;
 1929: 	}
 1930: 
 1931: 	if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) { 
 1932: 		plog(LLV_ERROR, LOCATION, NULL, 
 1933: 		    "Cannot set INTERNAL_NETMASK4\n");
 1934: 		return -1;
 1935: 	}
 1936: 
 1937: 	tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
 1938: 	for (cidr = 0; tmp != 0; cidr++)
 1939: 		tmp <<= 1;
 1940: 	snprintf(cidrstr, 3, "%d", cidr);
 1941: 
 1942: 	if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
 1943: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
 1944: 		return -1;
 1945: 	}
 1946: 
 1947: 	/* Internal IPv4 DNS */
 1948: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
 1949: 		/* First Internal IPv4 DNS (for compatibilty with older code */
 1950: 		inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0], 
 1951: 		    addrstr, IP_MAX);
 1952: 
 1953: 		/* Internal IPv4 DNS - all */
 1954: 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
 1955: 			(void *)iph1->mode_cfg->dns4, 0);
 1956: 	} else {
 1957: 		addrstr[0] = '\0';
 1958: 		addrlist[0] = '\0';
 1959: 	}
 1960: 
 1961: 	if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
 1962: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
 1963: 		return -1;
 1964: 	}
 1965: 	if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
 1966: 		plog(LLV_ERROR, LOCATION, NULL, 
 1967: 		    "Cannot set INTERNAL_DNS4_LIST\n");
 1968: 		return -1;
 1969: 	}
 1970: 	
 1971: 	/* Internal IPv4 WINS */
 1972: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
 1973: 		/* 
 1974: 		 * First Internal IPv4 WINS 
 1975: 		 * (for compatibilty with older code 
 1976: 		 */
 1977: 		inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0], 
 1978: 		    addrstr, IP_MAX);
 1979: 
 1980: 		/* Internal IPv4 WINS - all */
 1981: 		isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
 1982: 			(void *)iph1->mode_cfg->wins4, 0);
 1983: 	} else {
 1984: 		addrstr[0] = '\0';
 1985: 		addrlist[0] = '\0';
 1986: 	}
 1987: 
 1988: 	if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
 1989: 		plog(LLV_ERROR, LOCATION, NULL, 
 1990: 		    "Cannot set INTERNAL_WINS4\n");
 1991: 		return -1;
 1992: 	}
 1993: 	if (script_env_append(envp, envc, 
 1994: 	    "INTERNAL_WINS4_LIST", addrlist) != 0) {
 1995: 		plog(LLV_ERROR, LOCATION, NULL, 
 1996: 		    "Cannot set INTERNAL_WINS4_LIST\n");
 1997: 		return -1;
 1998: 	}
 1999: 
 2000: 	/* Deault domain */
 2001: 	if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) 
 2002: 		strncpy(defdom, 
 2003: 		    iph1->mode_cfg->default_domain, 
 2004: 		    MAXPATHLEN + 1);
 2005: 	else
 2006: 		defdom[0] = '\0';
 2007: 	
 2008: 	if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) { 
 2009: 		plog(LLV_ERROR, LOCATION, NULL, 
 2010: 		    "Cannot set DEFAULT_DOMAIN\n");
 2011: 		return -1;
 2012: 	}
 2013: 
 2014: 	/* Split networks */
 2015: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE) {
 2016: 		splitlist = 
 2017: 		    splitnet_list_2str(iph1->mode_cfg->split_include, NETMASK);
 2018: 		splitlist_cidr = 
 2019: 		    splitnet_list_2str(iph1->mode_cfg->split_include, CIDR);
 2020: 	} else {
 2021: 		splitlist = addrlist;
 2022: 		splitlist_cidr = addrlist;
 2023: 		addrlist[0] = '\0';
 2024: 	}
 2025: 
 2026: 	if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
 2027: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
 2028: 		return -1;
 2029: 	}
 2030: 	if (script_env_append(envp, envc, 
 2031: 	    "SPLIT_INCLUDE_CIDR", splitlist_cidr) != 0) {
 2032: 		plog(LLV_ERROR, LOCATION, NULL,
 2033: 		     "Cannot set SPLIT_INCLUDE_CIDR\n");
 2034: 		return -1;
 2035: 	}
 2036: 	if (splitlist != addrlist)
 2037: 		racoon_free(splitlist);
 2038: 	if (splitlist_cidr != addrlist)
 2039: 		racoon_free(splitlist_cidr);
 2040: 
 2041: 	if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL) {
 2042: 		splitlist =
 2043: 		    splitnet_list_2str(iph1->mode_cfg->split_local, NETMASK);
 2044: 		splitlist_cidr =
 2045: 		    splitnet_list_2str(iph1->mode_cfg->split_local, CIDR);
 2046: 	} else {
 2047: 		splitlist = addrlist;
 2048: 		splitlist_cidr = addrlist;
 2049: 		addrlist[0] = '\0';
 2050: 	}
 2051: 
 2052: 	if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
 2053: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
 2054: 		return -1;
 2055: 	}
 2056: 	if (script_env_append(envp, envc,
 2057: 	    "SPLIT_LOCAL_CIDR", splitlist_cidr) != 0) {
 2058: 		plog(LLV_ERROR, LOCATION, NULL,
 2059: 		     "Cannot set SPLIT_LOCAL_CIDR\n");
 2060: 		return -1;
 2061: 	}
 2062: 	if (splitlist != addrlist)
 2063: 		racoon_free(splitlist);
 2064: 	if (splitlist_cidr != addrlist)
 2065: 		racoon_free(splitlist_cidr);
 2066: 	
 2067: 	return 0;
 2068: }
 2069: 
 2070: int
 2071: isakmp_cfg_resize_pool(size)
 2072: 	int size;
 2073: {
 2074: 	struct isakmp_cfg_port *new_pool;
 2075: 	size_t len;
 2076: 	int i;
 2077: 
 2078: 	if (size == isakmp_cfg_config.pool_size)
 2079: 		return 0;
 2080: 
 2081: 	plog(LLV_INFO, LOCATION, NULL,
 2082: 	    "Resize address pool from %zu to %d\n",
 2083: 	    isakmp_cfg_config.pool_size, size);
 2084: 
 2085: 	/* If a pool already exists, check if we can shrink it */
 2086: 	if ((isakmp_cfg_config.port_pool != NULL) &&
 2087: 	    (size < isakmp_cfg_config.pool_size)) {
 2088: 		for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
 2089: 			if (isakmp_cfg_config.port_pool[i].used) {
 2090: 				plog(LLV_ERROR, LOCATION, NULL, 
 2091: 				    "resize pool from %zu to %d impossible "
 2092: 				    "port %d is in use\n", 
 2093: 				    isakmp_cfg_config.pool_size, size, i);
 2094: 				size = i;
 2095: 				break;
 2096: 			}	
 2097: 		}
 2098: 	}
 2099: 
 2100: 	len = size * sizeof(*isakmp_cfg_config.port_pool);
 2101: 	new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
 2102: 	if (new_pool == NULL) {
 2103: 		plog(LLV_ERROR, LOCATION, NULL, 
 2104: 		    "resize pool from %zu to %d impossible: %s",
 2105: 		    isakmp_cfg_config.pool_size, size, strerror(errno));
 2106: 		return -1;
 2107: 	}
 2108: 
 2109: 	/* If size increase, intialize correctly the new records */
 2110: 	if (size > isakmp_cfg_config.pool_size) {
 2111: 		size_t unit;
 2112: 		size_t old_size;
 2113: 
 2114: 		unit =  sizeof(*isakmp_cfg_config.port_pool);
 2115: 		old_size = isakmp_cfg_config.pool_size;
 2116: 
 2117: 		bzero((char *)new_pool + (old_size * unit), 
 2118: 		    (size - old_size) * unit);
 2119: 	}
 2120: 
 2121: 	isakmp_cfg_config.port_pool = new_pool;
 2122: 	isakmp_cfg_config.pool_size = size;
 2123: 
 2124: 	return 0;
 2125: }
 2126: 
 2127: int
 2128: isakmp_cfg_init(cold) 
 2129: 	int cold;
 2130: {
 2131: 	int i;
 2132: 	int error;
 2133: 
 2134: 	isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
 2135: 	isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
 2136: 	for (i = 0; i < MAXNS; i++)
 2137: 		isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
 2138: 	isakmp_cfg_config.dns4_index = 0;
 2139: 	for (i = 0; i < MAXWINS; i++)
 2140: 		isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
 2141: 	isakmp_cfg_config.nbns4_index = 0;
 2142: 	if (cold == ISAKMP_CFG_INIT_COLD)
 2143: 		isakmp_cfg_config.port_pool = NULL;
 2144: 	isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
 2145: 	isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
 2146: 	if (cold == ISAKMP_CFG_INIT_COLD) {
 2147: 		if (isakmp_cfg_config.grouplist != NULL) {
 2148: 			for (i = 0; i < isakmp_cfg_config.groupcount; i++)
 2149: 				racoon_free(isakmp_cfg_config.grouplist[i]);
 2150: 			racoon_free(isakmp_cfg_config.grouplist);
 2151: 		}
 2152: 	}
 2153: 	isakmp_cfg_config.grouplist = NULL;
 2154: 	isakmp_cfg_config.groupcount = 0;
 2155: 	isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
 2156: 	isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
 2157: 	if (cold == ISAKMP_CFG_INIT_COLD)
 2158: 		isakmp_cfg_config.pool_size = 0;
 2159: 	isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
 2160: 	strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
 2161: 	    MAXPATHLEN);
 2162: 	strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, MAXPATHLEN);
 2163: 
 2164: 	if (cold != ISAKMP_CFG_INIT_COLD )
 2165: 		if (isakmp_cfg_config.splitnet_list != NULL)
 2166: 			splitnet_list_free(isakmp_cfg_config.splitnet_list,
 2167: 				&isakmp_cfg_config.splitnet_count);
 2168: 	isakmp_cfg_config.splitnet_list = NULL;
 2169: 	isakmp_cfg_config.splitnet_count = 0;
 2170: 	isakmp_cfg_config.splitnet_type = 0;
 2171: 
 2172: 	isakmp_cfg_config.pfs_group = 0;
 2173: 	isakmp_cfg_config.save_passwd = 0;
 2174: 
 2175: 	if (cold != ISAKMP_CFG_INIT_COLD )
 2176: 		if (isakmp_cfg_config.splitdns_list != NULL)
 2177: 			racoon_free(isakmp_cfg_config.splitdns_list);
 2178: 	isakmp_cfg_config.splitdns_list = NULL;
 2179: 	isakmp_cfg_config.splitdns_len = 0;
 2180: 
 2181: #if 0
 2182: 	if (cold == ISAKMP_CFG_INIT_COLD) {
 2183: 		if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
 2184: 			return error;
 2185: 	}
 2186: #endif
 2187: 
 2188: 	return 0;
 2189: }
 2190: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>