File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / isakmp_cfg.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:45:57 2016 UTC (7 years, 9 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, HEAD
ipsec-tools 0.8.2

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

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