File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / isakmp_unity.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:37:12 2014 UTC (10 years ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, HEAD
ipsec-tools 0.8.1

    1: /*	$NetBSD: isakmp_unity.c,v 1.9.18.1 2012/01/01 17:32:04 tteras Exp $	*/
    2: 
    3: /* Id: isakmp_unity.c,v 1.10 2006/07/31 04:49:23 manubsd Exp */
    4: 
    5: /*
    6:  * Copyright (C) 2004 Emmanuel Dreyfus
    7:  * All rights reserved.
    8:  * 
    9:  * Redistribution and use in source and binary forms, with or without
   10:  * modification, are permitted provided that the following conditions
   11:  * are met:
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer.
   14:  * 2. Redistributions in binary form must reproduce the above copyright
   15:  *    notice, this list of conditions and the following disclaimer in the
   16:  *    documentation and/or other materials provided with the distribution.
   17:  * 3. Neither the name of the project nor the names of its contributors
   18:  *    may be used to endorse or promote products derived from this software
   19:  *    without specific prior written permission.
   20:  * 
   21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31:  * SUCH DAMAGE.
   32:  */
   33: 
   34: #include "config.h"
   35: 
   36: #include <sys/types.h>
   37: #include <sys/param.h>
   38: #include <sys/socket.h>
   39: #include <sys/queue.h>
   40: 
   41: #include <netinet/in.h>
   42: #include <arpa/inet.h>
   43: 
   44: #include <stdlib.h>
   45: #include <stdio.h>
   46: #include <fcntl.h>
   47: #include <string.h>
   48: #include <errno.h>
   49: #if TIME_WITH_SYS_TIME
   50: # include <sys/time.h>
   51: # include <time.h>
   52: #else
   53: # if HAVE_SYS_TIME_H
   54: #  include <sys/time.h>
   55: # else
   56: #  include <time.h>
   57: # endif
   58: #endif
   59: #include <netdb.h>
   60: #ifdef HAVE_UNISTD_H
   61: #include <unistd.h>
   62: #endif
   63: #include <ctype.h>
   64: #include <resolv.h>
   65: 
   66: #include "var.h"
   67: #include "misc.h"
   68: #include "vmbuf.h"
   69: #include "plog.h"
   70: #include "sockmisc.h"
   71: #include "schedule.h"
   72: #include "debug.h"
   73: 
   74: #include "isakmp_var.h"
   75: #include "isakmp.h"
   76: #include "handler.h"
   77: #include "isakmp_xauth.h"
   78: #include "isakmp_unity.h"
   79: #include "isakmp_cfg.h"
   80: #include "strnames.h"
   81: 
   82: static vchar_t *isakmp_cfg_split(struct ph1handle *, 
   83:     struct isakmp_data *, struct unity_netentry*,int);
   84: 
   85: vchar_t *
   86: isakmp_unity_req(iph1, attr)
   87: 	struct ph1handle *iph1;
   88: 	struct isakmp_data *attr;
   89: {
   90: 	int type;
   91: 	vchar_t *reply_attr = NULL;
   92: 
   93: 	if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) == 0) {
   94: 		plog(LLV_ERROR, LOCATION, NULL, 
   95: 		    "Unity mode config request but the peer "
   96: 		    "did not declare itself as  unity compliant\n");
   97: 		return NULL;
   98: 	}
   99: 
  100: 	type = ntohs(attr->type);
  101: 
  102: 	/* Handle short attributes */
  103: 	if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
  104: 		type &= ~ISAKMP_GEN_MASK;
  105: 
  106: 		plog(LLV_DEBUG, LOCATION, NULL,
  107: 		     "Short attribute %s = %d\n", 
  108: 		     s_isakmp_cfg_type(type), ntohs(attr->lorv));
  109: 
  110: 		switch (type) {
  111: 		default:
  112: 			plog(LLV_DEBUG, LOCATION, NULL,
  113: 			     "Ignored short attribute %s\n",
  114: 			     s_isakmp_cfg_type(type));
  115: 			break;
  116: 		}
  117: 
  118: 		return reply_attr;
  119: 	}
  120: 
  121: 	switch(type) {
  122: 	case UNITY_BANNER: {
  123: #define MAXMOTD 65536
  124: 		char buf[MAXMOTD + 1];
  125: 		int fd;
  126: 		char *filename = &isakmp_cfg_config.motd[0];
  127: 		int len;
  128: 
  129: 		if ((fd = open(filename, O_RDONLY, 0)) == -1) {
  130: 			plog(LLV_ERROR, LOCATION, NULL, 
  131: 			    "Cannot open \"%s\"\n", filename);
  132: 			return NULL;
  133: 		}
  134: 
  135: 		if ((len = read(fd, buf, MAXMOTD)) == -1) {
  136: 			plog(LLV_ERROR, LOCATION, NULL, 
  137: 			    "Cannot read \"%s\"\n", filename);
  138: 			close(fd);
  139: 			return NULL;
  140: 		}
  141: 		close(fd);
  142: 
  143: 		buf[len] = '\0';
  144: 		reply_attr = isakmp_cfg_string(iph1, attr, buf);
  145: 
  146: 		break;
  147: 	}
  148: 
  149: 	case UNITY_PFS:
  150: 		reply_attr = isakmp_cfg_short(iph1, attr, 
  151: 		    isakmp_cfg_config.pfs_group);
  152: 		break;
  153: 
  154: 	case UNITY_SAVE_PASSWD:
  155: 		reply_attr = isakmp_cfg_short(iph1, attr, 
  156: 		    isakmp_cfg_config.save_passwd);
  157: 		break;
  158: 
  159: 	case UNITY_DDNS_HOSTNAME:
  160: 		reply_attr = isakmp_cfg_copy(iph1, attr);
  161: 		break;
  162: 
  163: 	case UNITY_DEF_DOMAIN:
  164: 		reply_attr = isakmp_cfg_string(iph1, 
  165: 		    attr, isakmp_cfg_config.default_domain);
  166: 		break;
  167: 
  168: 	case UNITY_SPLIT_INCLUDE:
  169: 		if(isakmp_cfg_config.splitnet_type == UNITY_SPLIT_INCLUDE)
  170: 			reply_attr = isakmp_cfg_split(iph1, attr,
  171: 			isakmp_cfg_config.splitnet_list,
  172: 			isakmp_cfg_config.splitnet_count);
  173: 		else
  174: 			return NULL;
  175: 		break;
  176: 	case UNITY_LOCAL_LAN:
  177: 		if(isakmp_cfg_config.splitnet_type == UNITY_LOCAL_LAN)
  178: 			reply_attr = isakmp_cfg_split(iph1, attr,
  179: 			isakmp_cfg_config.splitnet_list,
  180: 			isakmp_cfg_config.splitnet_count);
  181: 		else
  182: 			return NULL;
  183: 		break;
  184: 	case UNITY_SPLITDNS_NAME:
  185: 		reply_attr = isakmp_cfg_varlen(iph1, attr,
  186: 				isakmp_cfg_config.splitdns_list,
  187: 				isakmp_cfg_config.splitdns_len);
  188: 		break;
  189: 	case UNITY_FW_TYPE:
  190: 	case UNITY_NATT_PORT:
  191: 	case UNITY_BACKUP_SERVERS:
  192: 	default:
  193: 		plog(LLV_DEBUG, LOCATION, NULL,
  194: 		     "Ignored attribute %s\n", s_isakmp_cfg_type(type));
  195: 		return NULL;
  196: 		break;
  197: 	}
  198: 
  199: 	return reply_attr;
  200: }
  201: 
  202: void
  203: isakmp_unity_reply(iph1, attr)
  204: 	struct ph1handle *iph1;
  205: 	struct isakmp_data *attr;
  206: {
  207: 	int type = ntohs(attr->type);
  208: 	int alen = ntohs(attr->lorv);
  209: 
  210: 	struct unity_network *network = (struct unity_network *)(attr + 1);
  211: 	int index = 0;
  212: 	int count = 0;
  213: 
  214: 	switch(type) {
  215: 	case UNITY_SPLIT_INCLUDE:
  216: 	{
  217: 		if (alen)
  218: 			count = alen / sizeof(struct unity_network);
  219: 
  220: 		for(;index < count; index++)
  221: 			splitnet_list_add(
  222: 				&iph1->mode_cfg->split_include,
  223: 				&network[index],
  224: 				&iph1->mode_cfg->include_count);
  225: 
  226: 		iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_INCLUDE;
  227: 		break;
  228: 	}
  229: 	case UNITY_LOCAL_LAN:
  230: 	{
  231: 		if (alen)
  232: 			count = alen / sizeof(struct unity_network);
  233: 
  234: 		for(;index < count; index++)
  235: 			splitnet_list_add(
  236: 				&iph1->mode_cfg->split_local,
  237: 				&network[index],
  238: 				&iph1->mode_cfg->local_count);
  239: 
  240: 		iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_SPLIT_LOCAL;
  241: 		break;
  242: 	}
  243: 	case UNITY_SPLITDNS_NAME:
  244: 	case UNITY_BANNER:
  245: 	case UNITY_SAVE_PASSWD:
  246: 	case UNITY_NATT_PORT:
  247: 	case UNITY_PFS:
  248: 	case UNITY_FW_TYPE:
  249: 	case UNITY_BACKUP_SERVERS:
  250: 	case UNITY_DDNS_HOSTNAME:
  251: 	default:
  252: 		plog(LLV_WARNING, LOCATION, NULL,
  253: 		     "Ignored attribute %s\n",
  254: 		     s_isakmp_cfg_type(type));
  255: 		break;
  256: 	}
  257: 	return;
  258: }
  259: 
  260: static vchar_t *
  261: isakmp_cfg_split(iph1, attr, netentry, count)
  262: 	struct ph1handle *iph1;
  263: 	struct isakmp_data *attr;
  264: 	struct unity_netentry *netentry;
  265: 	int count;
  266: {
  267: 	vchar_t *buffer;
  268: 	struct isakmp_data *new;
  269: 	struct unity_network * network;
  270: 	size_t len;
  271: 	int index = 0;
  272: 
  273: 	char tmp1[40];
  274: 	char tmp2[40];
  275: 
  276: 	len = sizeof(struct unity_network) * count;
  277: 	if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
  278: 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
  279: 		return NULL;
  280: 	}
  281: 
  282: 	new = (struct isakmp_data *)buffer->v;
  283: 	new->type = attr->type;
  284: 	new->lorv = htons(len);
  285: 
  286: 	network = (struct unity_network *)(new + 1);
  287: 	for (; index < count; index++) {
  288: 
  289: 		memcpy(&network[index],
  290: 			&netentry->network,
  291: 			sizeof(struct unity_network));
  292: 
  293: 		inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
  294: 		inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
  295: 		plog(LLV_DEBUG, LOCATION, NULL, "splitnet: %s/%s\n", tmp1, tmp2);
  296: 
  297: 		netentry = netentry->next;
  298: 	}
  299: 
  300: 	return buffer;
  301: }
  302: 
  303: int  splitnet_list_add(list, network, count)
  304: 	struct unity_netentry ** list;
  305: 	struct unity_network * network;
  306: 	int *count;
  307: {
  308: 	struct unity_netentry * nentry;
  309: 
  310: 	/*
  311: 	 * search for network in current list
  312: 	 * to avoid adding duplicates
  313: 	 */
  314: 	for (nentry = *list; nentry != NULL; nentry = nentry->next)
  315: 		if (memcmp(&nentry->network, network,
  316: 			   sizeof(struct unity_network)) == 0)
  317: 			return 0;	/* it's a dupe */
  318: 
  319: 	/*
  320: 	 * allocate new netentry and copy
  321: 	 * new splitnet network data
  322: 	 */
  323: 	nentry = (struct unity_netentry *)
  324: 		racoon_malloc(sizeof(struct unity_netentry));
  325: 	if (nentry == NULL)
  326: 		return -1;
  327: 
  328: 	memcpy(&nentry->network,network,
  329: 		sizeof(struct unity_network));
  330: 	nentry->next = NULL;
  331: 
  332: 	/*
  333: 	 * locate the last netentry in our
  334: 	 * splitnet list and add our entry
  335: 	 */
  336: 	if (*list == NULL)
  337: 		*list = nentry;
  338: 	else {
  339: 		struct unity_netentry * tmpentry = *list;
  340: 		while (tmpentry->next != NULL)
  341: 			tmpentry = tmpentry->next;
  342: 		tmpentry->next = nentry;
  343: 	}
  344: 
  345: 	(*count)++;
  346: 
  347: 	return 0;
  348: }
  349: 
  350: void splitnet_list_free(list, count)
  351: 	struct unity_netentry * list;
  352: 	int *count;
  353: {
  354: 	struct unity_netentry * netentry = list;
  355: 	struct unity_netentry * delentry;
  356: 
  357: 	*count = 0;
  358: 
  359: 	while (netentry != NULL) {
  360: 		delentry = netentry;
  361: 		netentry = netentry->next;
  362: 		racoon_free(delentry);
  363: 	}
  364: }
  365: 
  366: char * splitnet_list_2str(list, splitnet_ipaddr)
  367: 	struct unity_netentry * list;
  368: 	enum splinet_ipaddr splitnet_ipaddr;
  369: {
  370: 	struct unity_netentry * netentry;
  371: 	char tmp1[40];
  372: 	char tmp2[40];
  373: 	char * str;
  374: 	int len;
  375: 
  376: 	/* determine string length */
  377: 	len = 0;
  378: 	netentry = list;
  379: 	while (netentry != NULL) {
  380: 
  381: 		inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
  382: 		inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
  383: 		len += strlen(tmp1);
  384: 		len += strlen(tmp2);
  385: 		len += 2;
  386: 
  387: 		netentry = netentry->next;
  388: 	}
  389: 
  390: 	/* allocate network list string; we need the extra byte temporarily
  391: 	 * as sprintf() will write trailing 0-byte after the space. */
  392: 	str = racoon_malloc(len + 1);
  393: 	if (str == NULL)
  394: 		return NULL;
  395: 
  396: 	/* create network list string */
  397: 	len = 0;
  398: 	netentry = list;
  399: 	while (netentry != NULL) {
  400: 
  401: 		inet_ntop(AF_INET, &netentry->network.addr4, tmp1, 40);
  402: 		inet_ntop(AF_INET, &netentry->network.mask4, tmp2, 40);
  403: 		if (splitnet_ipaddr == CIDR) {
  404: 			uint32_t tmp3;
  405: 			int cidrmask;
  406: 
  407: 			tmp3 = ntohl(netentry->network.mask4.s_addr);
  408: 			for (cidrmask = 0; tmp3 != 0; cidrmask++)
  409: 				tmp3 <<= 1;
  410: 			len += sprintf(str+len, "%s/%d ", tmp1, cidrmask);
  411: 		} else {
  412: 			len += sprintf(str+len, "%s/%s ", tmp1, tmp2);
  413: 		}
  414: 
  415: 		netentry = netentry->next;
  416: 	}
  417: 
  418: 	/* trim the string to not have trailing spaces */
  419: 	str[len-1]=0;
  420: 
  421: 	return str;
  422: }

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