File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / cfparse.y
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:37:11 2014 UTC (10 years, 1 month 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: cfparse.y,v 1.42.2.1 2012/08/29 08:42:24 tteras Exp $	*/
    2: 
    3: /* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
    4: 
    5: %{
    6: /*
    7:  * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project.
    8:  * All rights reserved.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  * 3. Neither the name of the project nor the names of its contributors
   19:  *    may be used to endorse or promote products derived from this software
   20:  *    without specific prior written permission.
   21:  *
   22:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32:  * SUCH DAMAGE.
   33:  */
   34: 
   35: #include "config.h"
   36: 
   37: #include <sys/types.h>
   38: #include <sys/param.h>
   39: #include <sys/queue.h>
   40: #include <sys/socket.h>
   41: 
   42: #include <netinet/in.h>
   43: #include PATH_IPSEC_H
   44: 
   45: #ifdef ENABLE_HYBRID
   46: #include <arpa/inet.h>
   47: #endif
   48: 
   49: #include <stdlib.h>
   50: #include <stdio.h>
   51: #include <string.h>
   52: #include <errno.h>
   53: #include <netdb.h>
   54: #include <pwd.h>
   55: #include <grp.h>
   56: 
   57: #include "var.h"
   58: #include "misc.h"
   59: #include "vmbuf.h"
   60: #include "plog.h"
   61: #include "sockmisc.h"
   62: #include "str2val.h"
   63: #include "genlist.h"
   64: #include "debug.h"
   65: 
   66: #include "admin.h"
   67: #include "privsep.h"
   68: #include "cfparse_proto.h"
   69: #include "cftoken_proto.h"
   70: #include "algorithm.h"
   71: #include "localconf.h"
   72: #include "policy.h"
   73: #include "sainfo.h"
   74: #include "oakley.h"
   75: #include "pfkey.h"
   76: #include "remoteconf.h"
   77: #include "grabmyaddr.h"
   78: #include "isakmp_var.h"
   79: #include "handler.h"
   80: #include "isakmp.h"
   81: #include "nattraversal.h"
   82: #include "isakmp_frag.h"
   83: #ifdef ENABLE_HYBRID
   84: #include "resolv.h"
   85: #include "isakmp_unity.h"
   86: #include "isakmp_xauth.h"
   87: #include "isakmp_cfg.h"
   88: #endif
   89: #include "ipsec_doi.h"
   90: #include "strnames.h"
   91: #include "gcmalloc.h"
   92: #ifdef HAVE_GSSAPI
   93: #include "gssapi.h"
   94: #endif
   95: #include "vendorid.h"
   96: #include "rsalist.h"
   97: #include "crypto_openssl.h"
   98: 
   99: struct secprotospec {
  100: 	int prop_no;
  101: 	int trns_no;
  102: 	int strength;		/* for isakmp/ipsec */
  103: 	int encklen;		/* for isakmp/ipsec */
  104: 	time_t lifetime;	/* for isakmp */
  105: 	int lifebyte;		/* for isakmp */
  106: 	int proto_id;		/* for ipsec (isakmp?) */
  107: 	int ipsec_level;	/* for ipsec */
  108: 	int encmode;		/* for ipsec */
  109: 	int vendorid;		/* for isakmp */
  110: 	char *gssid;
  111: 	struct sockaddr *remote;
  112: 	int algclass[MAXALGCLASS];
  113: 
  114: 	struct secprotospec *next;	/* the tail is the most prefiered. */
  115: 	struct secprotospec *prev;
  116: };
  117: 
  118: static int num2dhgroup[] = {
  119: 	0,
  120: 	OAKLEY_ATTR_GRP_DESC_MODP768,
  121: 	OAKLEY_ATTR_GRP_DESC_MODP1024,
  122: 	OAKLEY_ATTR_GRP_DESC_EC2N155,
  123: 	OAKLEY_ATTR_GRP_DESC_EC2N185,
  124: 	OAKLEY_ATTR_GRP_DESC_MODP1536,
  125: 	0,
  126: 	0,
  127: 	0,
  128: 	0,
  129: 	0,
  130: 	0,
  131: 	0,
  132: 	0,
  133: 	OAKLEY_ATTR_GRP_DESC_MODP2048,
  134: 	OAKLEY_ATTR_GRP_DESC_MODP3072,
  135: 	OAKLEY_ATTR_GRP_DESC_MODP4096,
  136: 	OAKLEY_ATTR_GRP_DESC_MODP6144,
  137: 	OAKLEY_ATTR_GRP_DESC_MODP8192
  138: };
  139: 
  140: static struct remoteconf *cur_rmconf;
  141: static int tmpalgtype[MAXALGCLASS];
  142: static struct sainfo *cur_sainfo;
  143: static int cur_algclass;
  144: static int oldloglevel = LLV_BASE;
  145: 
  146: static struct secprotospec *newspspec __P((void));
  147: static void insspspec __P((struct remoteconf *, struct secprotospec *));
  148: void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src));
  149: void flushspspec __P((struct remoteconf *));
  150: static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int));
  151: 
  152: static int set_isakmp_proposal __P((struct remoteconf *));
  153: static void clean_tmpalgtype __P((void));
  154: static int expand_isakmpspec __P((int, int, int *,
  155: 	int, int, time_t, int, int, int, char *, struct remoteconf *));
  156: 
  157: void freeetypes (struct etypes **etypes);
  158: 
  159: static int load_x509(const char *file, char **filenameptr,
  160: 		     vchar_t **certptr)
  161: {
  162: 	char path[PATH_MAX];
  163: 
  164: 	getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file);
  165: 	*certptr = eay_get_x509cert(path);
  166: 	if (*certptr == NULL)
  167: 		return -1;
  168: 
  169: 	*filenameptr = racoon_strdup(file);
  170: 	STRDUP_FATAL(*filenameptr);
  171: 
  172: 	return 0;
  173: }
  174: 
  175: static int process_rmconf()
  176: {
  177: 
  178: 	/* check a exchange mode */
  179: 	if (cur_rmconf->etypes == NULL) {
  180: 		yyerror("no exchange mode specified.\n");
  181: 		return -1;
  182: 	}
  183: 
  184: 	if (cur_rmconf->idvtype == IDTYPE_UNDEFINED)
  185: 		cur_rmconf->idvtype = IDTYPE_ADDRESS;
  186: 
  187: 	if (cur_rmconf->idvtype == IDTYPE_ASN1DN) {
  188: 		if (cur_rmconf->mycertfile) {
  189: 			if (cur_rmconf->idv)
  190: 				yywarn("Both CERT and ASN1 ID "
  191: 				       "are set. Hope this is OK.\n");
  192: 			/* TODO: Preparse the DN here */
  193: 		} else if (cur_rmconf->idv) {
  194: 			/* OK, using asn1dn without X.509. */
  195: 		} else {
  196: 			yyerror("ASN1 ID not specified "
  197: 				"and no CERT defined!\n");
  198: 			return -1;
  199: 		}
  200: 	}
  201: 
  202: 	if (duprmconf_finish(cur_rmconf))
  203: 		return -1;
  204: 
  205: 	if (set_isakmp_proposal(cur_rmconf) != 0)
  206: 		return -1;
  207: 
  208: 	/* DH group settting if aggressive mode is there. */
  209: 	if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) {
  210: 		struct isakmpsa *p;
  211: 		int b = 0;
  212: 
  213: 		/* DH group */
  214: 		for (p = cur_rmconf->proposal; p; p = p->next) {
  215: 			if (b == 0 || (b && b == p->dh_group)) {
  216: 				b = p->dh_group;
  217: 				continue;
  218: 			}
  219: 			yyerror("DH group must be equal "
  220: 				"in all proposals "
  221: 				"when aggressive mode is "
  222: 				"used.\n");
  223: 			return -1;
  224: 		}
  225: 		cur_rmconf->dh_group = b;
  226: 
  227: 		if (cur_rmconf->dh_group == 0) {
  228: 			yyerror("DH group must be set in the proposal.\n");
  229: 			return -1;
  230: 		}
  231: 
  232: 		/* DH group settting if PFS is required. */
  233: 		if (oakley_setdhgroup(cur_rmconf->dh_group,
  234: 				&cur_rmconf->dhgrp) < 0) {
  235: 			yyerror("failed to set DH value.\n");
  236: 			return -1;
  237: 		}
  238: 	}
  239: 
  240: 	insrmconf(cur_rmconf);
  241: 
  242: 	return 0;
  243: }
  244: 
  245: %}
  246: 
  247: %union {
  248: 	unsigned long num;
  249: 	vchar_t *val;
  250: 	struct remoteconf *rmconf;
  251: 	struct sockaddr *saddr;
  252: 	struct sainfoalg *alg;
  253: }
  254: 
  255: 	/* privsep */
  256: %token PRIVSEP USER GROUP CHROOT
  257: 	/* path */
  258: %token PATH PATHTYPE
  259: 	/* include */
  260: %token INCLUDE
  261: 	/* PFKEY_BUFFER */
  262: %token PFKEY_BUFFER
  263: 	/* logging */
  264: %token LOGGING LOGLEV
  265: 	/* padding */
  266: %token PADDING PAD_RANDOMIZE PAD_RANDOMIZELEN PAD_MAXLEN PAD_STRICT PAD_EXCLTAIL
  267: 	/* listen */
  268: %token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED
  269: 	/* ldap config */
  270: %token LDAPCFG LDAP_HOST LDAP_PORT LDAP_PVER LDAP_BASE LDAP_BIND_DN LDAP_BIND_PW LDAP_SUBTREE
  271: %token LDAP_ATTR_USER LDAP_ATTR_ADDR LDAP_ATTR_MASK LDAP_ATTR_GROUP LDAP_ATTR_MEMBER
  272: 	/* radius config */
  273: %token RADCFG RAD_AUTH RAD_ACCT RAD_TIMEOUT RAD_RETRIES
  274: 	/* modecfg */
  275: %token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN
  276: %token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE
  277: %token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE
  278: %token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS
  279: %token CFG_PFS_GROUP CFG_SAVE_PASSWD
  280: 
  281: 	/* timer */
  282: %token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND
  283: %token RETRY_PHASE1 RETRY_PHASE2 NATT_KA
  284: 	/* algorithm */
  285: %token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE
  286: 	/* sainfo */
  287: %token SAINFO FROM
  288: 	/* remote */
  289: %token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS
  290: %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE
  291: %token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE
  292: %token VERIFY_CERT SEND_CERT SEND_CR MATCH_EMPTY_CR
  293: %token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER 
  294: %token PEERS_IDENTIFIER VERIFY_IDENTIFIER
  295: %token DNSSEC CERT_X509 CERT_PLAINRSA
  296: %token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT
  297: %token NAT_TRAVERSAL REMOTE_FORCE_LEVEL
  298: %token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL
  299: %token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY
  300: %token PROPOSAL
  301: %token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE
  302: %token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE
  303: %token COMPLEX_BUNDLE
  304: %token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL
  305: %token PH1ID
  306: %token XAUTH_LOGIN WEAK_PHASE1_CHECK
  307: %token REKEY
  308: 
  309: %token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG
  310: %token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID
  311: 
  312: %token SCRIPT PHASE1_UP PHASE1_DOWN PHASE1_DEAD
  313: 
  314: %token NUMBER SWITCH BOOLEAN
  315: %token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE
  316: %token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES
  317: %token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR
  318: %token EOS BOC EOC COMMA
  319: 
  320: %type <num> NUMBER BOOLEAN SWITCH keylength
  321: %type <num> PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE 
  322: %type <num> ALGORITHM_CLASS dh_group_num
  323: %type <num> ALGORITHMTYPE STRENGTHTYPE
  324: %type <num> PREFIX prefix PORT port ike_port
  325: %type <num> ul_proto UL_PROTO
  326: %type <num> EXCHANGETYPE DOITYPE SITUATIONTYPE
  327: %type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL REMOTE_FORCE_LEVEL GENERATE_LEVEL
  328: %type <num> unittype_time unittype_byte
  329: %type <val> QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id
  330: %type <val> identifierstring
  331: %type <saddr> remote_index ike_addrinfo_port
  332: %type <alg> algorithm
  333: 
  334: %%
  335: 
  336: statements
  337: 	:	/* nothing */
  338: 	|	statements statement
  339: 	;
  340: statement
  341: 	:	privsep_statement
  342: 	|	path_statement
  343: 	|	include_statement
  344: 	|	pfkey_statement
  345: 	|	gssenc_statement
  346: 	|	logging_statement
  347: 	|	padding_statement
  348: 	|	listen_statement
  349: 	|	ldapcfg_statement
  350: 	|	radcfg_statement
  351: 	|	modecfg_statement
  352: 	|	timer_statement
  353: 	|	sainfo_statement
  354: 	|	remote_statement
  355: 	|	special_statement
  356: 	;
  357: 
  358: 	/* privsep */
  359: privsep_statement
  360: 	:	PRIVSEP BOC privsep_stmts EOC
  361: 	;
  362: privsep_stmts
  363: 	:	/* nothing */
  364: 	|	privsep_stmts privsep_stmt
  365: 	;
  366: privsep_stmt
  367: 	:	USER QUOTEDSTRING
  368: 		{
  369: 			struct passwd *pw;
  370: 
  371: 			if ((pw = getpwnam($2->v)) == NULL) {
  372: 				yyerror("unknown user \"%s\"", $2->v);
  373: 				return -1;
  374: 			}
  375: 			lcconf->uid = pw->pw_uid;
  376: 		} 
  377: 		EOS
  378: 	|	USER NUMBER { lcconf->uid = $2; } EOS
  379: 	|	GROUP QUOTEDSTRING
  380: 		{
  381: 			struct group *gr;
  382: 
  383: 			if ((gr = getgrnam($2->v)) == NULL) {
  384: 				yyerror("unknown group \"%s\"", $2->v);
  385: 				return -1;
  386: 			}
  387: 			lcconf->gid = gr->gr_gid;
  388: 		}
  389: 		EOS
  390: 	|	GROUP NUMBER { lcconf->gid = $2; } EOS
  391: 	|	CHROOT QUOTEDSTRING { lcconf->chroot = $2->v; } EOS
  392: 	;
  393: 
  394: 	/* path */
  395: path_statement
  396: 	:	PATH PATHTYPE QUOTEDSTRING
  397: 		{
  398: 			if ($2 >= LC_PATHTYPE_MAX) {
  399: 				yyerror("invalid path type %d", $2);
  400: 				return -1;
  401: 			}
  402: 
  403: 			/* free old pathinfo */
  404: 			if (lcconf->pathinfo[$2])
  405: 				racoon_free(lcconf->pathinfo[$2]);
  406: 
  407: 			/* set new pathinfo */
  408: 			lcconf->pathinfo[$2] = racoon_strdup($3->v);
  409: 			STRDUP_FATAL(lcconf->pathinfo[$2]);
  410: 			vfree($3);
  411: 		}
  412: 		EOS
  413: 	;
  414: 
  415: 	/* special */
  416: special_statement
  417: 	:	COMPLEX_BUNDLE SWITCH { lcconf->complex_bundle = $2; } EOS
  418: 	;
  419: 
  420: 	/* include */
  421: include_statement
  422: 	:	INCLUDE QUOTEDSTRING EOS
  423: 		{
  424: 			char path[MAXPATHLEN];
  425: 
  426: 			getpathname(path, sizeof(path),
  427: 				LC_PATHTYPE_INCLUDE, $2->v);
  428: 			vfree($2);
  429: 			if (yycf_switch_buffer(path) != 0)
  430: 				return -1;
  431: 		}
  432: 	;
  433: 
  434:     /* pfkey_buffer */
  435: pfkey_statement
  436:     :   PFKEY_BUFFER NUMBER EOS
  437:         {
  438: 			lcconf->pfkey_buffer_size = $2;
  439:         }
  440:     ;
  441: 	/* gss_id_enc */
  442: gssenc_statement
  443: 	:	GSS_ID_ENC GSS_ID_ENCTYPE EOS
  444: 		{
  445: 			if ($2 >= LC_GSSENC_MAX) {
  446: 				yyerror("invalid GSS ID encoding %d", $2);
  447: 				return -1;
  448: 			}
  449: 			lcconf->gss_id_enc = $2;
  450: 		}
  451: 	;
  452: 
  453: 	/* logging */
  454: logging_statement
  455: 	:	LOGGING log_level EOS
  456: 	;
  457: log_level
  458: 	:	LOGLEV
  459: 		{
  460: 			/*
  461: 			 * set the loglevel to the value specified
  462: 			 * in the configuration file plus the number
  463: 			 * of -d options specified on the command line
  464: 			 */
  465: 			loglevel += $1 - oldloglevel;
  466: 			oldloglevel = $1;
  467: 		}
  468: 	;
  469: 
  470: 	/* padding */
  471: padding_statement
  472: 	:	PADDING BOC padding_stmts EOC
  473: 	;
  474: padding_stmts
  475: 	:	/* nothing */
  476: 	|	padding_stmts padding_stmt
  477: 	;
  478: padding_stmt
  479: 	:	PAD_RANDOMIZE SWITCH { lcconf->pad_random = $2; } EOS
  480: 	|	PAD_RANDOMIZELEN SWITCH { lcconf->pad_randomlen = $2; } EOS
  481: 	|	PAD_MAXLEN NUMBER { lcconf->pad_maxsize = $2; } EOS
  482: 	|	PAD_STRICT SWITCH { lcconf->pad_strict = $2; } EOS
  483: 	|	PAD_EXCLTAIL SWITCH { lcconf->pad_excltail = $2; } EOS
  484: 	;
  485: 
  486: 	/* listen */
  487: listen_statement
  488: 	:	LISTEN BOC listen_stmts EOC
  489: 	;
  490: listen_stmts
  491: 	:	/* nothing */
  492: 	|	listen_stmts listen_stmt
  493: 	;
  494: listen_stmt
  495: 	:	X_ISAKMP ike_addrinfo_port
  496: 		{
  497: 			myaddr_listen($2, FALSE);
  498: 			racoon_free($2);
  499: 		}
  500: 		EOS
  501: 	|	X_ISAKMP_NATT ike_addrinfo_port
  502: 		{
  503: #ifdef ENABLE_NATT
  504: 			myaddr_listen($2, TRUE);
  505: 			racoon_free($2);
  506: #else
  507: 			racoon_free($2);
  508: 			yyerror("NAT-T support not compiled in.");
  509: #endif
  510: 		}
  511: 		EOS
  512: 	|	ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER 
  513: 		{
  514: #ifdef ENABLE_ADMINPORT
  515: 			adminsock_conf($2, $3, $4, $5);
  516: #else
  517: 			yywarn("admin port support not compiled in");
  518: #endif
  519: 		}
  520: 		EOS
  521: 	|	ADMINSOCK QUOTEDSTRING
  522: 		{
  523: #ifdef ENABLE_ADMINPORT
  524: 			adminsock_conf($2, NULL, NULL, -1);
  525: #else
  526: 			yywarn("admin port support not compiled in");
  527: #endif
  528: 		}
  529: 		EOS
  530: 	|	ADMINSOCK DISABLED
  531: 		{
  532: #ifdef ENABLE_ADMINPORT
  533: 			adminsock_path = NULL;
  534: #else
  535: 			yywarn("admin port support not compiled in");
  536: #endif
  537: 		}
  538: 		EOS
  539: 	|	STRICT_ADDRESS { lcconf->strict_address = TRUE; } EOS
  540: 	;
  541: ike_addrinfo_port
  542: 	:	ADDRSTRING ike_port
  543: 		{
  544: 			char portbuf[10];
  545: 
  546: 			snprintf(portbuf, sizeof(portbuf), "%ld", $2);
  547: 			$$ = str2saddr($1->v, portbuf);
  548: 			vfree($1);
  549: 			if (!$$)
  550: 				return -1;
  551: 		}
  552: 	;
  553: ike_port
  554: 	:	/* nothing */	{ $$ = PORT_ISAKMP; }
  555: 	|	PORT		{ $$ = $1; }
  556: 	;
  557: 
  558: 	/* radius configuration */
  559: radcfg_statement
  560: 	:	RADCFG {
  561: #ifndef ENABLE_HYBRID
  562: 			yyerror("racoon not configured with --enable-hybrid");
  563: 			return -1;
  564: #endif
  565: #ifndef HAVE_LIBRADIUS
  566: 			yyerror("racoon not configured with --with-libradius");
  567: 			return -1;
  568: #endif
  569: #ifdef ENABLE_HYBRID
  570: #ifdef HAVE_LIBRADIUS
  571: 			xauth_rad_config.timeout = 3;
  572: 			xauth_rad_config.retries = 3;
  573: #endif
  574: #endif
  575: 		} BOC radcfg_stmts EOC
  576: 	;
  577: radcfg_stmts
  578: 	:	/* nothing */
  579: 	|	radcfg_stmts radcfg_stmt
  580: 	;
  581: radcfg_stmt
  582: 	:	RAD_AUTH QUOTEDSTRING QUOTEDSTRING
  583: 		{
  584: #ifdef ENABLE_HYBRID
  585: #ifdef HAVE_LIBRADIUS
  586: 			int i = xauth_rad_config.auth_server_count;
  587: 			if (i == RADIUS_MAX_SERVERS) {
  588: 				yyerror("maximum radius auth servers exceeded");
  589: 				return -1;
  590: 			}
  591: 
  592: 			xauth_rad_config.auth_server_list[i].host = vdup($2);
  593: 			xauth_rad_config.auth_server_list[i].secret = vdup($3);
  594: 			xauth_rad_config.auth_server_list[i].port = 0; // default port
  595: 			xauth_rad_config.auth_server_count++;
  596: #endif
  597: #endif
  598: 		}
  599: 		EOS
  600: 	|	RAD_AUTH QUOTEDSTRING NUMBER QUOTEDSTRING
  601: 		{
  602: #ifdef ENABLE_HYBRID
  603: #ifdef HAVE_LIBRADIUS
  604: 			int i = xauth_rad_config.auth_server_count;
  605: 			if (i == RADIUS_MAX_SERVERS) {
  606: 				yyerror("maximum radius auth servers exceeded");
  607: 				return -1;
  608: 			}
  609: 
  610: 			xauth_rad_config.auth_server_list[i].host = vdup($2);
  611: 			xauth_rad_config.auth_server_list[i].secret = vdup($4);
  612: 			xauth_rad_config.auth_server_list[i].port = $3;
  613: 			xauth_rad_config.auth_server_count++;
  614: #endif
  615: #endif
  616: 		}
  617: 		EOS
  618: 	|	RAD_ACCT QUOTEDSTRING QUOTEDSTRING
  619: 		{
  620: #ifdef ENABLE_HYBRID
  621: #ifdef HAVE_LIBRADIUS
  622: 			int i = xauth_rad_config.acct_server_count;
  623: 			if (i == RADIUS_MAX_SERVERS) {
  624: 				yyerror("maximum radius account servers exceeded");
  625: 				return -1;
  626: 			}
  627: 
  628: 			xauth_rad_config.acct_server_list[i].host = vdup($2);
  629: 			xauth_rad_config.acct_server_list[i].secret = vdup($3);
  630: 			xauth_rad_config.acct_server_list[i].port = 0; // default port
  631: 			xauth_rad_config.acct_server_count++;
  632: #endif
  633: #endif
  634: 		}
  635: 		EOS
  636: 	|	RAD_ACCT QUOTEDSTRING NUMBER QUOTEDSTRING
  637: 		{
  638: #ifdef ENABLE_HYBRID
  639: #ifdef HAVE_LIBRADIUS
  640: 			int i = xauth_rad_config.acct_server_count;
  641: 			if (i == RADIUS_MAX_SERVERS) {
  642: 				yyerror("maximum radius account servers exceeded");
  643: 				return -1;
  644: 			}
  645: 
  646: 			xauth_rad_config.acct_server_list[i].host = vdup($2);
  647: 			xauth_rad_config.acct_server_list[i].secret = vdup($4);
  648: 			xauth_rad_config.acct_server_list[i].port = $3;
  649: 			xauth_rad_config.acct_server_count++;
  650: #endif
  651: #endif
  652: 		}
  653: 		EOS
  654: 	|	RAD_TIMEOUT NUMBER
  655: 		{
  656: #ifdef ENABLE_HYBRID
  657: #ifdef HAVE_LIBRADIUS
  658: 			xauth_rad_config.timeout = $2;
  659: #endif
  660: #endif
  661: 		}
  662: 		EOS
  663: 	|	RAD_RETRIES NUMBER
  664: 		{
  665: #ifdef ENABLE_HYBRID
  666: #ifdef HAVE_LIBRADIUS
  667: 			xauth_rad_config.retries = $2;
  668: #endif
  669: #endif
  670: 		}
  671: 		EOS
  672: 	;
  673: 
  674: 	/* ldap configuration */
  675: ldapcfg_statement
  676: 	:	LDAPCFG {
  677: #ifndef ENABLE_HYBRID
  678: 			yyerror("racoon not configured with --enable-hybrid");
  679: 			return -1;
  680: #endif
  681: #ifndef HAVE_LIBLDAP
  682: 			yyerror("racoon not configured with --with-libldap");
  683: 			return -1;
  684: #endif
  685: 		} BOC ldapcfg_stmts EOC
  686: 	;
  687: ldapcfg_stmts
  688: 	:	/* nothing */
  689: 	|	ldapcfg_stmts ldapcfg_stmt
  690: 	;
  691: ldapcfg_stmt
  692: 	:	LDAP_PVER NUMBER
  693: 		{
  694: #ifdef ENABLE_HYBRID
  695: #ifdef HAVE_LIBLDAP
  696: 			if (($2<2)||($2>3))
  697: 				yyerror("invalid ldap protocol version (2|3)");
  698: 			xauth_ldap_config.pver = $2;
  699: #endif
  700: #endif
  701: 		}
  702: 		EOS
  703: 	|	LDAP_HOST QUOTEDSTRING
  704: 		{
  705: #ifdef ENABLE_HYBRID
  706: #ifdef HAVE_LIBLDAP
  707: 			if (xauth_ldap_config.host != NULL)
  708: 				vfree(xauth_ldap_config.host);
  709: 			xauth_ldap_config.host = vdup($2);
  710: #endif
  711: #endif
  712: 		}
  713: 		EOS
  714: 	|	LDAP_PORT NUMBER
  715: 		{
  716: #ifdef ENABLE_HYBRID
  717: #ifdef HAVE_LIBLDAP
  718: 			xauth_ldap_config.port = $2;
  719: #endif
  720: #endif
  721: 		}
  722: 		EOS
  723: 	|	LDAP_BASE QUOTEDSTRING
  724: 		{
  725: #ifdef ENABLE_HYBRID
  726: #ifdef HAVE_LIBLDAP
  727: 			if (xauth_ldap_config.base != NULL)
  728: 				vfree(xauth_ldap_config.base);
  729: 			xauth_ldap_config.base = vdup($2);
  730: #endif
  731: #endif
  732: 		}
  733: 		EOS
  734: 	|	LDAP_SUBTREE SWITCH
  735: 		{
  736: #ifdef ENABLE_HYBRID
  737: #ifdef HAVE_LIBLDAP
  738: 			xauth_ldap_config.subtree = $2;
  739: #endif
  740: #endif
  741: 		}
  742: 		EOS
  743: 	|	LDAP_BIND_DN QUOTEDSTRING
  744: 		{
  745: #ifdef ENABLE_HYBRID
  746: #ifdef HAVE_LIBLDAP
  747: 			if (xauth_ldap_config.bind_dn != NULL)
  748: 				vfree(xauth_ldap_config.bind_dn);
  749: 			xauth_ldap_config.bind_dn = vdup($2);
  750: #endif
  751: #endif
  752: 		}
  753: 		EOS
  754: 	|	LDAP_BIND_PW QUOTEDSTRING
  755: 		{
  756: #ifdef ENABLE_HYBRID
  757: #ifdef HAVE_LIBLDAP
  758: 			if (xauth_ldap_config.bind_pw != NULL)
  759: 				vfree(xauth_ldap_config.bind_pw);
  760: 			xauth_ldap_config.bind_pw = vdup($2);
  761: #endif
  762: #endif
  763: 		}
  764: 		EOS
  765: 	|	LDAP_ATTR_USER QUOTEDSTRING
  766: 		{
  767: #ifdef ENABLE_HYBRID
  768: #ifdef HAVE_LIBLDAP
  769: 			if (xauth_ldap_config.attr_user != NULL)
  770: 				vfree(xauth_ldap_config.attr_user);
  771: 			xauth_ldap_config.attr_user = vdup($2);
  772: #endif
  773: #endif
  774: 		}
  775: 		EOS
  776: 	|	LDAP_ATTR_ADDR QUOTEDSTRING
  777: 		{
  778: #ifdef ENABLE_HYBRID
  779: #ifdef HAVE_LIBLDAP
  780: 			if (xauth_ldap_config.attr_addr != NULL)
  781: 				vfree(xauth_ldap_config.attr_addr);
  782: 			xauth_ldap_config.attr_addr = vdup($2);
  783: #endif
  784: #endif
  785: 		}
  786: 		EOS
  787: 	|	LDAP_ATTR_MASK QUOTEDSTRING
  788: 		{
  789: #ifdef ENABLE_HYBRID
  790: #ifdef HAVE_LIBLDAP
  791: 			if (xauth_ldap_config.attr_mask != NULL)
  792: 				vfree(xauth_ldap_config.attr_mask);
  793: 			xauth_ldap_config.attr_mask = vdup($2);
  794: #endif
  795: #endif
  796: 		}
  797: 		EOS
  798: 	|	LDAP_ATTR_GROUP QUOTEDSTRING
  799: 		{
  800: #ifdef ENABLE_HYBRID
  801: #ifdef HAVE_LIBLDAP
  802: 			if (xauth_ldap_config.attr_group != NULL)
  803: 				vfree(xauth_ldap_config.attr_group);
  804: 			xauth_ldap_config.attr_group = vdup($2);
  805: #endif
  806: #endif
  807: 		}
  808: 		EOS
  809: 	|	LDAP_ATTR_MEMBER QUOTEDSTRING
  810: 		{
  811: #ifdef ENABLE_HYBRID
  812: #ifdef HAVE_LIBLDAP
  813: 			if (xauth_ldap_config.attr_member != NULL)
  814: 				vfree(xauth_ldap_config.attr_member);
  815: 			xauth_ldap_config.attr_member = vdup($2);
  816: #endif
  817: #endif
  818: 		}
  819: 		EOS
  820: 	;
  821: 
  822: 	/* modecfg */
  823: modecfg_statement
  824: 	:	MODECFG BOC modecfg_stmts EOC
  825: 	;
  826: modecfg_stmts
  827: 	:	/* nothing */
  828: 	|	modecfg_stmts modecfg_stmt
  829: 	;
  830: modecfg_stmt
  831: 	:	CFG_NET4 ADDRSTRING
  832: 		{
  833: #ifdef ENABLE_HYBRID
  834: 			if (inet_pton(AF_INET, $2->v,
  835: 			     &isakmp_cfg_config.network4) != 1)
  836: 				yyerror("bad IPv4 network address.");
  837: #else
  838: 			yyerror("racoon not configured with --enable-hybrid");
  839: #endif
  840: 		}
  841: 		EOS
  842: 	|	CFG_MASK4 ADDRSTRING
  843: 		{
  844: #ifdef ENABLE_HYBRID
  845: 			if (inet_pton(AF_INET, $2->v,
  846: 			    &isakmp_cfg_config.netmask4) != 1)
  847: 				yyerror("bad IPv4 netmask address.");
  848: #else
  849: 			yyerror("racoon not configured with --enable-hybrid");
  850: #endif
  851: 		}
  852: 		EOS
  853: 	|	CFG_DNS4 addrdnslist
  854: 		EOS
  855: 	|	CFG_NBNS4 addrwinslist
  856: 		EOS
  857: 	|	CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist
  858: 		{
  859: #ifdef ENABLE_HYBRID
  860: 			isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN;
  861: #else
  862: 			yyerror("racoon not configured with --enable-hybrid");
  863: #endif
  864: 		}
  865: 		EOS
  866: 	|	CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist
  867: 		{
  868: #ifdef ENABLE_HYBRID
  869: 			isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE;
  870: #else
  871: 			yyerror("racoon not configured with --enable-hybrid");
  872: #endif
  873: 		}
  874: 		EOS
  875: 	|	CFG_SPLIT_DNS splitdnslist
  876: 		{
  877: #ifndef ENABLE_HYBRID
  878: 			yyerror("racoon not configured with --enable-hybrid");
  879: #endif
  880: 		}
  881: 		EOS
  882: 	|	CFG_DEFAULT_DOMAIN QUOTEDSTRING
  883: 		{
  884: #ifdef ENABLE_HYBRID
  885: 			strncpy(&isakmp_cfg_config.default_domain[0], 
  886: 			    $2->v, MAXPATHLEN);
  887: 			isakmp_cfg_config.default_domain[MAXPATHLEN] = '\0';
  888: 			vfree($2);
  889: #else
  890: 			yyerror("racoon not configured with --enable-hybrid");
  891: #endif
  892: 		}
  893: 		EOS
  894: 	|	CFG_AUTH_SOURCE CFG_SYSTEM
  895: 		{
  896: #ifdef ENABLE_HYBRID
  897: 			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
  898: #else
  899: 			yyerror("racoon not configured with --enable-hybrid");
  900: #endif
  901: 		}
  902: 		EOS
  903: 	|	CFG_AUTH_SOURCE CFG_RADIUS
  904: 		{
  905: #ifdef ENABLE_HYBRID
  906: #ifdef HAVE_LIBRADIUS
  907: 			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_RADIUS;
  908: #else /* HAVE_LIBRADIUS */
  909: 			yyerror("racoon not configured with --with-libradius");
  910: #endif /* HAVE_LIBRADIUS */
  911: #else /* ENABLE_HYBRID */
  912: 			yyerror("racoon not configured with --enable-hybrid");
  913: #endif /* ENABLE_HYBRID */
  914: 		}
  915: 		EOS
  916: 	|	CFG_AUTH_SOURCE CFG_PAM
  917: 		{
  918: #ifdef ENABLE_HYBRID
  919: #ifdef HAVE_LIBPAM
  920: 			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_PAM;
  921: #else /* HAVE_LIBPAM */
  922: 			yyerror("racoon not configured with --with-libpam");
  923: #endif /* HAVE_LIBPAM */
  924: #else /* ENABLE_HYBRID */
  925: 			yyerror("racoon not configured with --enable-hybrid");
  926: #endif /* ENABLE_HYBRID */
  927: 		}
  928: 		EOS
  929: 	|	CFG_AUTH_SOURCE CFG_LDAP
  930: 		{
  931: #ifdef ENABLE_HYBRID
  932: #ifdef HAVE_LIBLDAP
  933: 			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP;
  934: #else /* HAVE_LIBLDAP */
  935: 			yyerror("racoon not configured with --with-libldap");
  936: #endif /* HAVE_LIBLDAP */
  937: #else /* ENABLE_HYBRID */
  938: 			yyerror("racoon not configured with --enable-hybrid");
  939: #endif /* ENABLE_HYBRID */
  940: 		}
  941: 		EOS
  942: 	|	CFG_AUTH_GROUPS authgrouplist
  943: 		{
  944: #ifndef ENABLE_HYBRID
  945: 			yyerror("racoon not configured with --enable-hybrid");
  946: #endif
  947: 		}
  948: 		EOS
  949: 	|	CFG_GROUP_SOURCE CFG_SYSTEM
  950: 		{
  951: #ifdef ENABLE_HYBRID
  952: 			isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
  953: #else
  954: 			yyerror("racoon not configured with --enable-hybrid");
  955: #endif
  956: 		}
  957: 		EOS
  958: 	|	CFG_GROUP_SOURCE CFG_LDAP
  959: 		{
  960: #ifdef ENABLE_HYBRID
  961: #ifdef HAVE_LIBLDAP
  962: 			isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP;
  963: #else /* HAVE_LIBLDAP */
  964: 			yyerror("racoon not configured with --with-libldap");
  965: #endif /* HAVE_LIBLDAP */
  966: #else /* ENABLE_HYBRID */
  967: 			yyerror("racoon not configured with --enable-hybrid");
  968: #endif /* ENABLE_HYBRID */
  969: 		}
  970: 		EOS
  971: 	|	CFG_ACCOUNTING CFG_NONE
  972: 		{
  973: #ifdef ENABLE_HYBRID
  974: 			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
  975: #else
  976: 			yyerror("racoon not configured with --enable-hybrid");
  977: #endif
  978: 		}
  979: 		EOS
  980: 	|	CFG_ACCOUNTING CFG_SYSTEM
  981: 		{
  982: #ifdef ENABLE_HYBRID
  983: 			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM;
  984: #else
  985: 			yyerror("racoon not configured with --enable-hybrid");
  986: #endif
  987: 		}
  988: 		EOS
  989: 	|	CFG_ACCOUNTING CFG_RADIUS
  990: 		{
  991: #ifdef ENABLE_HYBRID
  992: #ifdef HAVE_LIBRADIUS
  993: 			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_RADIUS;
  994: #else /* HAVE_LIBRADIUS */
  995: 			yyerror("racoon not configured with --with-libradius");
  996: #endif /* HAVE_LIBRADIUS */
  997: #else /* ENABLE_HYBRID */
  998: 			yyerror("racoon not configured with --enable-hybrid");
  999: #endif /* ENABLE_HYBRID */
 1000: 		}
 1001: 		EOS
 1002: 	|	CFG_ACCOUNTING CFG_PAM
 1003: 		{
 1004: #ifdef ENABLE_HYBRID
 1005: #ifdef HAVE_LIBPAM
 1006: 			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_PAM;
 1007: #else /* HAVE_LIBPAM */
 1008: 			yyerror("racoon not configured with --with-libpam");
 1009: #endif /* HAVE_LIBPAM */
 1010: #else /* ENABLE_HYBRID */
 1011: 			yyerror("racoon not configured with --enable-hybrid");
 1012: #endif /* ENABLE_HYBRID */
 1013: 		}
 1014: 		EOS
 1015: 	|	CFG_POOL_SIZE NUMBER
 1016: 		{
 1017: #ifdef ENABLE_HYBRID
 1018: 			if (isakmp_cfg_resize_pool($2) != 0)
 1019: 				yyerror("cannot allocate memory for pool");
 1020: #else /* ENABLE_HYBRID */
 1021: 			yyerror("racoon not configured with --enable-hybrid");
 1022: #endif /* ENABLE_HYBRID */
 1023: 		}
 1024: 		EOS
 1025: 	|	CFG_PFS_GROUP NUMBER
 1026: 		{
 1027: #ifdef ENABLE_HYBRID
 1028: 			isakmp_cfg_config.pfs_group = $2;
 1029: #else /* ENABLE_HYBRID */
 1030: 			yyerror("racoon not configured with --enable-hybrid");
 1031: #endif /* ENABLE_HYBRID */
 1032: 		}
 1033: 		EOS
 1034: 	|	CFG_SAVE_PASSWD SWITCH
 1035: 		{
 1036: #ifdef ENABLE_HYBRID
 1037: 			isakmp_cfg_config.save_passwd = $2;
 1038: #else /* ENABLE_HYBRID */
 1039: 			yyerror("racoon not configured with --enable-hybrid");
 1040: #endif /* ENABLE_HYBRID */
 1041: 		}
 1042: 		EOS
 1043: 	|	CFG_AUTH_THROTTLE NUMBER
 1044: 		{
 1045: #ifdef ENABLE_HYBRID
 1046: 			isakmp_cfg_config.auth_throttle = $2;
 1047: #else /* ENABLE_HYBRID */
 1048: 			yyerror("racoon not configured with --enable-hybrid");
 1049: #endif /* ENABLE_HYBRID */
 1050: 		}
 1051: 		EOS
 1052: 	|	CFG_CONF_SOURCE CFG_LOCAL
 1053: 		{
 1054: #ifdef ENABLE_HYBRID
 1055: 			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
 1056: #else /* ENABLE_HYBRID */
 1057: 			yyerror("racoon not configured with --enable-hybrid");
 1058: #endif /* ENABLE_HYBRID */
 1059: 		}
 1060: 		EOS
 1061: 	|	CFG_CONF_SOURCE CFG_RADIUS
 1062: 		{
 1063: #ifdef ENABLE_HYBRID
 1064: #ifdef HAVE_LIBRADIUS
 1065: 			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_RADIUS;
 1066: #else /* HAVE_LIBRADIUS */
 1067: 			yyerror("racoon not configured with --with-libradius");
 1068: #endif /* HAVE_LIBRADIUS */
 1069: #else /* ENABLE_HYBRID */
 1070: 			yyerror("racoon not configured with --enable-hybrid");
 1071: #endif /* ENABLE_HYBRID */
 1072: 		}
 1073: 		EOS
 1074: 	|	CFG_CONF_SOURCE CFG_LDAP
 1075: 		{
 1076: #ifdef ENABLE_HYBRID
 1077: #ifdef HAVE_LIBLDAP
 1078: 			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP;
 1079: #else /* HAVE_LIBLDAP */
 1080: 			yyerror("racoon not configured with --with-libldap");
 1081: #endif /* HAVE_LIBLDAP */
 1082: #else /* ENABLE_HYBRID */
 1083: 			yyerror("racoon not configured with --enable-hybrid");
 1084: #endif /* ENABLE_HYBRID */
 1085: 		}
 1086: 		EOS
 1087: 	|	CFG_MOTD QUOTEDSTRING
 1088: 		{
 1089: #ifdef ENABLE_HYBRID
 1090: 			strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN);
 1091: 			isakmp_cfg_config.motd[MAXPATHLEN] = '\0';
 1092: 			vfree($2);
 1093: #else
 1094: 			yyerror("racoon not configured with --enable-hybrid");
 1095: #endif
 1096: 		}
 1097: 		EOS
 1098: 	;
 1099: 
 1100: addrdnslist
 1101: 	:	addrdns
 1102: 	|	addrdns COMMA addrdnslist
 1103: 	;
 1104: addrdns
 1105: 	:	ADDRSTRING
 1106: 		{
 1107: #ifdef ENABLE_HYBRID
 1108: 			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
 1109: 
 1110: 			if (icc->dns4_index > MAXNS)
 1111: 				yyerror("No more than %d DNS", MAXNS);
 1112: 			if (inet_pton(AF_INET, $1->v,
 1113: 			    &icc->dns4[icc->dns4_index++]) != 1)
 1114: 				yyerror("bad IPv4 DNS address.");
 1115: #else
 1116: 			yyerror("racoon not configured with --enable-hybrid");
 1117: #endif
 1118: 		}
 1119: 	;
 1120: 
 1121: addrwinslist
 1122: 	:	addrwins
 1123: 	|	addrwins COMMA addrwinslist
 1124: 	;
 1125: addrwins
 1126: 	:	ADDRSTRING
 1127: 		{
 1128: #ifdef ENABLE_HYBRID
 1129: 			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
 1130: 
 1131: 			if (icc->nbns4_index > MAXWINS)
 1132: 				yyerror("No more than %d WINS", MAXWINS);
 1133: 			if (inet_pton(AF_INET, $1->v,
 1134: 			    &icc->nbns4[icc->nbns4_index++]) != 1)
 1135: 				yyerror("bad IPv4 WINS address.");
 1136: #else
 1137: 			yyerror("racoon not configured with --enable-hybrid");
 1138: #endif
 1139: 		}
 1140: 	;
 1141: 
 1142: splitnetlist
 1143: 	:	splitnet
 1144: 	|	splitnetlist COMMA splitnet
 1145: 	;
 1146: splitnet
 1147: 	:	ADDRSTRING PREFIX
 1148: 		{
 1149: #ifdef ENABLE_HYBRID
 1150: 			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
 1151: 			struct unity_network network;
 1152: 			memset(&network,0,sizeof(network));
 1153: 
 1154: 			if (inet_pton(AF_INET, $1->v, &network.addr4) != 1)
 1155: 				yyerror("bad IPv4 SPLIT address.");
 1156: 
 1157: 			/* Turn $2 (the prefix) into a subnet mask */
 1158: 			network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0;
 1159: 
 1160: 			/* add the network to our list */ 
 1161: 			if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count))
 1162: 				yyerror("Unable to allocate split network");
 1163: #else
 1164: 			yyerror("racoon not configured with --enable-hybrid");
 1165: #endif
 1166: 		}
 1167: 	;
 1168: 
 1169: authgrouplist
 1170: 	:	authgroup
 1171: 	|	authgroup COMMA authgrouplist
 1172: 	;
 1173: authgroup
 1174: 	:	QUOTEDSTRING
 1175: 		{
 1176: #ifdef ENABLE_HYBRID
 1177: 			char * groupname = NULL;
 1178: 			char ** grouplist = NULL;
 1179: 			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
 1180: 
 1181: 			grouplist = racoon_realloc(icc->grouplist,
 1182: 					sizeof(char**)*(icc->groupcount+1));
 1183: 			if (grouplist == NULL) {
 1184: 				yyerror("unable to allocate auth group list");
 1185: 				return -1;
 1186: 			}
 1187: 
 1188: 			groupname = racoon_malloc($1->l+1);
 1189: 			if (groupname == NULL) {
 1190: 				yyerror("unable to allocate auth group name");
 1191: 				return -1;
 1192: 			}
 1193: 
 1194: 			memcpy(groupname,$1->v,$1->l);
 1195: 			groupname[$1->l]=0;
 1196: 			grouplist[icc->groupcount]=groupname;
 1197: 			icc->grouplist = grouplist;
 1198: 			icc->groupcount++;
 1199: 
 1200: 			vfree($1);
 1201: #else
 1202: 			yyerror("racoon not configured with --enable-hybrid");
 1203: #endif
 1204: 		}
 1205: 	;
 1206: 
 1207: splitdnslist
 1208: 	:	splitdns
 1209: 	|	splitdns COMMA splitdnslist
 1210: 	;
 1211: splitdns
 1212: 	:	QUOTEDSTRING
 1213: 		{
 1214: #ifdef ENABLE_HYBRID
 1215: 			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
 1216: 
 1217: 			if (!icc->splitdns_len)
 1218: 			{
 1219: 				icc->splitdns_list = racoon_malloc($1->l);
 1220: 				if(icc->splitdns_list == NULL) {
 1221: 					yyerror("error allocating splitdns list buffer");
 1222: 					return -1;
 1223: 				}
 1224: 				memcpy(icc->splitdns_list,$1->v,$1->l);
 1225: 				icc->splitdns_len = $1->l;
 1226: 			}
 1227: 			else
 1228: 			{
 1229: 				int len = icc->splitdns_len + $1->l + 1;
 1230: 				icc->splitdns_list = racoon_realloc(icc->splitdns_list,len);
 1231: 				if(icc->splitdns_list == NULL) {
 1232: 					yyerror("error allocating splitdns list buffer");
 1233: 					return -1;
 1234: 				}
 1235: 				icc->splitdns_list[icc->splitdns_len] = ',';
 1236: 				memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l);
 1237: 				icc->splitdns_len = len;
 1238: 			}
 1239: 			vfree($1);
 1240: #else
 1241: 			yyerror("racoon not configured with --enable-hybrid");
 1242: #endif
 1243: 		}
 1244: 	;
 1245: 
 1246: 
 1247: 	/* timer */
 1248: timer_statement
 1249: 	:	RETRY BOC timer_stmts EOC
 1250: 	;
 1251: timer_stmts
 1252: 	:	/* nothing */
 1253: 	|	timer_stmts timer_stmt
 1254: 	;
 1255: timer_stmt
 1256: 	:	RETRY_COUNTER NUMBER
 1257: 		{
 1258: 			lcconf->retry_counter = $2;
 1259: 		}
 1260: 		EOS
 1261: 	|	RETRY_INTERVAL NUMBER unittype_time
 1262: 		{
 1263: 			lcconf->retry_interval = $2 * $3;
 1264: 		}
 1265: 		EOS
 1266: 	|	RETRY_PERSEND NUMBER
 1267: 		{
 1268: 			lcconf->count_persend = $2;
 1269: 		}
 1270: 		EOS
 1271: 	|	RETRY_PHASE1 NUMBER unittype_time
 1272: 		{
 1273: 			lcconf->retry_checkph1 = $2 * $3;
 1274: 		}
 1275: 		EOS
 1276: 	|	RETRY_PHASE2 NUMBER unittype_time
 1277: 		{
 1278: 			lcconf->wait_ph2complete = $2 * $3;
 1279: 		}
 1280: 		EOS
 1281: 	|	NATT_KA NUMBER unittype_time
 1282: 		{
 1283: #ifdef ENABLE_NATT
 1284:         		if (libipsec_opt & LIBIPSEC_OPT_NATT)
 1285: 				lcconf->natt_ka_interval = $2 * $3;
 1286: 			else
 1287:                 		yyerror("libipsec lacks NAT-T support");
 1288: #else
 1289: 			yyerror("NAT-T support not compiled in.");
 1290: #endif
 1291: 		}
 1292: 		EOS
 1293: 	;
 1294: 
 1295: 	/* sainfo */
 1296: sainfo_statement
 1297: 	:	SAINFO
 1298: 		{
 1299: 			cur_sainfo = newsainfo();
 1300: 			if (cur_sainfo == NULL) {
 1301: 				yyerror("failed to allocate sainfo");
 1302: 				return -1;
 1303: 			}
 1304: 		}
 1305: 		sainfo_name sainfo_param BOC sainfo_specs
 1306: 		{
 1307: 			struct sainfo *check;
 1308: 
 1309: 			/* default */
 1310: 			if (cur_sainfo->algs[algclass_ipsec_enc] == 0) {
 1311: 				yyerror("no encryption algorithm at %s",
 1312: 					sainfo2str(cur_sainfo));
 1313: 				return -1;
 1314: 			}
 1315: 			if (cur_sainfo->algs[algclass_ipsec_auth] == 0) {
 1316: 				yyerror("no authentication algorithm at %s",
 1317: 					sainfo2str(cur_sainfo));
 1318: 				return -1;
 1319: 			}
 1320: 			if (cur_sainfo->algs[algclass_ipsec_comp] == 0) {
 1321: 				yyerror("no compression algorithm at %s",
 1322: 					sainfo2str(cur_sainfo));
 1323: 				return -1;
 1324: 			}
 1325: 
 1326: 			/* duplicate check */
 1327: 			check = getsainfo(cur_sainfo->idsrc,
 1328: 					  cur_sainfo->iddst,
 1329: 					  cur_sainfo->id_i,
 1330: 					  NULL,
 1331: 					  cur_sainfo->remoteid);
 1332: 
 1333: 			if (check && ((check->idsrc != SAINFO_ANONYMOUS) &&
 1334: 				      (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) {
 1335: 				yyerror("duplicated sainfo: %s",
 1336: 					sainfo2str(cur_sainfo));
 1337: 				return -1;
 1338: 			}
 1339: 
 1340: 			inssainfo(cur_sainfo);
 1341: 		}
 1342: 		EOC
 1343: 	;
 1344: sainfo_name
 1345: 	:	ANONYMOUS
 1346: 		{
 1347: 			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
 1348: 			cur_sainfo->iddst = SAINFO_ANONYMOUS;
 1349: 		}
 1350: 	|	ANONYMOUS CLIENTADDR
 1351: 		{
 1352: 			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
 1353: 			cur_sainfo->iddst = SAINFO_CLIENTADDR;
 1354: 		}
 1355: 	|	ANONYMOUS sainfo_id
 1356: 		{
 1357: 			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
 1358: 			cur_sainfo->iddst = $2;
 1359: 		}
 1360: 	|	sainfo_id ANONYMOUS
 1361: 		{
 1362: 			cur_sainfo->idsrc = $1;
 1363: 			cur_sainfo->iddst = SAINFO_ANONYMOUS;
 1364: 		}
 1365: 	|	sainfo_id CLIENTADDR
 1366: 		{
 1367: 			cur_sainfo->idsrc = $1;
 1368: 			cur_sainfo->iddst = SAINFO_CLIENTADDR;
 1369: 		}
 1370: 	|	sainfo_id sainfo_id
 1371: 		{
 1372: 			cur_sainfo->idsrc = $1;
 1373: 			cur_sainfo->iddst = $2;
 1374: 		}
 1375: 	;
 1376: sainfo_id
 1377: 	:	IDENTIFIERTYPE ADDRSTRING prefix port ul_proto
 1378: 		{
 1379: 			char portbuf[10];
 1380: 			struct sockaddr *saddr;
 1381: 
 1382: 			if (($5 == IPPROTO_ICMP || $5 == IPPROTO_ICMPV6)
 1383: 			 && ($4 != IPSEC_PORT_ANY || $4 != IPSEC_PORT_ANY)) {
 1384: 				yyerror("port number must be \"any\".");
 1385: 				return -1;
 1386: 			}
 1387: 
 1388: 			snprintf(portbuf, sizeof(portbuf), "%lu", $4);
 1389: 			saddr = str2saddr($2->v, portbuf);
 1390: 			vfree($2);
 1391: 			if (saddr == NULL)
 1392: 				return -1;
 1393: 
 1394: 			switch (saddr->sa_family) {
 1395: 			case AF_INET:
 1396: 				if ($5 == IPPROTO_ICMPV6) {
 1397: 					yyerror("upper layer protocol mismatched.\n");
 1398: 					racoon_free(saddr);
 1399: 					return -1;
 1400: 				}
 1401: 				$$ = ipsecdoi_sockaddr2id(saddr,
 1402: 										  $3 == ~0 ? (sizeof(struct in_addr) << 3): $3,
 1403: 										  $5);
 1404: 				break;
 1405: #ifdef INET6
 1406: 			case AF_INET6:
 1407: 				if ($5 == IPPROTO_ICMP) {
 1408: 					yyerror("upper layer protocol mismatched.\n");
 1409: 					racoon_free(saddr);
 1410: 					return -1;
 1411: 				}
 1412: 				$$ = ipsecdoi_sockaddr2id(saddr, 
 1413: 										  $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3,
 1414: 										  $5);
 1415: 				break;
 1416: #endif
 1417: 			default:
 1418: 				yyerror("invalid family: %d", saddr->sa_family);
 1419: 				$$ = NULL;
 1420: 				break;
 1421: 			}
 1422: 			racoon_free(saddr);
 1423: 			if ($$ == NULL)
 1424: 				return -1;
 1425: 		}
 1426: 	|	IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto
 1427: 		{
 1428: 			char portbuf[10];
 1429: 			struct sockaddr *laddr = NULL, *haddr = NULL;
 1430: 			char *cur = NULL;
 1431: 
 1432: 			if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6)
 1433: 			 && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) {
 1434: 				yyerror("port number must be \"any\".");
 1435: 				return -1;
 1436: 			}
 1437: 
 1438: 			snprintf(portbuf, sizeof(portbuf), "%lu", $5);
 1439: 			
 1440: 			laddr = str2saddr($2->v, portbuf);
 1441: 			if (laddr == NULL) {
 1442: 			    return -1;
 1443: 			}
 1444: 			vfree($2);
 1445: 			haddr = str2saddr($3->v, portbuf);
 1446: 			if (haddr == NULL) {
 1447: 			    racoon_free(laddr);
 1448: 			    return -1;
 1449: 			}
 1450: 			vfree($3);
 1451: 
 1452: 			switch (laddr->sa_family) {
 1453: 			case AF_INET:
 1454: 				if ($6 == IPPROTO_ICMPV6) {
 1455: 				    yyerror("upper layer protocol mismatched.\n");
 1456: 				    if (laddr)
 1457: 					racoon_free(laddr);
 1458: 				    if (haddr)
 1459: 					racoon_free(haddr);
 1460: 				    return -1;
 1461: 				}
 1462:                                 $$ = ipsecdoi_sockrange2id(laddr, haddr, 
 1463: 							   $6);
 1464: 				break;
 1465: #ifdef INET6
 1466: 			case AF_INET6:
 1467: 				if ($6 == IPPROTO_ICMP) {
 1468: 					yyerror("upper layer protocol mismatched.\n");
 1469: 					if (laddr)
 1470: 					    racoon_free(laddr);
 1471: 					if (haddr)
 1472: 					    racoon_free(haddr);
 1473: 					return -1;
 1474: 				}
 1475: 				$$ = ipsecdoi_sockrange2id(laddr, haddr, 
 1476: 							       $6);
 1477: 				break;
 1478: #endif
 1479: 			default:
 1480: 				yyerror("invalid family: %d", laddr->sa_family);
 1481: 				$$ = NULL;
 1482: 				break;
 1483: 			}
 1484: 			if (laddr)
 1485: 			    racoon_free(laddr);
 1486: 			if (haddr)
 1487: 			    racoon_free(haddr);
 1488: 			if ($$ == NULL)
 1489: 				return -1;
 1490: 		}
 1491: 	|	IDENTIFIERTYPE QUOTEDSTRING
 1492: 		{
 1493: 			struct ipsecdoi_id_b *id_b;
 1494: 
 1495: 			if ($1 == IDTYPE_ASN1DN) {
 1496: 				yyerror("id type forbidden: %d", $1);
 1497: 				$$ = NULL;
 1498: 				return -1;
 1499: 			}
 1500: 
 1501: 			$2->l--;
 1502: 
 1503: 			$$ = vmalloc(sizeof(*id_b) + $2->l);
 1504: 			if ($$ == NULL) {
 1505: 				yyerror("failed to allocate identifier");
 1506: 				return -1;
 1507: 			}
 1508: 
 1509: 			id_b = (struct ipsecdoi_id_b *)$$->v;
 1510: 			id_b->type = idtype2doi($1);
 1511: 
 1512: 			id_b->proto_id = 0;
 1513: 			id_b->port = 0;
 1514: 
 1515: 			memcpy($$->v + sizeof(*id_b), $2->v, $2->l);
 1516: 		}
 1517: 	;
 1518: sainfo_param
 1519: 	:	/* nothing */
 1520: 		{
 1521: 			cur_sainfo->id_i = NULL;
 1522: 		}
 1523: 	|	FROM IDENTIFIERTYPE identifierstring
 1524: 		{
 1525: 			struct ipsecdoi_id_b *id_b;
 1526: 			vchar_t *idv;
 1527: 
 1528: 			if (set_identifier(&idv, $2, $3) != 0) {
 1529: 				yyerror("failed to set identifer.\n");
 1530: 				return -1;
 1531: 			}
 1532: 			cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l);
 1533: 			if (cur_sainfo->id_i == NULL) {
 1534: 				yyerror("failed to allocate identifier");
 1535: 				return -1;
 1536: 			}
 1537: 
 1538: 			id_b = (struct ipsecdoi_id_b *)cur_sainfo->id_i->v;
 1539: 			id_b->type = idtype2doi($2);
 1540: 
 1541: 			id_b->proto_id = 0;
 1542: 			id_b->port = 0;
 1543: 
 1544: 			memcpy(cur_sainfo->id_i->v + sizeof(*id_b),
 1545: 			       idv->v, idv->l);
 1546: 			vfree(idv);
 1547: 		}
 1548: 	|	GROUP QUOTEDSTRING
 1549: 		{
 1550: #ifdef ENABLE_HYBRID
 1551: 			if ((cur_sainfo->group = vdup($2)) == NULL) {
 1552: 				yyerror("failed to set sainfo xauth group.\n");
 1553: 				return -1;
 1554: 			}
 1555: #else
 1556: 			yyerror("racoon not configured with --enable-hybrid");
 1557: 			return -1;
 1558: #endif
 1559:  		}
 1560: 	;
 1561: sainfo_specs
 1562: 	:	/* nothing */
 1563: 	|	sainfo_specs sainfo_spec
 1564: 	;
 1565: sainfo_spec
 1566: 	:	PFS_GROUP dh_group_num
 1567: 		{
 1568: 			cur_sainfo->pfs_group = $2;
 1569: 		}
 1570: 		EOS
 1571: 	|	REMOTEID NUMBER
 1572: 		{
 1573: 			cur_sainfo->remoteid = $2;
 1574: 		}
 1575: 		EOS
 1576: 	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
 1577: 		{
 1578: 			cur_sainfo->lifetime = $3 * $4;
 1579: 		}
 1580: 		EOS
 1581: 	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
 1582: 		{
 1583: #if 1
 1584: 			yyerror("byte lifetime support is deprecated");
 1585: 			return -1;
 1586: #else
 1587: 			cur_sainfo->lifebyte = fix_lifebyte($3 * $4);
 1588: 			if (cur_sainfo->lifebyte == 0)
 1589: 				return -1;
 1590: #endif
 1591: 		}
 1592: 		EOS
 1593: 	|	ALGORITHM_CLASS {
 1594: 			cur_algclass = $1;
 1595: 		}
 1596: 		algorithms EOS
 1597: 	;
 1598: 
 1599: algorithms
 1600: 	:	algorithm
 1601: 		{
 1602: 			inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
 1603: 		}
 1604: 	|	algorithm
 1605: 		{
 1606: 			inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
 1607: 		}
 1608: 		COMMA algorithms
 1609: 	;
 1610: algorithm
 1611: 	:	ALGORITHMTYPE keylength
 1612: 		{
 1613: 			int defklen;
 1614: 
 1615: 			$$ = newsainfoalg();
 1616: 			if ($$ == NULL) {
 1617: 				yyerror("failed to get algorithm allocation");
 1618: 				return -1;
 1619: 			}
 1620: 
 1621: 			$$->alg = algtype2doi(cur_algclass, $1);
 1622: 			if ($$->alg == -1) {
 1623: 				yyerror("algorithm mismatched");
 1624: 				racoon_free($$);
 1625: 				$$ = NULL;
 1626: 				return -1;
 1627: 			}
 1628: 
 1629: 			defklen = default_keylen(cur_algclass, $1);
 1630: 			if (defklen == 0) {
 1631: 				if ($2) {
 1632: 					yyerror("keylen not allowed");
 1633: 					racoon_free($$);
 1634: 					$$ = NULL;
 1635: 					return -1;
 1636: 				}
 1637: 			} else {
 1638: 				if ($2 && check_keylen(cur_algclass, $1, $2) < 0) {
 1639: 					yyerror("invalid keylen %d", $2);
 1640: 					racoon_free($$);
 1641: 					$$ = NULL;
 1642: 					return -1;
 1643: 				}
 1644: 			}
 1645: 
 1646: 			if ($2)
 1647: 				$$->encklen = $2;
 1648: 			else
 1649: 				$$->encklen = defklen;
 1650: 
 1651: 			/* check if it's supported algorithm by kernel */
 1652: 			if (!(cur_algclass == algclass_ipsec_auth && $1 == algtype_non_auth)
 1653: 			 && pk_checkalg(cur_algclass, $1, $$->encklen)) {
 1654: 				int a = algclass2doi(cur_algclass);
 1655: 				int b = algtype2doi(cur_algclass, $1);
 1656: 				if (a == IPSECDOI_ATTR_AUTH)
 1657: 					a = IPSECDOI_PROTO_IPSEC_AH;
 1658: 				yyerror("algorithm %s not supported by the kernel (missing module?)",
 1659: 					s_ipsecdoi_trns(a, b));
 1660: 				racoon_free($$);
 1661: 				$$ = NULL;
 1662: 				return -1;
 1663: 			}
 1664: 		}
 1665: 	;
 1666: prefix
 1667: 	:	/* nothing */ { $$ = ~0; }
 1668: 	|	PREFIX { $$ = $1; }
 1669: 	;
 1670: port
 1671: 	:	/* nothing */ { $$ = IPSEC_PORT_ANY; }
 1672: 	|	PORT { $$ = $1; }
 1673: 	|	PORTANY { $$ = IPSEC_PORT_ANY; }
 1674: 	;
 1675: ul_proto
 1676: 	:	NUMBER { $$ = $1; }
 1677: 	|	UL_PROTO { $$ = $1; }
 1678: 	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
 1679: 	;
 1680: keylength
 1681: 	:	/* nothing */ { $$ = 0; }
 1682: 	|	NUMBER { $$ = $1; }
 1683: 	;
 1684: 
 1685: 	/* remote */
 1686: remote_statement
 1687: 	: REMOTE QUOTEDSTRING INHERIT QUOTEDSTRING
 1688: 		{
 1689: 			struct remoteconf *from, *new;
 1690: 
 1691: 			if (getrmconf_by_name($2->v) != NULL) {
 1692: 				yyerror("named remoteconf \"%s\" already exists.");
 1693: 				return -1;
 1694: 			}
 1695: 
 1696: 			from = getrmconf_by_name($4->v);
 1697: 			if (from == NULL) {
 1698: 				yyerror("named parent remoteconf \"%s\" does not exist.",
 1699: 					$4->v);
 1700: 				return -1;
 1701: 			}
 1702: 
 1703: 			new = duprmconf_shallow(from);
 1704: 			if (new == NULL) {
 1705: 				yyerror("failed to duplicate remoteconf from \"%s\".",
 1706: 					$4->v);
 1707: 				return -1;
 1708: 			}
 1709: 
 1710: 			new->name = racoon_strdup($2->v);
 1711: 			cur_rmconf = new;
 1712: 
 1713: 			vfree($2);
 1714: 			vfree($4);
 1715: 		}
 1716: 		remote_specs_inherit_block
 1717: 	| REMOTE QUOTEDSTRING
 1718: 		{
 1719: 			struct remoteconf *new;
 1720: 
 1721: 			if (getrmconf_by_name($2->v) != NULL) {
 1722: 				yyerror("Named remoteconf \"%s\" already exists.");
 1723: 				return -1;
 1724: 			}
 1725: 
 1726: 			new = newrmconf();
 1727: 			if (new == NULL) {
 1728: 				yyerror("failed to get new remoteconf.");
 1729: 				return -1;
 1730: 			}
 1731: 			new->name = racoon_strdup($2->v);
 1732: 			cur_rmconf = new;
 1733: 
 1734: 			vfree($2);
 1735: 		}
 1736: 		remote_specs_block
 1737: 	| REMOTE remote_index INHERIT remote_index
 1738: 		{
 1739: 			struct remoteconf *from, *new;
 1740: 
 1741: 			from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS);
 1742: 			if (from == NULL) {
 1743: 				yyerror("failed to get remoteconf for %s.",
 1744: 					saddr2str($4));
 1745: 				return -1;
 1746: 			}
 1747: 
 1748: 			new = duprmconf_shallow(from);
 1749: 			if (new == NULL) {
 1750: 				yyerror("failed to duplicate remoteconf from %s.",
 1751: 					saddr2str($4));
 1752: 				return -1;
 1753: 			}
 1754: 
 1755: 			racoon_free($4);
 1756: 			new->remote = $2;
 1757: 			cur_rmconf = new;
 1758: 		}
 1759: 		remote_specs_inherit_block
 1760: 	|	REMOTE remote_index
 1761: 		{
 1762: 			struct remoteconf *new;
 1763: 
 1764: 			new = newrmconf();
 1765: 			if (new == NULL) {
 1766: 				yyerror("failed to get new remoteconf.");
 1767: 				return -1;
 1768: 			}
 1769: 
 1770: 			new->remote = $2;
 1771: 			cur_rmconf = new;
 1772: 		}
 1773: 		remote_specs_block
 1774: 	;
 1775: 
 1776: remote_specs_inherit_block
 1777: 	:	remote_specs_block
 1778: 	|	EOS /* inheritance without overriding any settings */
 1779: 		{
 1780: 			if (process_rmconf() != 0)
 1781: 				return -1;
 1782: 		}
 1783: 	;
 1784: 
 1785: remote_specs_block
 1786: 	:	BOC remote_specs EOC
 1787: 		{
 1788: 			if (process_rmconf() != 0)
 1789: 				return -1;
 1790: 		}
 1791: 	;
 1792: remote_index
 1793: 	:	ANONYMOUS ike_port
 1794: 		{
 1795: 			$$ = newsaddr(sizeof(struct sockaddr));
 1796: 			$$->sa_family = AF_UNSPEC;
 1797: 			((struct sockaddr_in *)$$)->sin_port = htons($2);
 1798: 		}
 1799: 	|	ike_addrinfo_port
 1800: 		{
 1801: 			$$ = $1;
 1802: 			if ($$ == NULL) {
 1803: 				yyerror("failed to allocate sockaddr");
 1804: 				return -1;
 1805: 			}
 1806: 		}
 1807: 	;
 1808: remote_specs
 1809: 	:	/* nothing */
 1810: 	|	remote_specs remote_spec
 1811: 	;
 1812: remote_spec
 1813: 	:	REMOTE_ADDRESS ike_addrinfo_port
 1814: 		{
 1815: 			if (cur_rmconf->remote != NULL) {
 1816: 				yyerror("remote_address already specified");
 1817: 				return -1;
 1818: 			}
 1819: 			cur_rmconf->remote = $2;
 1820: 		}
 1821: 		EOS
 1822: 	|	EXCHANGE_MODE
 1823: 		{
 1824: 			cur_rmconf->etypes = NULL;
 1825: 		}
 1826: 		exchange_types EOS
 1827: 	|	DOI DOITYPE { cur_rmconf->doitype = $2; } EOS
 1828: 	|	SITUATION SITUATIONTYPE { cur_rmconf->sittype = $2; } EOS
 1829: 	|	CERTIFICATE_TYPE cert_spec
 1830: 	|	PEERS_CERTFILE QUOTEDSTRING
 1831: 		{
 1832: 			yywarn("This directive without certtype will be removed!\n");
 1833: 			yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v);
 1834: 
 1835: 			if (cur_rmconf->peerscert != NULL) {
 1836: 				yyerror("peers_certfile already defined\n");
 1837: 				return -1;
 1838: 			}
 1839: 
 1840: 			if (load_x509($2->v, &cur_rmconf->peerscertfile,
 1841: 				      &cur_rmconf->peerscert)) {
 1842: 				yyerror("failed to load certificate \"%s\"\n",
 1843: 					$2->v);
 1844: 				return -1;
 1845: 			}
 1846: 
 1847: 			vfree($2);
 1848: 		}
 1849: 		EOS
 1850: 	|	PEERS_CERTFILE CERT_X509 QUOTEDSTRING
 1851: 		{
 1852: 			if (cur_rmconf->peerscert != NULL) {
 1853: 				yyerror("peers_certfile already defined\n");
 1854: 				return -1;
 1855: 			}
 1856: 
 1857: 			if (load_x509($3->v, &cur_rmconf->peerscertfile,
 1858: 				      &cur_rmconf->peerscert)) {
 1859: 				yyerror("failed to load certificate \"%s\"\n",
 1860: 					$3->v);
 1861: 				return -1;
 1862: 			}
 1863: 
 1864: 			vfree($3);
 1865: 		}
 1866: 		EOS
 1867: 	|	PEERS_CERTFILE CERT_PLAINRSA QUOTEDSTRING
 1868: 		{
 1869: 			char path[MAXPATHLEN];
 1870: 			int ret = 0;
 1871: 
 1872: 			if (cur_rmconf->peerscert != NULL) {
 1873: 				yyerror("peers_certfile already defined\n");
 1874: 				return -1;
 1875: 			}
 1876: 
 1877: 			cur_rmconf->peerscert = vmalloc(1);
 1878: 			if (cur_rmconf->peerscert == NULL) {
 1879: 				yyerror("failed to allocate peerscert");
 1880: 				return -1;
 1881: 			}
 1882: 			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA;
 1883: 
 1884: 			getpathname(path, sizeof(path),
 1885: 				    LC_PATHTYPE_CERT, $3->v);
 1886: 			if (rsa_parse_file(cur_rmconf->rsa_public, path,
 1887: 					   RSA_TYPE_PUBLIC)) {
 1888: 				yyerror("Couldn't parse keyfile.\n", path);
 1889: 				return -1;
 1890: 			}
 1891: 			plog(LLV_DEBUG, LOCATION, NULL,
 1892: 			     "Public PlainRSA keyfile parsed: %s\n", path);
 1893: 
 1894: 			vfree($3);
 1895: 		}
 1896: 		EOS
 1897: 	|	PEERS_CERTFILE DNSSEC
 1898: 		{
 1899: 			if (cur_rmconf->peerscert != NULL) {
 1900: 				yyerror("peers_certfile already defined\n");
 1901: 				return -1;
 1902: 			}
 1903: 			cur_rmconf->peerscert = vmalloc(1);
 1904: 			if (cur_rmconf->peerscert == NULL) {
 1905: 				yyerror("failed to allocate peerscert");
 1906: 				return -1;
 1907: 			}
 1908: 			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS;
 1909: 		}
 1910: 		EOS
 1911: 	|	CA_TYPE CERT_X509 QUOTEDSTRING
 1912: 		{
 1913: 			if (cur_rmconf->cacert != NULL) {
 1914: 				yyerror("ca_type already defined\n");
 1915: 				return -1;
 1916: 			}
 1917: 
 1918: 			if (load_x509($3->v, &cur_rmconf->cacertfile,
 1919: 				      &cur_rmconf->cacert)) {
 1920: 				yyerror("failed to load certificate \"%s\"\n",
 1921: 					$3->v);
 1922: 				return -1;
 1923: 			}
 1924: 
 1925: 			vfree($3);
 1926: 		}
 1927: 		EOS
 1928: 	|	VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS
 1929: 	|	SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS
 1930: 	|	SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS
 1931: 	|	MATCH_EMPTY_CR SWITCH { cur_rmconf->match_empty_cr = $2; } EOS
 1932: 	|	MY_IDENTIFIER IDENTIFIERTYPE identifierstring
 1933: 		{
 1934: 			if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) {
 1935: 				yyerror("failed to set identifer.\n");
 1936: 				return -1;
 1937: 			}
 1938: 			cur_rmconf->idvtype = $2;
 1939: 		}
 1940: 		EOS
 1941: 	|	MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
 1942: 		{
 1943: 			if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) {
 1944: 				yyerror("failed to set identifer.\n");
 1945: 				return -1;
 1946: 			}
 1947: 			cur_rmconf->idvtype = $2;
 1948: 		}
 1949: 		EOS
 1950: 	|	XAUTH_LOGIN identifierstring
 1951: 		{
 1952: #ifdef ENABLE_HYBRID
 1953: 			/* formerly identifier type login */
 1954: 			if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) {
 1955: 				yyerror("failed to allocate xauth state\n");
 1956: 				return -1;
 1957: 			}
 1958: 			if ((cur_rmconf->xauth->login = vdup($2)) == NULL) {
 1959: 				yyerror("failed to set identifer.\n");
 1960: 				return -1;
 1961: 			}
 1962: #else
 1963: 			yyerror("racoon not configured with --enable-hybrid");
 1964: #endif
 1965: 		}
 1966: 		EOS
 1967: 	|	PEERS_IDENTIFIER IDENTIFIERTYPE identifierstring
 1968: 		{
 1969: 			struct idspec  *id;
 1970: 			id = newidspec();
 1971: 			if (id == NULL) {
 1972: 				yyerror("failed to allocate idspec");
 1973: 				return -1;
 1974: 			}
 1975: 			if (set_identifier(&id->id, $2, $3) != 0) {
 1976: 				yyerror("failed to set identifer.\n");
 1977: 				racoon_free(id);
 1978: 				return -1;
 1979: 			}
 1980: 			id->idtype = $2;
 1981: 			genlist_append (cur_rmconf->idvl_p, id);
 1982: 		}
 1983: 		EOS
 1984: 	|	PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
 1985: 		{
 1986: 			struct idspec  *id;
 1987: 			id = newidspec();
 1988: 			if (id == NULL) {
 1989: 				yyerror("failed to allocate idspec");
 1990: 				return -1;
 1991: 			}
 1992: 			if (set_identifier_qual(&id->id, $2, $4, $3) != 0) {
 1993: 				yyerror("failed to set identifer.\n");
 1994: 				racoon_free(id);
 1995: 				return -1;
 1996: 			}
 1997: 			id->idtype = $2;
 1998: 			genlist_append (cur_rmconf->idvl_p, id);
 1999: 		}
 2000: 		EOS
 2001: 	|	VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS
 2002: 	|	NONCE_SIZE NUMBER { cur_rmconf->nonce_size = $2; } EOS
 2003: 	|	DH_GROUP
 2004: 		{
 2005: 			yyerror("dh_group cannot be defined here.");
 2006: 			return -1;
 2007: 		}
 2008: 		dh_group_num EOS
 2009: 	|	PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS
 2010: 	|	IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS
 2011: 	|	IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS
 2012: 	|	ESP_FRAG NUMBER { 
 2013: #ifdef SADB_X_EXT_NAT_T_FRAG
 2014:         		if (libipsec_opt & LIBIPSEC_OPT_FRAG)
 2015: 				cur_rmconf->esp_frag = $2; 
 2016: 			else
 2017:                 		yywarn("libipsec lacks IKE frag support");
 2018: #else
 2019: 			yywarn("Your kernel does not support esp_frag");
 2020: #endif
 2021: 		} EOS
 2022: 	|	SCRIPT QUOTEDSTRING PHASE1_UP { 
 2023: 			if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL)
 2024: 				vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]);
 2025: 
 2026: 			cur_rmconf->script[SCRIPT_PHASE1_UP] = 
 2027: 			    script_path_add(vdup($2));
 2028: 		} EOS
 2029: 	|	SCRIPT QUOTEDSTRING PHASE1_DOWN { 
 2030: 			if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL)
 2031: 				vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]);
 2032: 
 2033: 			cur_rmconf->script[SCRIPT_PHASE1_DOWN] = 
 2034: 			    script_path_add(vdup($2));
 2035: 		} EOS
 2036: 	|	SCRIPT QUOTEDSTRING PHASE1_DEAD { 
 2037: 			if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL)
 2038: 				vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]);
 2039: 
 2040: 			cur_rmconf->script[SCRIPT_PHASE1_DEAD] = 
 2041: 			    script_path_add(vdup($2));
 2042: 		} EOS
 2043: 	|	MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS
 2044: 	|	WEAK_PHASE1_CHECK SWITCH {
 2045: 			cur_rmconf->weak_phase1_check = $2;
 2046: 		} EOS
 2047: 	|	GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS
 2048: 	|	GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS
 2049: 	|	SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS
 2050: 	|	INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS
 2051: 	|	NAT_TRAVERSAL SWITCH
 2052: 		{
 2053: #ifdef ENABLE_NATT
 2054:         		if (libipsec_opt & LIBIPSEC_OPT_NATT)
 2055: 				cur_rmconf->nat_traversal = $2;
 2056: 			else
 2057:                 		yyerror("libipsec lacks NAT-T support");
 2058: #else
 2059: 			yyerror("NAT-T support not compiled in.");
 2060: #endif
 2061: 		} EOS
 2062: 	|	NAT_TRAVERSAL REMOTE_FORCE_LEVEL
 2063: 		{
 2064: #ifdef ENABLE_NATT
 2065: 			if (libipsec_opt & LIBIPSEC_OPT_NATT)
 2066: 				cur_rmconf->nat_traversal = NATT_FORCE;
 2067: 			else
 2068:                 		yyerror("libipsec lacks NAT-T support");
 2069: #else
 2070: 			yyerror("NAT-T support not compiled in.");
 2071: #endif
 2072: 		} EOS
 2073: 	|	DPD SWITCH
 2074: 		{
 2075: #ifdef ENABLE_DPD
 2076: 			cur_rmconf->dpd = $2;
 2077: #else
 2078: 			yyerror("DPD support not compiled in.");
 2079: #endif
 2080: 		} EOS
 2081: 	|	DPD_DELAY NUMBER
 2082: 		{
 2083: #ifdef ENABLE_DPD
 2084: 			cur_rmconf->dpd_interval = $2;
 2085: #else
 2086: 			yyerror("DPD support not compiled in.");
 2087: #endif
 2088: 		}
 2089: 		EOS
 2090: 	|	DPD_RETRY NUMBER
 2091: 		{
 2092: #ifdef ENABLE_DPD
 2093: 			cur_rmconf->dpd_retry = $2;
 2094: #else
 2095: 			yyerror("DPD support not compiled in.");
 2096: #endif
 2097: 		}
 2098: 		EOS
 2099: 	|	DPD_MAXFAIL NUMBER
 2100: 		{
 2101: #ifdef ENABLE_DPD
 2102: 			cur_rmconf->dpd_maxfails = $2;
 2103: #else
 2104: 			yyerror("DPD support not compiled in.");
 2105: #endif
 2106: 		}
 2107: 		EOS
 2108: 	|	REKEY SWITCH { cur_rmconf->rekey = $2; } EOS
 2109: 	|	REKEY REMOTE_FORCE_LEVEL { cur_rmconf->rekey = REKEY_FORCE; } EOS
 2110: 	|	PH1ID NUMBER
 2111: 		{
 2112: 			cur_rmconf->ph1id = $2;
 2113: 		}
 2114: 		EOS
 2115: 	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
 2116: 		{
 2117: 			cur_rmconf->lifetime = $3 * $4;
 2118: 		}
 2119: 		EOS
 2120: 	|	PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS
 2121: 	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
 2122: 		{
 2123: #if 1
 2124: 			yyerror("byte lifetime support is deprecated in Phase1");
 2125: 			return -1;
 2126: #else
 2127: 			yywarn("the lifetime of bytes in phase 1 "
 2128: 				"will be ignored at the moment.");
 2129: 			cur_rmconf->lifebyte = fix_lifebyte($3 * $4);
 2130: 			if (cur_rmconf->lifebyte == 0)
 2131: 				return -1;
 2132: #endif
 2133: 		}
 2134: 		EOS
 2135: 	|	PROPOSAL
 2136: 		{
 2137: 			struct secprotospec *spspec;
 2138: 
 2139: 			spspec = newspspec();
 2140: 			if (spspec == NULL)
 2141: 				return -1;
 2142: 			insspspec(cur_rmconf, spspec);
 2143: 		}
 2144: 		BOC isakmpproposal_specs EOC
 2145: 	;
 2146: exchange_types
 2147: 	:	/* nothing */
 2148: 	|	exchange_types EXCHANGETYPE
 2149: 		{
 2150: 			struct etypes *new;
 2151: 			new = racoon_malloc(sizeof(struct etypes));
 2152: 			if (new == NULL) {
 2153: 				yyerror("failed to allocate etypes");
 2154: 				return -1;
 2155: 			}
 2156: 			new->type = $2;
 2157: 			new->next = NULL;
 2158: 			if (cur_rmconf->etypes == NULL)
 2159: 				cur_rmconf->etypes = new;
 2160: 			else {
 2161: 				struct etypes *p;
 2162: 				for (p = cur_rmconf->etypes;
 2163: 				     p->next != NULL;
 2164: 				     p = p->next)
 2165: 					;
 2166: 				p->next = new;
 2167: 			}
 2168: 		}
 2169: 	;
 2170: cert_spec
 2171: 	:	CERT_X509 QUOTEDSTRING QUOTEDSTRING
 2172: 		{
 2173: 			if (cur_rmconf->mycert != NULL) {
 2174: 				yyerror("certificate_type already defined\n");
 2175: 				return -1;
 2176: 			}
 2177: 
 2178: 			if (load_x509($2->v, &cur_rmconf->mycertfile,
 2179: 				      &cur_rmconf->mycert)) {
 2180: 				yyerror("failed to load certificate \"%s\"\n",
 2181: 					$2->v);
 2182: 				return -1;
 2183: 			}
 2184: 
 2185: 			cur_rmconf->myprivfile = racoon_strdup($3->v);
 2186: 			STRDUP_FATAL(cur_rmconf->myprivfile);
 2187: 
 2188: 			vfree($2);
 2189: 			vfree($3);
 2190: 		}
 2191: 		EOS
 2192: 	|	CERT_PLAINRSA QUOTEDSTRING
 2193: 		{
 2194: 			char path[MAXPATHLEN];
 2195: 			int ret = 0;
 2196: 
 2197: 			if (cur_rmconf->mycert != NULL) {
 2198: 				yyerror("certificate_type already defined\n");
 2199: 				return -1;
 2200: 			}
 2201: 
 2202: 			cur_rmconf->mycert = vmalloc(1);
 2203: 			if (cur_rmconf->mycert == NULL) {
 2204: 				yyerror("failed to allocate mycert");
 2205: 				return -1;
 2206: 			}
 2207: 			cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA;
 2208: 
 2209: 			getpathname(path, sizeof(path),
 2210: 				    LC_PATHTYPE_CERT, $2->v);
 2211: 			cur_rmconf->send_cr = FALSE;
 2212: 			cur_rmconf->send_cert = FALSE;
 2213: 			cur_rmconf->verify_cert = FALSE;
 2214: 			if (rsa_parse_file(cur_rmconf->rsa_private, path,
 2215: 					   RSA_TYPE_PRIVATE)) {
 2216: 				yyerror("Couldn't parse keyfile.\n", path);
 2217: 				return -1;
 2218: 			}
 2219: 			plog(LLV_DEBUG, LOCATION, NULL,
 2220: 			     "Private PlainRSA keyfile parsed: %s\n", path);
 2221: 			vfree($2);
 2222: 		}
 2223: 		EOS
 2224: 	;
 2225: dh_group_num
 2226: 	:	ALGORITHMTYPE
 2227: 		{
 2228: 			$$ = algtype2doi(algclass_isakmp_dh, $1);
 2229: 			if ($$ == -1) {
 2230: 				yyerror("must be DH group");
 2231: 				return -1;
 2232: 			}
 2233: 		}
 2234: 	|	NUMBER
 2235: 		{
 2236: 			if (ARRAYLEN(num2dhgroup) > $1 && num2dhgroup[$1] != 0) {
 2237: 				$$ = num2dhgroup[$1];
 2238: 			} else {
 2239: 				yyerror("must be DH group");
 2240: 				$$ = 0;
 2241: 				return -1;
 2242: 			}
 2243: 		}
 2244: 	;
 2245: identifierstring
 2246: 	:	/* nothing */ { $$ = NULL; }
 2247: 	|	ADDRSTRING { $$ = $1; }
 2248: 	|	QUOTEDSTRING { $$ = $1; }
 2249: 	;
 2250: isakmpproposal_specs
 2251: 	:	/* nothing */
 2252: 	|	isakmpproposal_specs isakmpproposal_spec
 2253: 	;
 2254: isakmpproposal_spec
 2255: 	:	LIFETIME LIFETYPE_TIME NUMBER unittype_time
 2256: 		{
 2257: 			cur_rmconf->spspec->lifetime = $3 * $4;
 2258: 		}
 2259: 		EOS
 2260: 	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
 2261: 		{
 2262: #if 1
 2263: 			yyerror("byte lifetime support is deprecated");
 2264: 			return -1;
 2265: #else
 2266: 			cur_rmconf->spspec->lifebyte = fix_lifebyte($3 * $4);
 2267: 			if (cur_rmconf->spspec->lifebyte == 0)
 2268: 				return -1;
 2269: #endif
 2270: 		}
 2271: 		EOS
 2272: 	|	DH_GROUP dh_group_num
 2273: 		{
 2274: 			cur_rmconf->spspec->algclass[algclass_isakmp_dh] = $2;
 2275: 		}
 2276: 		EOS
 2277: 	|	GSS_ID QUOTEDSTRING
 2278: 		{
 2279: 			if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) {
 2280: 				yyerror("wrong Vendor ID for gssapi_id");
 2281: 				return -1;
 2282: 			}
 2283: 			if (cur_rmconf->spspec->gssid != NULL)
 2284: 				racoon_free(cur_rmconf->spspec->gssid);
 2285: 			cur_rmconf->spspec->gssid =
 2286: 			    racoon_strdup($2->v);
 2287: 			STRDUP_FATAL(cur_rmconf->spspec->gssid);
 2288: 		}
 2289: 		EOS
 2290: 	|	ALGORITHM_CLASS ALGORITHMTYPE keylength
 2291: 		{
 2292: 			int doi;
 2293: 			int defklen;
 2294: 
 2295: 			doi = algtype2doi($1, $2);
 2296: 			if (doi == -1) {
 2297: 				yyerror("algorithm mismatched 1");
 2298: 				return -1;
 2299: 			}
 2300: 
 2301: 			switch ($1) {
 2302: 			case algclass_isakmp_enc:
 2303: 			/* reject suppressed algorithms */
 2304: #ifndef HAVE_OPENSSL_RC5_H
 2305: 				if ($2 == algtype_rc5) {
 2306: 					yyerror("algorithm %s not supported",
 2307: 					    s_attr_isakmp_enc(doi));
 2308: 					return -1;
 2309: 				}
 2310: #endif
 2311: #ifndef HAVE_OPENSSL_IDEA_H
 2312: 				if ($2 == algtype_idea) {
 2313: 					yyerror("algorithm %s not supported",
 2314: 					    s_attr_isakmp_enc(doi));
 2315: 					return -1;
 2316: 				}
 2317: #endif
 2318: 
 2319: 				cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi;
 2320: 				defklen = default_keylen($1, $2);
 2321: 				if (defklen == 0) {
 2322: 					if ($3) {
 2323: 						yyerror("keylen not allowed");
 2324: 						return -1;
 2325: 					}
 2326: 				} else {
 2327: 					if ($3 && check_keylen($1, $2, $3) < 0) {
 2328: 						yyerror("invalid keylen %d", $3);
 2329: 						return -1;
 2330: 					}
 2331: 				}
 2332: 				if ($3)
 2333: 					cur_rmconf->spspec->encklen = $3;
 2334: 				else
 2335: 					cur_rmconf->spspec->encklen = defklen;
 2336: 				break;
 2337: 			case algclass_isakmp_hash:
 2338: 				cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi;
 2339: 				break;
 2340: 			case algclass_isakmp_ameth:
 2341: 				cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi;
 2342: 				/*
 2343: 				 * We may have to set the Vendor ID for the
 2344: 				 * authentication method we're using.
 2345: 				 */
 2346: 				switch ($2) {
 2347: 				case algtype_gssapikrb:
 2348: 					if (cur_rmconf->spspec->vendorid !=
 2349: 					    VENDORID_UNKNOWN) {
 2350: 						yyerror("Vendor ID mismatch "
 2351: 						    "for auth method");
 2352: 						return -1;
 2353: 					}
 2354: 					/*
 2355: 					 * For interoperability with Win2k,
 2356: 					 * we set the Vendor ID to "GSSAPI".
 2357: 					 */
 2358: 					cur_rmconf->spspec->vendorid =
 2359: 					    VENDORID_GSSAPI;
 2360: 					break;
 2361: 				case algtype_rsasig:
 2362: 					if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) {
 2363: 						if (rsa_list_count(cur_rmconf->rsa_private) == 0) {
 2364: 							yyerror ("Private PlainRSA key not set. "
 2365: 								 "Use directive 'certificate_type plainrsa ...'\n");
 2366: 							return -1;
 2367: 						}
 2368: 						if (rsa_list_count(cur_rmconf->rsa_public) == 0) {
 2369: 							yyerror ("Public PlainRSA keys not set. "
 2370: 								 "Use directive 'peers_certfile plainrsa ...'\n");
 2371: 							return -1;
 2372: 						}
 2373: 					}
 2374: 					break;
 2375: 				default:
 2376: 					break;
 2377: 				}
 2378: 				break;
 2379: 			default:
 2380: 				yyerror("algorithm mismatched 2");
 2381: 				return -1;
 2382: 			}
 2383: 		}
 2384: 		EOS
 2385: 	;
 2386: 
 2387: unittype_time
 2388: 	:	UNITTYPE_SEC	{ $$ = 1; }
 2389: 	|	UNITTYPE_MIN	{ $$ = 60; }
 2390: 	|	UNITTYPE_HOUR	{ $$ = (60 * 60); }
 2391: 	;
 2392: unittype_byte
 2393: 	:	UNITTYPE_BYTE	{ $$ = 1; }
 2394: 	|	UNITTYPE_KBYTES	{ $$ = 1024; }
 2395: 	|	UNITTYPE_MBYTES	{ $$ = (1024 * 1024); }
 2396: 	|	UNITTYPE_TBYTES	{ $$ = (1024 * 1024 * 1024); }
 2397: 	;
 2398: %%
 2399: 
 2400: static struct secprotospec *
 2401: newspspec()
 2402: {
 2403: 	struct secprotospec *new;
 2404: 
 2405: 	new = racoon_calloc(1, sizeof(*new));
 2406: 	if (new == NULL) {
 2407: 		yyerror("failed to allocate spproto");
 2408: 		return NULL;
 2409: 	}
 2410: 
 2411: 	new->encklen = 0;	/*XXX*/
 2412: 
 2413: 	/*
 2414: 	 * Default to "uknown" vendor -- we will override this
 2415: 	 * as necessary.  When we send a Vendor ID payload, an
 2416: 	 * "unknown" will be translated to a KAME/racoon ID.
 2417: 	 */
 2418: 	new->vendorid = VENDORID_UNKNOWN;
 2419: 
 2420: 	return new;
 2421: }
 2422: 
 2423: /*
 2424:  * insert into head of list.
 2425:  */
 2426: static void
 2427: insspspec(rmconf, spspec)
 2428: 	struct remoteconf *rmconf;
 2429: 	struct secprotospec *spspec;
 2430: {
 2431: 	if (rmconf->spspec != NULL)
 2432: 		rmconf->spspec->prev = spspec;
 2433: 	spspec->next = rmconf->spspec;
 2434: 	rmconf->spspec = spspec;
 2435: }
 2436: 
 2437: static struct secprotospec *
 2438: dupspspec(spspec)
 2439: 	struct secprotospec *spspec;
 2440: {
 2441: 	struct secprotospec *new;
 2442: 
 2443: 	new = newspspec();
 2444: 	if (new == NULL) {
 2445: 		plog(LLV_ERROR, LOCATION, NULL, 
 2446: 		    "dupspspec: malloc failed\n");
 2447: 		return NULL;
 2448: 	}
 2449: 	memcpy(new, spspec, sizeof(*new));
 2450: 
 2451: 	if (spspec->gssid) {
 2452: 		new->gssid = racoon_strdup(spspec->gssid);
 2453: 		STRDUP_FATAL(new->gssid);
 2454: 	}
 2455: 	if (spspec->remote) {
 2456: 		new->remote = racoon_malloc(sizeof(*new->remote));
 2457: 		if (new->remote == NULL) {
 2458: 			plog(LLV_ERROR, LOCATION, NULL, 
 2459: 			    "dupspspec: malloc failed (remote)\n");
 2460: 			return NULL;
 2461: 		}
 2462: 		memcpy(new->remote, spspec->remote, sizeof(*new->remote));
 2463: 	}
 2464: 
 2465: 	return new;
 2466: }
 2467: 
 2468: /*
 2469:  * copy the whole list
 2470:  */
 2471: void
 2472: dupspspec_list(dst, src)
 2473: 	struct remoteconf *dst, *src;
 2474: {
 2475: 	struct secprotospec *p, *new, *last;
 2476: 
 2477: 	for(p = src->spspec, last = NULL; p; p = p->next, last = new) {
 2478: 		new = dupspspec(p);
 2479: 		if (new == NULL)
 2480: 			exit(1);
 2481: 
 2482: 		new->prev = last;
 2483: 		new->next = NULL; /* not necessary but clean */
 2484: 
 2485: 		if (last)
 2486: 			last->next = new;
 2487: 		else /* first element */
 2488: 			dst->spspec = new;
 2489: 
 2490: 	}
 2491: }
 2492: 
 2493: /*
 2494:  * delete the whole list
 2495:  */
 2496: void
 2497: flushspspec(rmconf)
 2498: 	struct remoteconf *rmconf;
 2499: {
 2500: 	struct secprotospec *p;
 2501: 
 2502: 	while(rmconf->spspec != NULL) {
 2503: 		p = rmconf->spspec;
 2504: 		rmconf->spspec = p->next;
 2505: 		if (p->next != NULL)
 2506: 			p->next->prev = NULL; /* not necessary but clean */
 2507: 
 2508: 		if (p->gssid)
 2509: 			racoon_free(p->gssid);
 2510: 		if (p->remote)
 2511: 			racoon_free(p->remote);
 2512: 		racoon_free(p);
 2513: 	}
 2514: 	rmconf->spspec = NULL;
 2515: }
 2516: 
 2517: /* set final acceptable proposal */
 2518: static int
 2519: set_isakmp_proposal(rmconf)
 2520: 	struct remoteconf *rmconf;
 2521: {
 2522: 	struct secprotospec *s;
 2523: 	int prop_no = 1; 
 2524: 	int trns_no = 1;
 2525: 	int32_t types[MAXALGCLASS];
 2526: 
 2527: 	/* mandatory check */
 2528: 	if (rmconf->spspec == NULL) {
 2529: 		yyerror("no remote specification found: %s.\n",
 2530: 			saddr2str(rmconf->remote));
 2531: 		return -1;
 2532: 	}
 2533: 	for (s = rmconf->spspec; s != NULL; s = s->next) {
 2534: 		/* XXX need more to check */
 2535: 		if (s->algclass[algclass_isakmp_enc] == 0) {
 2536: 			yyerror("encryption algorithm required.");
 2537: 			return -1;
 2538: 		}
 2539: 		if (s->algclass[algclass_isakmp_hash] == 0) {
 2540: 			yyerror("hash algorithm required.");
 2541: 			return -1;
 2542: 		}
 2543: 		if (s->algclass[algclass_isakmp_dh] == 0) {
 2544: 			yyerror("DH group required.");
 2545: 			return -1;
 2546: 		}
 2547: 		if (s->algclass[algclass_isakmp_ameth] == 0) {
 2548: 			yyerror("authentication method required.");
 2549: 			return -1;
 2550: 		}
 2551: 	}
 2552: 
 2553: 	/* skip to last part */
 2554: 	for (s = rmconf->spspec; s->next != NULL; s = s->next)
 2555: 		;
 2556: 
 2557: 	while (s != NULL) {
 2558: 		plog(LLV_DEBUG2, LOCATION, NULL,
 2559: 			"lifetime = %ld\n", (long)
 2560: 			(s->lifetime ? s->lifetime : rmconf->lifetime));
 2561: 		plog(LLV_DEBUG2, LOCATION, NULL,
 2562: 			"lifebyte = %d\n",
 2563: 			s->lifebyte ? s->lifebyte : rmconf->lifebyte);
 2564: 		plog(LLV_DEBUG2, LOCATION, NULL,
 2565: 			"encklen=%d\n", s->encklen);
 2566: 
 2567: 		memset(types, 0, ARRAYLEN(types));
 2568: 		types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc];
 2569: 		types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash];
 2570: 		types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh];
 2571: 		types[algclass_isakmp_ameth] =
 2572: 		    s->algclass[algclass_isakmp_ameth];
 2573: 
 2574: 		/* expanding spspec */
 2575: 		clean_tmpalgtype();
 2576: 		trns_no = expand_isakmpspec(prop_no, trns_no, types,
 2577: 				algclass_isakmp_enc, algclass_isakmp_ameth + 1,
 2578: 				s->lifetime ? s->lifetime : rmconf->lifetime,
 2579: 				s->lifebyte ? s->lifebyte : rmconf->lifebyte,
 2580: 				s->encklen, s->vendorid, s->gssid,
 2581: 				rmconf);
 2582: 		if (trns_no == -1) {
 2583: 			plog(LLV_ERROR, LOCATION, NULL,
 2584: 				"failed to expand isakmp proposal.\n");
 2585: 			return -1;
 2586: 		}
 2587: 
 2588: 		s = s->prev;
 2589: 	}
 2590: 
 2591: 	if (rmconf->proposal == NULL) {
 2592: 		plog(LLV_ERROR, LOCATION, NULL,
 2593: 			"no proposal found.\n");
 2594: 		return -1;
 2595: 	}
 2596: 
 2597: 	return 0;
 2598: }
 2599: 
 2600: static void
 2601: clean_tmpalgtype()
 2602: {
 2603: 	int i;
 2604: 	for (i = 0; i < MAXALGCLASS; i++)
 2605: 		tmpalgtype[i] = 0;	/* means algorithm undefined. */
 2606: }
 2607: 
 2608: static int
 2609: expand_isakmpspec(prop_no, trns_no, types,
 2610: 		class, last, lifetime, lifebyte, encklen, vendorid, gssid,
 2611: 		rmconf)
 2612: 	int prop_no, trns_no;
 2613: 	int *types, class, last;
 2614: 	time_t lifetime;
 2615: 	int lifebyte;
 2616: 	int encklen;
 2617: 	int vendorid;
 2618: 	char *gssid;
 2619: 	struct remoteconf *rmconf;
 2620: {
 2621: 	struct isakmpsa *new;
 2622: 
 2623: 	/* debugging */
 2624:     {
 2625: 	int j;
 2626: 	char tb[10];
 2627: 	plog(LLV_DEBUG2, LOCATION, NULL,
 2628: 		"p:%d t:%d\n", prop_no, trns_no);
 2629: 	for (j = class; j < MAXALGCLASS; j++) {
 2630: 		snprintf(tb, sizeof(tb), "%d", types[j]);
 2631: 		plog(LLV_DEBUG2, LOCATION, NULL,
 2632: 			"%s%s%s%s\n",
 2633: 			s_algtype(j, types[j]),
 2634: 			types[j] ? "(" : "",
 2635: 			tb[0] == '0' ? "" : tb,
 2636: 			types[j] ? ")" : "");
 2637: 	}
 2638: 	plog(LLV_DEBUG2, LOCATION, NULL, "\n");
 2639:     }
 2640: 
 2641: #define TMPALGTYPE2STR(n) \
 2642: 	s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n])
 2643: 		/* check mandatory values */
 2644: 		if (types[algclass_isakmp_enc] == 0
 2645: 		 || types[algclass_isakmp_ameth] == 0
 2646: 		 || types[algclass_isakmp_hash] == 0
 2647: 		 || types[algclass_isakmp_dh] == 0) {
 2648: 			yyerror("few definition of algorithm "
 2649: 				"enc=%s ameth=%s hash=%s dhgroup=%s.\n",
 2650: 				TMPALGTYPE2STR(enc),
 2651: 				TMPALGTYPE2STR(ameth),
 2652: 				TMPALGTYPE2STR(hash),
 2653: 				TMPALGTYPE2STR(dh));
 2654: 			return -1;
 2655: 		}
 2656: #undef TMPALGTYPE2STR
 2657: 
 2658: 	/* set new sa */
 2659: 	new = newisakmpsa();
 2660: 	if (new == NULL) {
 2661: 		yyerror("failed to allocate isakmp sa");
 2662: 		return -1;
 2663: 	}
 2664: 	new->prop_no = prop_no;
 2665: 	new->trns_no = trns_no++;
 2666: 	new->lifetime = lifetime;
 2667: 	new->lifebyte = lifebyte;
 2668: 	new->enctype = types[algclass_isakmp_enc];
 2669: 	new->encklen = encklen;
 2670: 	new->authmethod = types[algclass_isakmp_ameth];
 2671: 	new->hashtype = types[algclass_isakmp_hash];
 2672: 	new->dh_group = types[algclass_isakmp_dh];
 2673: 	new->vendorid = vendorid;
 2674: #ifdef HAVE_GSSAPI
 2675: 	if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
 2676: 		if (gssid != NULL) {
 2677: 			if ((new->gssid = vmalloc(strlen(gssid))) == NULL) {
 2678: 				racoon_free(new);
 2679: 				yyerror("failed to allocate gssid");
 2680: 				return -1;
 2681: 			}
 2682: 			memcpy(new->gssid->v, gssid, new->gssid->l);
 2683: 			racoon_free(gssid);
 2684: 		} else {
 2685: 			/*
 2686: 			 * Allocate the default ID so that it gets put
 2687: 			 * into a GSS ID attribute during the Phase 1
 2688: 			 * exchange.
 2689: 			 */
 2690: 			new->gssid = gssapi_get_default_gss_id();
 2691: 		}
 2692: 	}
 2693: #endif
 2694: 	insisakmpsa(new, rmconf);
 2695: 
 2696: 	return trns_no;
 2697: }
 2698: 
 2699: #if 0
 2700: /*
 2701:  * fix lifebyte.
 2702:  * Must be more than 1024B because its unit is kilobytes.
 2703:  * That is defined RFC2407.
 2704:  */
 2705: static int
 2706: fix_lifebyte(t)
 2707: 	unsigned long t;
 2708: {
 2709: 	if (t < 1024) {
 2710: 		yyerror("byte size should be more than 1024B.");
 2711: 		return 0;
 2712: 	}
 2713: 
 2714: 	return(t / 1024);
 2715: }
 2716: #endif
 2717: 
 2718: int
 2719: cfparse()
 2720: {
 2721: 	int error;
 2722: 
 2723: 	yyerrorcount = 0;
 2724: 	yycf_init_buffer();
 2725: 
 2726: 	if (yycf_switch_buffer(lcconf->racoon_conf) != 0) {
 2727: 		plog(LLV_ERROR, LOCATION, NULL, 
 2728: 		    "could not read configuration file \"%s\"\n", 
 2729: 		    lcconf->racoon_conf);
 2730: 		return -1;
 2731: 	}
 2732: 
 2733: 	error = yyparse();
 2734: 	if (error != 0) {
 2735: 		if (yyerrorcount) {
 2736: 			plog(LLV_ERROR, LOCATION, NULL,
 2737: 				"fatal parse failure (%d errors)\n",
 2738: 				yyerrorcount);
 2739: 		} else {
 2740: 			plog(LLV_ERROR, LOCATION, NULL,
 2741: 				"fatal parse failure.\n");
 2742: 		}
 2743: 		return -1;
 2744: 	}
 2745: 
 2746: 	if (error == 0 && yyerrorcount) {
 2747: 		plog(LLV_ERROR, LOCATION, NULL,
 2748: 			"parse error is nothing, but yyerrorcount is %d.\n",
 2749: 				yyerrorcount);
 2750: 		exit(1);
 2751: 	}
 2752: 
 2753: 	yycf_clean_buffer();
 2754: 
 2755: 	plog(LLV_DEBUG2, LOCATION, NULL, "parse successed.\n");
 2756: 
 2757: 	return 0;
 2758: }
 2759: 
 2760: int
 2761: cfreparse()
 2762: {
 2763: 	flushph2();
 2764: 	flushph1();
 2765: 	flushrmconf();
 2766: 	flushsainfo();
 2767: 	clean_tmpalgtype();
 2768: 	return(cfparse());
 2769: }
 2770: 
 2771: #ifdef ENABLE_ADMINPORT
 2772: static void
 2773: adminsock_conf(path, owner, group, mode_dec)
 2774: 	vchar_t *path;
 2775: 	vchar_t *owner;
 2776: 	vchar_t *group;
 2777: 	int mode_dec;
 2778: {
 2779: 	struct passwd *pw = NULL;
 2780: 	struct group *gr = NULL;
 2781: 	mode_t mode = 0;
 2782: 	uid_t uid;
 2783: 	gid_t gid;
 2784: 	int isnum;
 2785: 
 2786: 	adminsock_path = path->v;
 2787: 
 2788: 	if (owner == NULL)
 2789: 		return;
 2790: 
 2791: 	errno = 0;
 2792: 	uid = atoi(owner->v);
 2793: 	isnum = !errno;
 2794: 	if (((pw = getpwnam(owner->v)) == NULL) && !isnum)
 2795: 		yyerror("User \"%s\" does not exist", owner->v);
 2796: 
 2797: 	if (pw)
 2798: 		adminsock_owner = pw->pw_uid;
 2799: 	else
 2800: 		adminsock_owner = uid;
 2801: 
 2802: 	if (group == NULL)
 2803: 		return;
 2804: 
 2805: 	errno = 0;
 2806: 	gid = atoi(group->v);
 2807: 	isnum = !errno;
 2808: 	if (((gr = getgrnam(group->v)) == NULL) && !isnum)
 2809: 		yyerror("Group \"%s\" does not exist", group->v);
 2810: 
 2811: 	if (gr)
 2812: 		adminsock_group = gr->gr_gid;
 2813: 	else
 2814: 		adminsock_group = gid;
 2815: 
 2816: 	if (mode_dec == -1)
 2817: 		return;
 2818: 
 2819: 	if (mode_dec > 777)
 2820: 		yyerror("Mode 0%03o is invalid", mode_dec);
 2821: 	if (mode_dec >= 400) { mode += 0400; mode_dec -= 400; }
 2822: 	if (mode_dec >= 200) { mode += 0200; mode_dec -= 200; }
 2823: 	if (mode_dec >= 100) { mode += 0200; mode_dec -= 100; }
 2824: 
 2825: 	if (mode_dec > 77)
 2826: 		yyerror("Mode 0%03o is invalid", mode_dec);
 2827: 	if (mode_dec >= 40) { mode += 040; mode_dec -= 40; }
 2828: 	if (mode_dec >= 20) { mode += 020; mode_dec -= 20; }
 2829: 	if (mode_dec >= 10) { mode += 020; mode_dec -= 10; }
 2830: 
 2831: 	if (mode_dec > 7)
 2832: 		yyerror("Mode 0%03o is invalid", mode_dec);
 2833: 	if (mode_dec >= 4) { mode += 04; mode_dec -= 4; }
 2834: 	if (mode_dec >= 2) { mode += 02; mode_dec -= 2; }
 2835: 	if (mode_dec >= 1) { mode += 02; mode_dec -= 1; }
 2836: 	
 2837: 	adminsock_mode = mode;
 2838: 
 2839: 	return;
 2840: }
 2841: #endif

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