File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / cfparse.y
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 5 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_0p0, v0_8_0, HEAD
ipsec-tools

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

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