121923Sdavidn/*	$NetBSD: cfparse.y,v 1.53 2020/11/25 18:11:00 bouyer Exp $	*/
221923Sdavidn
321923Sdavidn/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
421923Sdavidn
521923Sdavidn%{
621923Sdavidn/*
721923Sdavidn * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project.
821923Sdavidn * All rights reserved.
921923Sdavidn *
1021923Sdavidn * Redistribution and use in source and binary forms, with or without
1121923Sdavidn * modification, are permitted provided that the following conditions
1221923Sdavidn * are met:
1321923Sdavidn * 1. Redistributions of source code must retain the above copyright
1421923Sdavidn *    notice, this list of conditions and the following disclaimer.
1521923Sdavidn * 2. Redistributions in binary form must reproduce the above copyright
1621923Sdavidn *    notice, this list of conditions and the following disclaimer in the
1721923Sdavidn *    documentation and/or other materials provided with the distribution.
1821923Sdavidn * 3. Neither the name of the project nor the names of its contributors
1921923Sdavidn *    may be used to endorse or promote products derived from this software
2050477Speter *    without specific prior written permission.
2121923Sdavidn *
22235211Sgjb * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2321923Sdavidn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2479535Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2521923Sdavidn * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2621923Sdavidn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2727573Scharnier * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2821923Sdavidn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2968963Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30230549Strociny * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3121923Sdavidn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3227573Scharnier * SUCH DAMAGE.
33220358Spluknet */
3468963Sru
35107267Sru#include "config.h"
3621923Sdavidn
37220358Spluknet#include <sys/types.h>
3821923Sdavidn#include <sys/param.h>
39107267Sru#include <sys/queue.h>
4071895Sru#include <sys/socket.h>
41107267Sru
42107267Sru#include <netinet/in.h>
4321923Sdavidn#include PATH_IPSEC_H
4495124Scharnier
4595124Scharnier#ifdef ENABLE_HYBRID
4695124Scharnier#include <arpa/inet.h>
4721923Sdavidn#endif
4821923Sdavidn
4921923Sdavidn#include <stdlib.h>
5021923Sdavidn#include <stdio.h>
5158609Scharnier#include <string.h>
52107267Sru#include <errno.h>
5372477Sru#include <netdb.h>
5472477Sru#include <pwd.h>
5572477Sru#include <grp.h>
5668963Sru
57107267Sru#include "var.h"
5821923Sdavidn#include "misc.h"
5972477Sru#include "vmbuf.h"
6021923Sdavidn#include "plog.h"
6121923Sdavidn#include "sockmisc.h"
6221923Sdavidn#include "str2val.h"
6371895Sru#include "genlist.h"
64107267Sru#include "debug.h"
65107267Sru
66107267Sru#include "admin.h"
6721923Sdavidn#include "privsep.h"
6821923Sdavidn#include "cfparse_proto.h"
6921923Sdavidn#include "cftoken_proto.h"
7021923Sdavidn#include "algorithm.h"
7121923Sdavidn#include "localconf.h"
7221923Sdavidn#include "policy.h"
7321923Sdavidn#include "sainfo.h"
7421923Sdavidn#include "oakley.h"
7521923Sdavidn#include "pfkey.h"
7621923Sdavidn#include "remoteconf.h"
77107267Sru#include "grabmyaddr.h"
7878686Sdd#include "isakmp_var.h"
7921923Sdavidn#include "handler.h"
8021923Sdavidn#include "isakmp.h"
8121923Sdavidn#include "nattraversal.h"
82107267Sru#include "isakmp_frag.h"
8321923Sdavidn#ifdef ENABLE_HYBRID
8421923Sdavidn#include "resolv.h"
8521923Sdavidn#include "isakmp_unity.h"
86107267Sru#include "isakmp_xauth.h"
8721923Sdavidn#include "isakmp_cfg.h"
88107267Sru#endif
8921923Sdavidn#include "ipsec_doi.h"
9021923Sdavidn#include "strnames.h"
9121923Sdavidn#include "gcmalloc.h"
92107788Sru#ifdef HAVE_GSSAPI
93131491Sru#include "gssapi.h"
94107267Sru#endif
95107267Sru#include "vendorid.h"
96107267Sru#include "rsalist.h"
9758609Scharnier#include "crypto_openssl.h"
98107267Sru
99107267Srustruct secprotospec {
100107267Sru	int prop_no;
101107267Sru	int trns_no;
102107267Sru	int strength;		/* for isakmp/ipsec */
10321923Sdavidn	int encklen;		/* for isakmp/ipsec */
104107267Sru	time_t lifetime;	/* for isakmp */
105107267Sru	int lifebyte;		/* for isakmp */
10621923Sdavidn	int proto_id;		/* for ipsec (isakmp?) */
10771895Sru	int ipsec_level;	/* for ipsec */
10821923Sdavidn	int encmode;		/* for ipsec */
10921923Sdavidn	int vendorid;		/* for isakmp */
11021923Sdavidn	char *gssid;
11121923Sdavidn	struct sockaddr *remote;
11221923Sdavidn	int algclass[MAXALGCLASS];
11321923Sdavidn
11421923Sdavidn	struct secprotospec *next;	/* the tail is the most prefiered. */
11521923Sdavidn	struct secprotospec *prev;
11621923Sdavidn};
11758609Scharnier
11821923Sdavidnstatic int num2dhgroup[] = {
11921923Sdavidn	0,
120107267Sru	OAKLEY_ATTR_GRP_DESC_MODP768,
12121923Sdavidn	OAKLEY_ATTR_GRP_DESC_MODP1024,
12221923Sdavidn	OAKLEY_ATTR_GRP_DESC_EC2N155,
12358609Scharnier	OAKLEY_ATTR_GRP_DESC_EC2N185,
12421923Sdavidn	OAKLEY_ATTR_GRP_DESC_MODP1536,
12521923Sdavidn	0,
12621923Sdavidn	0,
12798840Ssheldonh	0,
12898840Ssheldonh	0,
12998840Ssheldonh	0,
130107267Sru	0,
13121923Sdavidn	0,
13221923Sdavidn	0,
133107267Sru	OAKLEY_ATTR_GRP_DESC_MODP2048,
134107267Sru	OAKLEY_ATTR_GRP_DESC_MODP3072,
13521923Sdavidn	OAKLEY_ATTR_GRP_DESC_MODP4096,
13621923Sdavidn	OAKLEY_ATTR_GRP_DESC_MODP6144,
137107267Sru	OAKLEY_ATTR_GRP_DESC_MODP8192
138107267Sru};
139107267Sru
140107267Srustatic struct remoteconf *cur_rmconf = NULL;
141107267Srustatic int tmpalgtype[MAXALGCLASS] = {0};
142107267Srustatic struct sainfo *cur_sainfo = NULL;
143107267Srustatic int cur_algclass = 0;
144107267Srustatic int oldloglevel = LLV_BASE;
145107267Sru
146230549Strocinystatic struct secprotospec *newspspec __P((void));
147230549Strocinystatic void insspspec __P((struct remoteconf *, struct secprotospec *));
148230549Strocinyvoid dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src));
14921923Sdavidnvoid flushspspec __P((struct remoteconf *));
150107267Srustatic void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int));
151107267Sru
152107267Srustatic int set_isakmp_proposal __P((struct remoteconf *));
15321923Sdavidnstatic void clean_tmpalgtype __P((void));
15421923Sdavidnstatic int expand_isakmpspec __P((int, int, int *,
15521923Sdavidn	int, int, time_t, int, int, int, char *, struct remoteconf *));
15621923Sdavidn
15721923Sdavidnvoid freeetypes (struct etypes **etypes);
158107267Sru
15921923Sdavidnstatic int load_x509(const char *file, char **filenameptr,
160107267Sru		     vchar_t **certptr)
161107267Sru{
162107267Sru	char path[PATH_MAX];
16321923Sdavidn
16421923Sdavidn	getpathname(path, sizeof(path), LC_PATHTYPE_CERT, file);
16521923Sdavidn	*certptr = eay_get_x509cert(path);
16621923Sdavidn	if (*certptr == NULL)
16721923Sdavidn		return -1;
168107267Sru
16921923Sdavidn	*filenameptr = racoon_strdup(file);
170107267Sru	STRDUP_FATAL(*filenameptr);
171107267Sru
172107267Sru	return 0;
173107267Sru}
174107267Sru
17521923Sdavidnstatic int process_rmconf(void)
17621923Sdavidn{
17721923Sdavidn
17821923Sdavidn	/* check a exchange mode */
17979755Sdd	if (cur_rmconf->etypes == NULL) {
18021923Sdavidn		yyerror("no exchange mode specified.\n");
181107267Sru		return -1;
182235211Sgjb	}
183107267Sru
184107267Sru	if (cur_rmconf->idvtype == IDTYPE_UNDEFINED)
185107267Sru		cur_rmconf->idvtype = IDTYPE_ADDRESS;
18621923Sdavidn
18721923Sdavidn	if (cur_rmconf->idvtype == IDTYPE_ASN1DN) {
18836649Ssteve		if (cur_rmconf->mycertfile) {
18921923Sdavidn			if (cur_rmconf->idv)
19058609Scharnier				yywarn("Both CERT and ASN1 ID "
19121923Sdavidn				       "are set. Hope this is OK.\n");
192107267Sru			/* TODO: Preparse the DN here */
193107267Sru		} else if (cur_rmconf->idv) {
194107267Sru			/* OK, using asn1dn without X.509. */
19552071Sgreen		} else {
196107267Sru			yyerror("ASN1 ID not specified "
197107267Sru				"and no CERT defined!\n");
198107267Sru			return -1;
199107267Sru		}
200107267Sru	}
20121923Sdavidn
20221923Sdavidn	if (duprmconf_finish(cur_rmconf))
203107267Sru		return -1;
204107267Sru
205107267Sru	if (set_isakmp_proposal(cur_rmconf) != 0)
206107267Sru		return -1;
207107267Sru
20821923Sdavidn	/* DH group settting if aggressive mode is there. */
209107267Sru	if (check_etypeok(cur_rmconf, (void*) ISAKMP_ETYPE_AGG)) {
21058609Scharnier		struct isakmpsa *p;
211107267Sru		int b = 0;
21221923Sdavidn
213107267Sru		/* DH group */
21458609Scharnier		for (p = cur_rmconf->proposal; p; p = p->next) {
215107267Sru			if (b == 0 || (b && b == p->dh_group)) {
21621923Sdavidn				b = p->dh_group;
217107267Sru				continue;
21858609Scharnier			}
219107267Sru			yyerror("DH group must be equal "
22027573Scharnier				"in all proposals "
221107267Sru				"when aggressive mode is "
22258609Scharnier				"used.\n");
223107267Sru			return -1;
224107267Sru		}
225107267Sru		cur_rmconf->dh_group = b;
226107267Sru
227107267Sru		if (cur_rmconf->dh_group == 0) {
228107267Sru			yyerror("DH group must be set in the proposal.\n");
229107267Sru			return -1;
230107267Sru		}
231107267Sru
232107267Sru		/* DH group settting if PFS is required. */
233107267Sru		if (oakley_setdhgroup(cur_rmconf->dh_group,
234107267Sru				&cur_rmconf->dhgrp) < 0) {
235107267Sru			yyerror("failed to set DH value.\n");
23658609Scharnier			return -1;
237107267Sru		}
23821923Sdavidn	}
239107267Sru
24058609Scharnier	insrmconf(cur_rmconf);
241107267Sru	cur_rmconf = NULL;
24221923Sdavidn
243107267Sru	return 0;
24458609Scharnier}
245107267Sru
246107267Sru/* some frequently used warning texts */
247107267Srustatic const char error_message_hybrid_config_not_configured[] = "racoon not configured with --enable-hybrid\n";
248107267Srustatic const char error_message_ldap_config_not_configured[]   = "racoon not configured with --with-libldap\n";
249107267Srustatic const char error_message_admin_port_not_compiled_in[] = "admin port support not compiled in\n";
250107267Srustatic const char error_message_natt_not_compiled_in[] = "NAT-T support not compiled in\n";
251107267Srustatic const char error_message_dpd_not_compiled_in[] = "DPD support not compiled in\n";
25244786Sghelmer
253107267Sru/* macros for aborting the parsing with freeing up allocated memory */
254107267Sru#define ABORT_CLEANUP {delrmconf(cur_rmconf); delsainfo(cur_sainfo); YYABORT;}
255107267Sru#define ABORT() ABORT_CLEANUP
256107267Sru
257107267Sru#define ABORT_AND_VFREE(val0) {\
25898850Sdillon	vfree(val0); val0 = NULL;\
259107267Sru	ABORT_CLEANUP}
26098850Sdillon
26198850Sdillon#define ABORT_AND_RACOON_FREE(val0) {\
26298850Sdillon	racoon_free(val0); val0 = NULL;\
26398850Sdillon	ABORT_CLEANUP}
26498850Sdillon
26598850Sdillon#define ABORT_AND_VFREE2(val0, val1) {\
26698850Sdillon	vfree(val0); val0 = NULL;\
26798850Sdillon	vfree(val1); val1 = NULL;\
268182685Sed	ABORT_CLEANUP}
269182685Sed
270182685Sed#define ABORT_AND_RACOON_FREE2(val0, val1) {\
271182685Sed	racoon_free(val0); val0 = NULL;\
272220358Spluknet	racoon_free(val1); val1 = NULL;\
273220358Spluknet	ABORT_CLEANUP}
274220358Spluknet%}
275220358Spluknet
27698840Ssheldonh%union {
27721923Sdavidn	unsigned long num;
27858609Scharnier	vchar_t *val;
279107267Sru	struct remoteconf *rmconf;
280107267Sru	struct sockaddr *saddr;
28158609Scharnier	struct sainfoalg *alg;
282107267Sru}
283107267Sru
284107267Sru	/* privsep */
28558609Scharnier%token PRIVSEP USER GROUP CHROOT
286107267Sru	/* path */
28758609Scharnier%token PATH PATHTYPE
288107267Sru	/* include */
28921923Sdavidn%token INCLUDE
29021923Sdavidn	/* PFKEY_BUFFER */
29121923Sdavidn%token PFKEY_BUFFER
292107267Sru	/* logging */
293107267Sru%token LOGGING LOGLEV
29421923Sdavidn	/* padding */
295107267Sru%token PADDING PAD_RANDOMIZE PAD_RANDOMIZELEN PAD_MAXLEN PAD_STRICT PAD_EXCLTAIL
29621923Sdavidn	/* listen */
297107267Sru%token LISTEN X_ISAKMP X_ISAKMP_NATT X_ADMIN STRICT_ADDRESS ADMINSOCK DISABLED
29821923Sdavidn	/* ldap config */
299107267Sru%token LDAPCFG LDAP_URI LDAP_HOST LDAP_PORT LDAP_TLS LDAP_PVER LDAP_DEBUG LDAP_TIMEOUT LDAP_BASE LDAP_BIND_DN LDAP_BIND_PW LDAP_SUBTREE
30021923Sdavidn%token LDAP_ATTR_USER LDAP_ATTR_ADDR LDAP_ATTR_MASK LDAP_ATTR_GROUP LDAP_ATTR_MEMBER
301107267Sru	/* radius config */
30236649Ssteve%token RADCFG RAD_AUTH RAD_ACCT RAD_TIMEOUT RAD_RETRIES
30321923Sdavidn	/* modecfg */
30421923Sdavidn%token MODECFG CFG_NET4 CFG_MASK4 CFG_DNS4 CFG_NBNS4 CFG_DEFAULT_DOMAIN
30521923Sdavidn%token CFG_AUTH_SOURCE CFG_AUTH_GROUPS CFG_SYSTEM CFG_RADIUS CFG_PAM CFG_LDAP CFG_LOCAL CFG_NONE
306107267Sru%token CFG_GROUP_SOURCE CFG_ACCOUNTING CFG_CONF_SOURCE CFG_MOTD CFG_POOL_SIZE CFG_AUTH_THROTTLE
30721923Sdavidn%token CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL CFG_SPLIT_INCLUDE CFG_SPLIT_DNS
30821923Sdavidn%token CFG_PFS_GROUP CFG_SAVE_PASSWD
30921923Sdavidn
310107267Sru	/* timer */
311107267Sru%token RETRY RETRY_COUNTER RETRY_INTERVAL RETRY_PERSEND
312107267Sru%token RETRY_PHASE1 RETRY_PHASE2 NATT_KA
31321923Sdavidn	/* algorithm */
314107267Sru%token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE
31521923Sdavidn	/* sainfo */
316107267Sru%token SAINFO FROM
31721923Sdavidn	/* remote */
318107267Sru%token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS
31921923Sdavidn%token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE
320107267Sru%token CERTIFICATE_TYPE CERTTYPE PEERS_CERTFILE CA_TYPE
32121923Sdavidn%token VERIFY_CERT SEND_CERT SEND_CR MATCH_EMPTY_CR
322107267Sru%token IDENTIFIERTYPE IDENTIFIERQUAL MY_IDENTIFIER
32321923Sdavidn%token PEERS_IDENTIFIER VERIFY_IDENTIFIER
32421923Sdavidn%token DNSSEC CERT_X509 CERT_PLAINRSA
325107267Sru%token NONCE_SIZE DH_GROUP KEEPALIVE PASSIVE INITIAL_CONTACT
32621923Sdavidn%token NAT_TRAVERSAL REMOTE_FORCE_LEVEL
327107267Sru%token PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL
32858609Scharnier%token GENERATE_POLICY GENERATE_LEVEL SUPPORT_PROXY
32921923Sdavidn%token PROPOSAL
33021923Sdavidn%token EXEC_PATH EXEC_COMMAND EXEC_SUCCESS EXEC_FAILURE
331107267Sru%token GSS_ID GSS_ID_ENC GSS_ID_ENCTYPE
33221923Sdavidn%token COMPLEX_BUNDLE
33321923Sdavidn%token DPD DPD_DELAY DPD_RETRY DPD_MAXFAIL
334107267Sru%token PH1ID
335107267Sru%token XAUTH_LOGIN WEAK_PHASE1_CHECK
336107267Sru%token REKEY
337107267Sru
33821923Sdavidn%token PREFIX PORT PORTANY UL_PROTO ANY IKE_FRAG ESP_FRAG MODE_CFG
339107267Sru%token PFS_GROUP LIFETIME LIFETYPE_TIME LIFETYPE_BYTE STRENGTH REMOTEID
34021923Sdavidn
34179755Sdd%token SCRIPT PHASE1_UP PHASE1_DOWN PHASE1_DEAD
34249734Schris
343107267Sru%token NUMBER SWITCH BOOLEAN
344107267Sru%token HEXSTRING QUOTEDSTRING ADDRSTRING ADDRRANGE
345107267Sru%token UNITTYPE_BYTE UNITTYPE_KBYTES UNITTYPE_MBYTES UNITTYPE_TBYTES
346107267Sru%token UNITTYPE_SEC UNITTYPE_MIN UNITTYPE_HOUR
347107267Sru%token EOS BOC EOC COMMA
348107267Sru
34921923Sdavidn%type <num> NUMBER BOOLEAN SWITCH keylength
35021923Sdavidn%type <num> PATHTYPE IDENTIFIERTYPE IDENTIFIERQUAL LOGLEV GSS_ID_ENCTYPE
35158609Scharnier%type <num> ALGORITHM_CLASS dh_group_num
35221923Sdavidn%type <num> ALGORITHMTYPE STRENGTHTYPE
35321923Sdavidn%type <num> PREFIX prefix PORT port ike_port
354140368Sru%type <num> ul_proto UL_PROTO
35595124Scharnier%type <num> EXCHANGETYPE DOITYPE SITUATIONTYPE
35695124Scharnier%type <num> CERTTYPE CERT_X509 CERT_PLAINRSA PROPOSAL_CHECK_LEVEL REMOTE_FORCE_LEVEL GENERATE_LEVEL
35795124Scharnier%type <num> unittype_time unittype_byte
358107267Sru%type <val> QUOTEDSTRING HEXSTRING ADDRSTRING ADDRRANGE sainfo_id
359107267Sru%type <val> identifierstring
360131491Sru%type <saddr> remote_index ike_addrinfo_port
36121923Sdavidn%type <alg> algorithm
36221923Sdavidn%type <saddr> ike_addrinfo_port_natt
36321923Sdavidn%type <num> ike_port_natt
36421923Sdavidn
36558609Scharnier%%
366107267Sru
367107267Srustatements
36821923Sdavidn	:	/* nothing */
36921923Sdavidn	|	statements statement
37021923Sdavidn	;
37121923Sdavidnstatement
37221923Sdavidn	:	privsep_statement
37321923Sdavidn	|	path_statement
37421923Sdavidn	|	include_statement
37535843Smax	|	pfkey_statement
37635843Smax	|	gssenc_statement
37729988Swosch	|	logging_statement
37844786Sghelmer	|	padding_statement
379220516Strasz	|	listen_statement
38044786Sghelmer	|	ldapcfg_statement
38121923Sdavidn	|	radcfg_statement
38295124Scharnier	|	modecfg_statement
38395124Scharnier	|	timer_statement
384107267Sru	|	sainfo_statement
385107267Sru	|	remote_statement
386107267Sru	|	special_statement
38721923Sdavidn	;
38821923Sdavidn
38958609Scharnier	/* privsep */
39058609Scharnierprivsep_statement
391107788Sru	:	PRIVSEP BOC privsep_stmts EOC
39221923Sdavidn	;
39321923Sdavidnprivsep_stmts
39458609Scharnier	:	/* nothing */
39571895Sru	|	privsep_stmts privsep_stmt
39658609Scharnier	;
39721923Sdavidnprivsep_stmt
39858609Scharnier	:	USER QUOTEDSTRING
39958609Scharnier		{
40058609Scharnier			struct passwd *pw = getpwnam($2->v);
40158609Scharnier			vfree($2);
40221923Sdavidn
40321923Sdavidn			if (pw == NULL) {
40495124Scharnier				yyerror("unknown user \"%s\"", $2->v);
40595124Scharnier				ABORT();
40695124Scharnier			}
40721923Sdavidn
40827450Sdavidn			lcconf->uid = pw->pw_uid;
40958609Scharnier		}
41058609Scharnier		EOS
41158609Scharnier	|	USER NUMBER { lcconf->uid = $2; } EOS
41221923Sdavidn	|	GROUP QUOTEDSTRING
413		{
414			struct group *gr = getgrnam($2->v);
415			vfree($2);
416
417			if (gr == NULL) {
418				yyerror("unknown group \"%s\"", $2->v);
419				ABORT();
420			}
421
422			lcconf->gid = gr->gr_gid;
423		}
424		EOS
425	|	GROUP NUMBER { lcconf->gid = $2; } EOS
426	|	CHROOT QUOTEDSTRING
427		{
428			lcconf_setchroot(racoon_strdup($2->v));
429			vfree($2);
430		} EOS
431	;
432
433	/* path */
434path_statement
435	:	PATH PATHTYPE QUOTEDSTRING
436		{
437			char * path = racoon_strdup($3->v);
438
439			if (path == NULL) {
440				yyerror("copy string fatal error: %s", $3->v);
441				ABORT_AND_VFREE($3);
442			}
443
444			if (lcconf_setpath(path, $2) < 0) {
445				yyerror("invalid path type %d", $2);
446				ABORT_AND_VFREE($3);
447			}
448
449			vfree($3);
450		}
451		EOS
452	;
453
454	/* special */
455special_statement
456	:	COMPLEX_BUNDLE SWITCH { lcconf->complex_bundle = $2; } EOS
457	;
458
459	/* include */
460include_statement
461	:	INCLUDE QUOTEDSTRING EOS
462		{
463			char path[MAXPATHLEN];
464
465			getpathname(path, sizeof(path),
466				LC_PATHTYPE_INCLUDE, $2->v);
467			vfree($2);
468			if (yycf_switch_buffer(path) != 0)
469				ABORT();
470		}
471	;
472
473    /* pfkey_buffer */
474pfkey_statement
475    :   PFKEY_BUFFER NUMBER EOS
476        {
477			lcconf->pfkey_buffer_size = $2;
478        }
479    ;
480	/* gss_id_enc */
481gssenc_statement
482	:	GSS_ID_ENC GSS_ID_ENCTYPE EOS
483		{
484			if ($2 >= LC_GSSENC_MAX) {
485				yyerror("invalid GSS ID encoding %d", $2);
486				ABORT();
487			}
488
489			lcconf->gss_id_enc = $2;
490		}
491	;
492
493	/* logging */
494logging_statement
495	:	LOGGING log_level EOS
496	;
497log_level
498	:	LOGLEV
499		{
500			/*
501			 * set the loglevel to the value specified
502			 * in the configuration file plus the number
503			 * of -d options specified on the command line
504			 */
505			loglevel += $1 - oldloglevel;
506			oldloglevel = $1;
507		}
508	;
509
510	/* padding */
511padding_statement
512	:	PADDING BOC padding_stmts EOC
513	;
514padding_stmts
515	:	/* nothing */
516	|	padding_stmts padding_stmt
517	;
518padding_stmt
519	:	PAD_RANDOMIZE SWITCH { lcconf->pad_random = $2; } EOS
520	|	PAD_RANDOMIZELEN SWITCH { lcconf->pad_randomlen = $2; } EOS
521	|	PAD_MAXLEN NUMBER { lcconf->pad_maxsize = $2; } EOS
522	|	PAD_STRICT SWITCH { lcconf->pad_strict = $2; } EOS
523	|	PAD_EXCLTAIL SWITCH { lcconf->pad_excltail = $2; } EOS
524	;
525
526	/* listen */
527listen_statement
528	:	LISTEN BOC listen_stmts EOC
529	;
530listen_stmts
531	:	/* nothing */
532	|	listen_stmts listen_stmt
533	;
534listen_stmt
535	:	X_ISAKMP ike_addrinfo_port
536		{
537			myaddr_listen($2, FALSE);
538			racoon_free($2);
539		}
540		EOS
541	|	X_ISAKMP_NATT ike_addrinfo_port_natt
542		{
543#ifdef ENABLE_NATT
544			myaddr_listen($2, TRUE);
545#else
546
547			yywarn(error_message_natt_not_compiled_in);
548#endif
549			racoon_free($2);
550		}
551		EOS
552	|	ADMINSOCK QUOTEDSTRING QUOTEDSTRING QUOTEDSTRING NUMBER
553		{
554#ifdef ENABLE_ADMINPORT
555			adminsock_conf($2, $3, $4, $5);
556#else
557			yywarn(error_message_admin_port_not_compiled_in);
558#endif
559			vfree($2);vfree($3);vfree($4);
560		}
561		EOS
562	|	ADMINSOCK QUOTEDSTRING
563		{
564#ifdef ENABLE_ADMINPORT
565			adminsock_conf($2, NULL, NULL, -1);
566#else
567			yywarn(error_message_admin_port_not_compiled_in);
568#endif
569			vfree($2);
570		}
571		EOS
572	|	ADMINSOCK DISABLED
573		{
574#ifdef ENABLE_ADMINPORT
575			adminsock_path = NULL;
576#else
577			yywarn(error_message_admin_port_not_compiled_in);
578#endif
579		}
580		EOS
581	|	STRICT_ADDRESS { lcconf->strict_address = TRUE; } EOS
582	;
583ike_addrinfo_port
584	:	ADDRSTRING ike_port
585		{
586			char portbuf[10];
587
588			snprintf(portbuf, sizeof(portbuf), "%ld", $2);
589			$$ = str2saddr($1->v, portbuf);
590
591			vfree($1);
592			if (!$$)
593				ABORT();
594		}
595	;
596ike_addrinfo_port_natt
597	:	ADDRSTRING ike_port_natt
598		{
599			char portbuf[10];
600
601			snprintf(portbuf, sizeof(portbuf), "%ld", $2);
602			$$ = str2saddr($1->v, portbuf);
603
604			vfree($1);
605			if (!$$)
606				ABORT();
607		}
608	;
609ike_port
610	:	/* nothing */	{	$$ = lcconf->port_isakmp; }
611	|	PORT		{ $$ = $1; }
612	;
613ike_port_natt
614	:	/* nothing */
615		{
616			$$ = lcconf->port_isakmp_natt;
617		}
618	|	PORT
619		{
620			$$ = $1;
621#ifndef ENABLE_NATT
622			yywarn(error_message_natt_not_compiled_in);
623#endif
624		}
625	;
626	/* radius configuration */
627radcfg_statement
628	:	RADCFG {
629#ifndef ENABLE_HYBRID
630			yyerror(error_message_hybrid_config_not_configured);
631			ABORT();
632#endif
633#ifndef HAVE_LIBRADIUS
634			yyerror("racoon not configured with --with-libradius");
635			ABORT();
636#endif
637#ifdef ENABLE_HYBRID
638#ifdef HAVE_LIBRADIUS
639			xauth_rad_config.timeout = 3;
640			xauth_rad_config.retries = 3;
641#endif
642#endif
643		} BOC radcfg_stmts EOC
644	;
645radcfg_stmts
646	:	/* nothing */
647	|	radcfg_stmts radcfg_stmt
648	;
649radcfg_stmt
650	:	RAD_AUTH QUOTEDSTRING QUOTEDSTRING
651		{
652#ifdef ENABLE_HYBRID
653#ifdef HAVE_LIBRADIUS
654			int i = xauth_rad_config.auth_server_count;
655			if (i == RADIUS_MAX_SERVERS) {
656				yyerror("maximum radius auth servers exceeded");
657				ABORT_AND_VFREE2($2, $3);
658			}
659
660			xauth_rad_config.auth_server_list[i].host = vdup($2);
661			xauth_rad_config.auth_server_list[i].secret = vdup($3);
662			xauth_rad_config.auth_server_list[i].port = 0; /* default port */
663			xauth_rad_config.auth_server_count++;
664#endif
665#endif
666			vfree($2); vfree($3);
667		}
668		EOS
669	|	RAD_AUTH QUOTEDSTRING NUMBER QUOTEDSTRING
670		{
671#ifdef ENABLE_HYBRID
672#ifdef HAVE_LIBRADIUS
673			int i = xauth_rad_config.auth_server_count;
674			if (i == RADIUS_MAX_SERVERS) {
675				yyerror("maximum radius auth servers exceeded");
676				ABORT_AND_VFREE2($2, $4);
677			}
678
679			xauth_rad_config.auth_server_list[i].host = vdup($2);
680			xauth_rad_config.auth_server_list[i].secret = vdup($4);
681			xauth_rad_config.auth_server_list[i].port = $3;
682			xauth_rad_config.auth_server_count++;
683#endif
684#endif
685			vfree($2); vfree($4);
686		}
687		EOS
688	|	RAD_ACCT QUOTEDSTRING QUOTEDSTRING
689		{
690#ifdef ENABLE_HYBRID
691#ifdef HAVE_LIBRADIUS
692			int i = xauth_rad_config.acct_server_count;
693			if (i == RADIUS_MAX_SERVERS) {
694				yyerror("maximum radius account servers exceeded");
695				ABORT_AND_VFREE2($2, $3);
696			}
697
698			xauth_rad_config.acct_server_list[i].host = vdup($2);
699			xauth_rad_config.acct_server_list[i].secret = vdup($3);
700			xauth_rad_config.acct_server_list[i].port = 0; /* default port */
701			xauth_rad_config.acct_server_count++;
702#endif
703#endif
704			vfree($2); vfree($3);
705		}
706		EOS
707	|	RAD_ACCT QUOTEDSTRING NUMBER QUOTEDSTRING
708		{
709#ifdef ENABLE_HYBRID
710#ifdef HAVE_LIBRADIUS
711			int i = xauth_rad_config.acct_server_count;
712			if (i == RADIUS_MAX_SERVERS) {
713				yyerror("maximum radius account servers exceeded");
714				ABORT_AND_VFREE2($2, $4);
715			}
716
717			xauth_rad_config.acct_server_list[i].host = vdup($2);
718			xauth_rad_config.acct_server_list[i].secret = vdup($4);
719			xauth_rad_config.acct_server_list[i].port = $3;
720			xauth_rad_config.acct_server_count++;
721#endif
722#endif
723			vfree($2); vfree($4);
724		}
725		EOS
726	|	RAD_TIMEOUT NUMBER
727		{
728#ifdef ENABLE_HYBRID
729#ifdef HAVE_LIBRADIUS
730			xauth_rad_config.timeout = $2;
731#endif
732#endif
733		}
734		EOS
735	|	RAD_RETRIES NUMBER
736		{
737#ifdef ENABLE_HYBRID
738#ifdef HAVE_LIBRADIUS
739			xauth_rad_config.retries = $2;
740#endif
741#endif
742		}
743		EOS
744	;
745
746	/* ldap configuration */
747ldapcfg_statement
748	:	LDAPCFG {
749#ifndef ENABLE_HYBRID
750			yyerror(error_message_hybrid_config_not_configured);
751			ABORT();
752#endif
753#ifndef HAVE_LIBLDAP
754			yyerror(error_message_ldap_config_not_configured);
755			ABORT();
756#endif
757		} BOC ldapcfg_stmts EOC
758	;
759ldapcfg_stmts
760	:	/* nothing */
761	|	ldapcfg_stmts ldapcfg_stmt
762	;
763ldapcfg_stmt
764	:	LDAP_PVER NUMBER
765		{
766#ifdef ENABLE_HYBRID
767#ifdef HAVE_LIBLDAP
768			if (($2<2)||($2>3))
769				yywarn("invalid ldap protocol version (2|3)");
770
771			xauth_ldap_config.pver = $2;
772#endif
773#endif
774		}
775		EOS
776	|	LDAP_DEBUG NUMBER
777		{
778#ifdef ENABLE_HYBRID
779#ifdef HAVE_LIBLDAP
780			xauth_ldap_config.debug = $2;
781#endif
782#endif
783		}
784		EOS
785	|	LDAP_TIMEOUT NUMBER
786		{
787#ifdef ENABLE_HYBRID
788#ifdef HAVE_LIBLDAP
789			xauth_ldap_config.timeout = $2;
790#endif
791#endif
792		}
793		EOS
794	|	LDAP_URI QUOTEDSTRING
795		{
796#ifdef ENABLE_HYBRID
797#ifdef HAVE_LIBLDAP
798			if (xauth_ldap_config.uri != NULL)
799				vfree(xauth_ldap_config.uri);
800
801			xauth_ldap_config.uri = vdup($2);
802#endif
803#endif
804			vfree($2);
805		}
806		EOS
807	|	LDAP_HOST QUOTEDSTRING
808		{
809#ifdef ENABLE_HYBRID
810#ifdef HAVE_LIBLDAP
811			if (xauth_ldap_config.host != NULL)
812				vfree(xauth_ldap_config.host);
813
814			xauth_ldap_config.host = vdup($2);
815#endif
816#endif
817			vfree($2);
818		}
819		EOS
820	|	LDAP_PORT NUMBER
821		{
822#ifdef ENABLE_HYBRID
823#ifdef HAVE_LIBLDAP
824			xauth_ldap_config.port = $2;
825#endif
826#endif
827		}
828		EOS
829	|	LDAP_TLS SWITCH
830		{
831#ifdef ENABLE_HYBRID
832#ifdef HAVE_LIBLDAP
833			xauth_ldap_config.tls = $2;
834#endif
835#endif
836		}
837		EOS
838	|	LDAP_BASE QUOTEDSTRING
839		{
840#ifdef ENABLE_HYBRID
841#ifdef HAVE_LIBLDAP
842			if (xauth_ldap_config.base != NULL)
843				vfree(xauth_ldap_config.base);
844
845			xauth_ldap_config.base = vdup($2);
846#endif
847#endif
848			vfree($2);
849		}
850		EOS
851	|	LDAP_SUBTREE SWITCH
852		{
853#ifdef ENABLE_HYBRID
854#ifdef HAVE_LIBLDAP
855			xauth_ldap_config.subtree = $2;
856#endif
857#endif
858		}
859		EOS
860	|	LDAP_BIND_DN QUOTEDSTRING
861		{
862#ifdef ENABLE_HYBRID
863#ifdef HAVE_LIBLDAP
864			if (xauth_ldap_config.bind_dn != NULL)
865				vfree(xauth_ldap_config.bind_dn);
866
867			xauth_ldap_config.bind_dn = vdup($2);
868#endif
869#endif
870			vfree($2);
871		}
872		EOS
873	|	LDAP_BIND_PW QUOTEDSTRING
874		{
875#ifdef ENABLE_HYBRID
876#ifdef HAVE_LIBLDAP
877			if (xauth_ldap_config.bind_pw != NULL)
878				vfree(xauth_ldap_config.bind_pw);
879
880			xauth_ldap_config.bind_pw = vdup($2);
881#endif
882#endif
883			vfree($2);
884		}
885		EOS
886	|	LDAP_ATTR_USER QUOTEDSTRING
887		{
888#ifdef ENABLE_HYBRID
889#ifdef HAVE_LIBLDAP
890			if (xauth_ldap_config.attr_user != NULL)
891				vfree(xauth_ldap_config.attr_user);
892
893			xauth_ldap_config.attr_user = vdup($2);
894#endif
895#endif
896			vfree($2);
897		}
898		EOS
899	|	LDAP_ATTR_ADDR QUOTEDSTRING
900		{
901#ifdef ENABLE_HYBRID
902#ifdef HAVE_LIBLDAP
903			if (xauth_ldap_config.attr_addr != NULL)
904				vfree(xauth_ldap_config.attr_addr);
905
906			xauth_ldap_config.attr_addr = vdup($2);
907#endif
908#endif
909			vfree($2);
910		}
911		EOS
912	|	LDAP_ATTR_MASK QUOTEDSTRING
913		{
914#ifdef ENABLE_HYBRID
915#ifdef HAVE_LIBLDAP
916			if (xauth_ldap_config.attr_mask != NULL)
917				vfree(xauth_ldap_config.attr_mask);
918
919			xauth_ldap_config.attr_mask = vdup($2);
920#endif
921#endif
922			vfree($2);
923		}
924		EOS
925	|	LDAP_ATTR_GROUP QUOTEDSTRING
926		{
927#ifdef ENABLE_HYBRID
928#ifdef HAVE_LIBLDAP
929			if (xauth_ldap_config.attr_group != NULL)
930				vfree(xauth_ldap_config.attr_group);
931
932			xauth_ldap_config.attr_group = vdup($2);
933#endif
934#endif
935			vfree($2);
936		}
937		EOS
938	|	LDAP_ATTR_MEMBER QUOTEDSTRING
939		{
940#ifdef ENABLE_HYBRID
941#ifdef HAVE_LIBLDAP
942			if (xauth_ldap_config.attr_member != NULL)
943				vfree(xauth_ldap_config.attr_member);
944
945			xauth_ldap_config.attr_member = vdup($2);
946#endif
947#endif
948			vfree($2);
949		}
950		EOS
951	;
952
953	/* modecfg */
954modecfg_statement
955	:	MODECFG BOC modecfg_stmts EOC
956	;
957modecfg_stmts
958	:	/* nothing */
959	|	modecfg_stmts modecfg_stmt
960	;
961modecfg_stmt
962	:	CFG_NET4 ADDRSTRING
963		{
964#ifdef ENABLE_HYBRID
965			if (inet_pton(AF_INET, $2->v,
966			     &isakmp_cfg_config.network4) != 1)
967				yyerror("bad IPv4 network address.");
968#else
969			yywarn(error_message_hybrid_config_not_configured);
970#endif
971			vfree($2);
972		}
973		EOS
974	|	CFG_MASK4 ADDRSTRING
975		{
976#ifdef ENABLE_HYBRID
977			if (inet_pton(AF_INET, $2->v,
978			    &isakmp_cfg_config.netmask4) != 1)
979				yyerror("bad IPv4 netmask address.");
980#else
981			yywarn(error_message_hybrid_config_not_configured);
982#endif
983			vfree($2);
984		}
985		EOS
986	|	CFG_DNS4 addrdnslist
987		EOS
988	|	CFG_NBNS4 addrwinslist
989		EOS
990	|	CFG_SPLIT_NETWORK CFG_SPLIT_LOCAL splitnetlist
991		{
992#ifdef ENABLE_HYBRID
993			isakmp_cfg_config.splitnet_type = UNITY_LOCAL_LAN;
994#else
995			yywarn(error_message_hybrid_config_not_configured);
996#endif
997		}
998		EOS
999	|	CFG_SPLIT_NETWORK CFG_SPLIT_INCLUDE splitnetlist
1000		{
1001#ifdef ENABLE_HYBRID
1002			isakmp_cfg_config.splitnet_type = UNITY_SPLIT_INCLUDE;
1003#else
1004			yywarn(error_message_hybrid_config_not_configured);
1005#endif
1006		}
1007		EOS
1008	|	CFG_SPLIT_DNS splitdnslist
1009		{
1010#ifndef ENABLE_HYBRID
1011			yywarn(error_message_hybrid_config_not_configured);
1012#endif
1013		}
1014		EOS
1015	|	CFG_DEFAULT_DOMAIN QUOTEDSTRING
1016		{
1017#ifdef ENABLE_HYBRID
1018			strncpy(&isakmp_cfg_config.default_domain[0],
1019			    $2->v, MAXPATHLEN);
1020			isakmp_cfg_config.default_domain[MAXPATHLEN] = '\0';
1021#else
1022			yyerror(error_message_hybrid_config_not_configured);
1023#endif
1024			vfree($2);
1025		}
1026		EOS
1027	|	CFG_AUTH_SOURCE CFG_SYSTEM
1028		{
1029#ifdef ENABLE_HYBRID
1030			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
1031#else
1032			yywarn(error_message_hybrid_config_not_configured);
1033#endif
1034		}
1035		EOS
1036	|	CFG_AUTH_SOURCE CFG_RADIUS
1037		{
1038#ifdef ENABLE_HYBRID
1039#ifdef HAVE_LIBRADIUS
1040			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_RADIUS;
1041#else /* HAVE_LIBRADIUS */
1042			yyerror("racoon not configured with --with-libradius");
1043#endif /* HAVE_LIBRADIUS */
1044#else /* ENABLE_HYBRID */
1045			yywarn(error_message_hybrid_config_not_configured);
1046#endif /* ENABLE_HYBRID */
1047		}
1048		EOS
1049	|	CFG_AUTH_SOURCE CFG_PAM
1050		{
1051#ifdef ENABLE_HYBRID
1052#ifdef HAVE_LIBPAM
1053			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_PAM;
1054#else /* HAVE_LIBPAM */
1055			yyerror("racoon not configured with --with-libpam");
1056#endif /* HAVE_LIBPAM */
1057#else /* ENABLE_HYBRID */
1058			yywarn(error_message_hybrid_config_not_configured);
1059#endif /* ENABLE_HYBRID */
1060		}
1061		EOS
1062	|	CFG_AUTH_SOURCE CFG_LDAP
1063		{
1064#ifdef ENABLE_HYBRID
1065#ifdef HAVE_LIBLDAP
1066			isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_LDAP;
1067#else /* HAVE_LIBLDAP */
1068			yywarn(error_message_ldap_config_not_configured);
1069#endif /* HAVE_LIBLDAP */
1070#else /* ENABLE_HYBRID */
1071			yywarn(error_message_hybrid_config_not_configured);
1072#endif /* ENABLE_HYBRID */
1073		}
1074		EOS
1075	|	CFG_AUTH_GROUPS authgrouplist
1076		{
1077#ifndef ENABLE_HYBRID
1078			yywarn(error_message_hybrid_config_not_configured);
1079#endif
1080		}
1081		EOS
1082	|	CFG_GROUP_SOURCE CFG_SYSTEM
1083		{
1084#ifdef ENABLE_HYBRID
1085			isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
1086#else
1087			yywarn(error_message_hybrid_config_not_configured);
1088#endif
1089		}
1090		EOS
1091	|	CFG_GROUP_SOURCE CFG_LDAP
1092		{
1093#ifdef ENABLE_HYBRID
1094#ifdef HAVE_LIBLDAP
1095			isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_LDAP;
1096#else /* HAVE_LIBLDAP */
1097			yywarn(error_message_ldap_config_not_configured);
1098#endif /* HAVE_LIBLDAP */
1099#else /* ENABLE_HYBRID */
1100			yywarn(error_message_hybrid_config_not_configured);
1101#endif /* ENABLE_HYBRID */
1102		}
1103		EOS
1104	|	CFG_ACCOUNTING CFG_NONE
1105		{
1106#ifdef ENABLE_HYBRID
1107			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
1108#else
1109			yywarn(error_message_hybrid_config_not_configured);
1110#endif
1111		}
1112		EOS
1113	|	CFG_ACCOUNTING CFG_SYSTEM
1114		{
1115#ifdef ENABLE_HYBRID
1116			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_SYSTEM;
1117#else
1118			yywarn(error_message_hybrid_config_not_configured);
1119#endif
1120		}
1121		EOS
1122	|	CFG_ACCOUNTING CFG_RADIUS
1123		{
1124#ifdef ENABLE_HYBRID
1125#ifdef HAVE_LIBRADIUS
1126			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_RADIUS;
1127#else /* HAVE_LIBRADIUS */
1128			yyerror("racoon not configured with --with-libradius");
1129#endif /* HAVE_LIBRADIUS */
1130#else /* ENABLE_HYBRID */
1131			yywarn(error_message_hybrid_config_not_configured);
1132#endif /* ENABLE_HYBRID */
1133		}
1134		EOS
1135	|	CFG_ACCOUNTING CFG_PAM
1136		{
1137#ifdef ENABLE_HYBRID
1138#ifdef HAVE_LIBPAM
1139			isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_PAM;
1140#else /* HAVE_LIBPAM */
1141			yyerror("racoon not configured with --with-libpam");
1142#endif /* HAVE_LIBPAM */
1143#else /* ENABLE_HYBRID */
1144			yywarn(error_message_hybrid_config_not_configured);
1145#endif /* ENABLE_HYBRID */
1146		}
1147		EOS
1148	|	CFG_POOL_SIZE NUMBER
1149		{
1150#ifdef ENABLE_HYBRID
1151			if (isakmp_cfg_resize_pool($2) != 0)
1152				yyerror("cannot allocate memory for pool");
1153#else /* ENABLE_HYBRID */
1154			yywarn(error_message_hybrid_config_not_configured);
1155#endif /* ENABLE_HYBRID */
1156		}
1157		EOS
1158	|	CFG_PFS_GROUP NUMBER
1159		{
1160#ifdef ENABLE_HYBRID
1161			isakmp_cfg_config.pfs_group = $2;
1162#else /* ENABLE_HYBRID */
1163			yywarn(error_message_hybrid_config_not_configured);
1164#endif /* ENABLE_HYBRID */
1165		}
1166		EOS
1167	|	CFG_SAVE_PASSWD SWITCH
1168		{
1169#ifdef ENABLE_HYBRID
1170			isakmp_cfg_config.save_passwd = $2;
1171#else /* ENABLE_HYBRID */
1172			yywarn(error_message_hybrid_config_not_configured);
1173#endif /* ENABLE_HYBRID */
1174		}
1175		EOS
1176	|	CFG_AUTH_THROTTLE NUMBER
1177		{
1178#ifdef ENABLE_HYBRID
1179			isakmp_cfg_config.auth_throttle = $2;
1180#else /* ENABLE_HYBRID */
1181			yywarn(error_message_hybrid_config_not_configured);
1182#endif /* ENABLE_HYBRID */
1183		}
1184		EOS
1185	|	CFG_CONF_SOURCE CFG_LOCAL
1186		{
1187#ifdef ENABLE_HYBRID
1188			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
1189#else /* ENABLE_HYBRID */
1190			yywarn(error_message_hybrid_config_not_configured);
1191#endif /* ENABLE_HYBRID */
1192		}
1193		EOS
1194	|	CFG_CONF_SOURCE CFG_RADIUS
1195		{
1196#ifdef ENABLE_HYBRID
1197#ifdef HAVE_LIBRADIUS
1198			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_RADIUS;
1199#else /* HAVE_LIBRADIUS */
1200			yyerror("racoon not configured with --with-libradius");
1201#endif /* HAVE_LIBRADIUS */
1202#else /* ENABLE_HYBRID */
1203			yywarn(error_message_hybrid_config_not_configured);
1204#endif /* ENABLE_HYBRID */
1205		}
1206		EOS
1207	|	CFG_CONF_SOURCE CFG_LDAP
1208		{
1209#ifdef ENABLE_HYBRID
1210#ifdef HAVE_LIBLDAP
1211			isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LDAP;
1212#else /* HAVE_LIBLDAP */
1213			yywarn(error_message_ldap_config_not_configured);
1214#endif /* HAVE_LIBLDAP */
1215#else /* ENABLE_HYBRID */
1216			yywarn(error_message_hybrid_config_not_configured);
1217#endif /* ENABLE_HYBRID */
1218		}
1219		EOS
1220	|	CFG_MOTD QUOTEDSTRING
1221		{
1222#ifdef ENABLE_HYBRID
1223			strncpy(&isakmp_cfg_config.motd[0], $2->v, MAXPATHLEN);
1224			isakmp_cfg_config.motd[MAXPATHLEN] = '\0';
1225#else
1226			yywarn(error_message_hybrid_config_not_configured);
1227#endif
1228			vfree($2);
1229		}
1230		EOS
1231	;
1232
1233addrdnslist
1234	:	addrdns
1235	|	addrdns COMMA addrdnslist
1236	;
1237addrdns
1238	:	ADDRSTRING
1239		{
1240#ifdef ENABLE_HYBRID
1241			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
1242
1243			if (icc->dns4_index > MAXNS)
1244				yyerror("No more than %d DNS", MAXNS);
1245			if (inet_pton(AF_INET, $1->v,
1246			    &icc->dns4[icc->dns4_index++]) != 1)
1247				yyerror("bad IPv4 DNS address.");
1248#else
1249			yywarn(error_message_hybrid_config_not_configured);
1250#endif
1251			vfree($1);
1252		}
1253	;
1254
1255addrwinslist
1256	:	addrwins
1257	|	addrwins COMMA addrwinslist
1258	;
1259addrwins
1260	:	ADDRSTRING
1261		{
1262#ifdef ENABLE_HYBRID
1263			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
1264
1265			if (icc->nbns4_index > MAXWINS)
1266				yyerror("No more than %d WINS", MAXWINS);
1267			if (inet_pton(AF_INET, $1->v,
1268			    &icc->nbns4[icc->nbns4_index++]) != 1)
1269				yyerror("bad IPv4 WINS address.");
1270#else
1271			yywarn(error_message_hybrid_config_not_configured);
1272#endif
1273			vfree($1);
1274		}
1275	;
1276
1277splitnetlist
1278	:	splitnet
1279	|	splitnetlist COMMA splitnet
1280	;
1281splitnet
1282	:	ADDRSTRING PREFIX
1283		{
1284#ifdef ENABLE_HYBRID
1285			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
1286			struct unity_network network;
1287			memset(&network,0,sizeof(network));
1288
1289			if (inet_pton(AF_INET, $1->v, &network.addr4) != 1)
1290				yyerror("bad IPv4 SPLIT address.");
1291
1292			/* Turn $2 (the prefix) into a subnet mask */
1293			network.mask4.s_addr = ($2) ? htonl(~((1 << (32 - $2)) - 1)) : 0;
1294
1295			/* add the network to our list */
1296			if (splitnet_list_add(&icc->splitnet_list, &network,&icc->splitnet_count))
1297				yyerror("Unable to allocate split network");
1298#else
1299			yywarn(error_message_hybrid_config_not_configured);
1300#endif
1301			vfree($1);
1302		}
1303	;
1304
1305authgrouplist
1306	:	authgroup
1307	|	authgroup COMMA authgrouplist
1308	;
1309authgroup
1310	:	QUOTEDSTRING
1311		{
1312#ifdef ENABLE_HYBRID
1313			char * groupname = NULL;
1314			char ** grouplist = NULL;
1315			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
1316
1317			grouplist = racoon_realloc(icc->grouplist,
1318					sizeof(char**)*(icc->groupcount+1));
1319			if (grouplist == NULL) {
1320				yyerror("unable to allocate auth group list");
1321				ABORT_AND_VFREE($1);
1322			}
1323
1324
1325			groupname = racoon_malloc($1->l+1);
1326			if (groupname == NULL) {
1327				yyerror("unable to allocate auth group name");
1328				ABORT_AND_VFREE($1);
1329			}
1330
1331			memcpy(groupname,$1->v,$1->l);
1332			groupname[$1->l]=0;
1333			grouplist[icc->groupcount]=groupname;
1334			icc->grouplist = grouplist;
1335			icc->groupcount++;
1336
1337#else
1338			yywarn(error_message_hybrid_config_not_configured);
1339#endif
1340			vfree($1);
1341		}
1342	;
1343
1344splitdnslist
1345	:	splitdns
1346	|	splitdns COMMA splitdnslist
1347	;
1348splitdns
1349	:	QUOTEDSTRING
1350		{
1351#ifdef ENABLE_HYBRID
1352			struct isakmp_cfg_config *icc = &isakmp_cfg_config;
1353
1354			if (!icc->splitdns_len)
1355			{
1356				icc->splitdns_list = racoon_malloc($1->l);
1357				if (icc->splitdns_list == NULL) {
1358					yyerror("error allocating splitdns list buffer");
1359					ABORT_AND_VFREE($1);
1360				}
1361
1362				memcpy(icc->splitdns_list,$1->v,$1->l);
1363				icc->splitdns_len = $1->l;
1364			}
1365			else
1366			{
1367				int len = icc->splitdns_len + $1->l + 1;
1368				icc->splitdns_list = racoon_realloc(icc->splitdns_list,len);
1369				if (icc->splitdns_list == NULL) {
1370					yyerror("error allocating splitdns list buffer");
1371					ABORT_AND_VFREE($1);
1372				}
1373
1374				icc->splitdns_list[icc->splitdns_len] = ',';
1375				memcpy(icc->splitdns_list + icc->splitdns_len + 1, $1->v, $1->l);
1376				icc->splitdns_len = len;
1377			}
1378#else
1379			yywarn(error_message_hybrid_config_not_configured);
1380#endif
1381			vfree($1);
1382		}
1383	;
1384
1385
1386	/* timer */
1387timer_statement
1388	:	RETRY BOC timer_stmts EOC
1389	;
1390timer_stmts
1391	:	/* nothing */
1392	|	timer_stmts timer_stmt
1393	;
1394timer_stmt
1395	:	RETRY_COUNTER NUMBER
1396		{
1397			lcconf->retry_counter = $2;
1398		}
1399		EOS
1400	|	RETRY_INTERVAL NUMBER unittype_time
1401		{
1402			lcconf->retry_interval = $2 * $3;
1403		}
1404		EOS
1405	|	RETRY_PERSEND NUMBER
1406		{
1407			lcconf->count_persend = $2;
1408		}
1409		EOS
1410	|	RETRY_PHASE1 NUMBER unittype_time
1411		{
1412			lcconf->retry_checkph1 = $2 * $3;
1413		}
1414		EOS
1415	|	RETRY_PHASE2 NUMBER unittype_time
1416		{
1417			lcconf->wait_ph2complete = $2 * $3;
1418		}
1419		EOS
1420	|	NATT_KA NUMBER unittype_time
1421		{
1422#ifdef ENABLE_NATT
1423			if (libipsec_opt & LIBIPSEC_OPT_NATT)
1424				lcconf->natt_ka_interval = $2 * $3;
1425			else
1426				yyerror("libipsec lacks NAT-T support");
1427#else
1428			yyerror(error_message_natt_not_compiled_in);
1429#endif
1430		}
1431		EOS
1432	;
1433
1434	/* sainfo */
1435sainfo_statement
1436	:	SAINFO
1437		{
1438			delsainfo(cur_sainfo);
1439			cur_sainfo = newsainfo();
1440			if (cur_sainfo == NULL) {
1441				yyerror("failed to allocate sainfo");
1442				ABORT();
1443			}
1444
1445		}
1446		sainfo_name sainfo_param BOC sainfo_specs
1447		{
1448			struct sainfo *check;
1449
1450			/* default */
1451			if (cur_sainfo->algs[algclass_ipsec_enc] == 0) {
1452				yyerror("no encryption algorithm at %s",
1453					sainfo2str(cur_sainfo));
1454				return -1;
1455			}
1456			if (cur_sainfo->algs[algclass_ipsec_auth] == 0) {
1457				yyerror("no authentication algorithm at %s",
1458					sainfo2str(cur_sainfo));
1459				return -1;
1460			}
1461			if (cur_sainfo->algs[algclass_ipsec_comp] == 0) {
1462				yyerror("no compression algorithm at %s",
1463					sainfo2str(cur_sainfo));
1464				return -1;
1465			}
1466
1467			/* duplicate check */
1468			check = getsainfo(cur_sainfo->idsrc,
1469					  cur_sainfo->iddst,
1470					  cur_sainfo->id_i,
1471					  NULL,
1472					  cur_sainfo->remoteid);
1473
1474			if (check && ((check->idsrc != SAINFO_ANONYMOUS) &&
1475				      (cur_sainfo->idsrc != SAINFO_ANONYMOUS))) {
1476				yyerror("duplicated sainfo: %s",
1477					sainfo2str(cur_sainfo));
1478				return -1;
1479			}
1480
1481			inssainfo(cur_sainfo);
1482			cur_sainfo = NULL;
1483		}
1484		EOC
1485	;
1486sainfo_name
1487	:	ANONYMOUS
1488		{
1489			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
1490			cur_sainfo->iddst = SAINFO_ANONYMOUS;
1491		}
1492	|	ANONYMOUS CLIENTADDR
1493		{
1494			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
1495			cur_sainfo->iddst = SAINFO_CLIENTADDR;
1496		}
1497	|	ANONYMOUS sainfo_id
1498		{
1499			cur_sainfo->idsrc = SAINFO_ANONYMOUS;
1500			cur_sainfo->iddst = $2;
1501		}
1502	|	sainfo_id ANONYMOUS
1503		{
1504			cur_sainfo->idsrc = $1;
1505			cur_sainfo->iddst = SAINFO_ANONYMOUS;
1506		}
1507	|	sainfo_id CLIENTADDR
1508		{
1509			cur_sainfo->idsrc = $1;
1510			cur_sainfo->iddst = SAINFO_CLIENTADDR;
1511		}
1512	|	sainfo_id sainfo_id
1513		{
1514			cur_sainfo->idsrc = $1;
1515			cur_sainfo->iddst = $2;
1516		}
1517	;
1518sainfo_id
1519	:	IDENTIFIERTYPE ADDRSTRING prefix port ul_proto
1520		{
1521			char portbuf[10];
1522			struct sockaddr *saddr;
1523
1524			switch ($5) {
1525			case IPPROTO_ICMP:
1526			case IPPROTO_ICMPV6:
1527				if ($4 == IPSEC_PORT_ANY)
1528					break;
1529				yyerror("port must be \"any\" for icmp{,6}.");
1530				return -1;
1531			default:
1532				break;
1533			}
1534
1535			snprintf(portbuf, sizeof(portbuf), "%lu", $4);
1536			saddr = str2saddr($2->v, portbuf);
1537			vfree($2);
1538			if (saddr == NULL)
1539				return -1;
1540
1541			switch (saddr->sa_family) {
1542			case AF_INET:
1543				if ($5 == IPPROTO_ICMPV6) {
1544					yyerror("upper layer protocol mismatched.\n");
1545					racoon_free(saddr);
1546					return -1;
1547				}
1548				$$ = ipsecdoi_sockaddr2id(saddr,
1549										  $3 == ~0 ? (sizeof(struct in_addr) << 3): $3,
1550										  $5);
1551				break;
1552#ifdef INET6
1553			case AF_INET6:
1554				if ($5 == IPPROTO_ICMP) {
1555					yyerror("upper layer protocol mismatched.\n");
1556					racoon_free(saddr);
1557					return -1;
1558				}
1559				$$ = ipsecdoi_sockaddr2id(saddr,
1560										  $3 == ~0 ? (sizeof(struct in6_addr) << 3): $3,
1561										  $5);
1562				break;
1563#endif
1564			default:
1565				yyerror("invalid family: %d", saddr->sa_family);
1566				$$ = NULL;
1567				break;
1568			}
1569			racoon_free(saddr);
1570			if ($$ == NULL)
1571				return -1;
1572		}
1573	|	IDENTIFIERTYPE ADDRSTRING ADDRRANGE prefix port ul_proto
1574		{
1575			char portbuf[10];
1576			struct sockaddr *laddr = NULL, *haddr = NULL;
1577
1578			if (($6 == IPPROTO_ICMP || $6 == IPPROTO_ICMPV6)
1579			 && ($5 != IPSEC_PORT_ANY || $5 != IPSEC_PORT_ANY)) {
1580				yyerror("port number must be \"any\".");
1581				return -1;
1582			}
1583
1584			snprintf(portbuf, sizeof(portbuf), "%lu", $5);
1585
1586			laddr = str2saddr($2->v, portbuf);
1587			if (laddr == NULL) {
1588			    return -1;
1589			}
1590			vfree($2);
1591			haddr = str2saddr($3->v, portbuf);
1592			if (haddr == NULL) {
1593			    racoon_free(laddr);
1594			    return -1;
1595			}
1596			vfree($3);
1597
1598			switch (laddr->sa_family) {
1599			case AF_INET:
1600				if ($6 == IPPROTO_ICMPV6) {
1601				    yyerror("upper layer protocol mismatched.\n");
1602				    if (laddr)
1603					racoon_free(laddr);
1604				    if (haddr)
1605					racoon_free(haddr);
1606				    return -1;
1607				}
1608                                $$ = ipsecdoi_sockrange2id(laddr, haddr,
1609							   $6);
1610				break;
1611#ifdef INET6
1612			case AF_INET6:
1613				if ($6 == IPPROTO_ICMP) {
1614					yyerror("upper layer protocol mismatched.\n");
1615					if (laddr)
1616					    racoon_free(laddr);
1617					if (haddr)
1618					    racoon_free(haddr);
1619					return -1;
1620				}
1621				$$ = ipsecdoi_sockrange2id(laddr, haddr,
1622							       $6);
1623				break;
1624#endif
1625			default:
1626				yyerror("invalid family: %d", laddr->sa_family);
1627				$$ = NULL;
1628				break;
1629			}
1630			if (laddr)
1631			    racoon_free(laddr);
1632			if (haddr)
1633			    racoon_free(haddr);
1634			if ($$ == NULL)
1635				return -1;
1636		}
1637	|	IDENTIFIERTYPE QUOTEDSTRING
1638		{
1639			struct ipsecdoi_id_b *id_b;
1640
1641			if ($1 == IDTYPE_ASN1DN) {
1642				yyerror("id type forbidden: %d", $1);
1643				$$ = NULL;
1644				return -1;
1645			}
1646
1647			$2->l--;
1648
1649			$$ = vmalloc(sizeof(*id_b) + $2->l);
1650			if ($$ == NULL) {
1651				yyerror("failed to allocate identifier");
1652				return -1;
1653			}
1654
1655			id_b = (struct ipsecdoi_id_b *)$$->v;
1656			id_b->type = idtype2doi($1);
1657
1658			id_b->proto_id = 0;
1659			id_b->port = 0;
1660
1661			memcpy($$->v + sizeof(*id_b), $2->v, $2->l);
1662		}
1663	;
1664sainfo_param
1665	:	/* nothing */
1666		{
1667			cur_sainfo->id_i = NULL;
1668		}
1669	|	FROM IDENTIFIERTYPE identifierstring
1670		{
1671			struct ipsecdoi_id_b *id_b;
1672			vchar_t *idv;
1673
1674			if (set_identifier(&idv, $2, $3) != 0) {
1675				yyerror("failed to set identifer.\n");
1676				return -1;
1677			}
1678			cur_sainfo->id_i = vmalloc(sizeof(*id_b) + idv->l);
1679			if (cur_sainfo->id_i == NULL) {
1680				yyerror("failed to allocate identifier");
1681				return -1;
1682			}
1683
1684			id_b = (struct ipsecdoi_id_b *)cur_sainfo->id_i->v;
1685			id_b->type = idtype2doi($2);
1686
1687			id_b->proto_id = 0;
1688			id_b->port = 0;
1689
1690			memcpy(cur_sainfo->id_i->v + sizeof(*id_b),
1691			       idv->v, idv->l);
1692			vfree(idv);
1693		}
1694	|	GROUP QUOTEDSTRING
1695		{
1696#ifdef ENABLE_HYBRID
1697			if ((cur_sainfo->group = vdup($2)) == NULL) {
1698				yyerror("failed to set sainfo xauth group.\n");
1699				return -1;
1700			}
1701#else
1702			yywarn(error_message_hybrid_config_not_configured);
1703			ABORT_AND_VFREE($2);
1704#endif
1705 		}
1706	;
1707sainfo_specs
1708	:	/* nothing */
1709	|	sainfo_specs sainfo_spec
1710	;
1711sainfo_spec
1712	:	PFS_GROUP dh_group_num
1713		{
1714			cur_sainfo->pfs_group = $2;
1715		}
1716		EOS
1717	|	REMOTEID NUMBER
1718		{
1719			cur_sainfo->remoteid = $2;
1720		}
1721		EOS
1722	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
1723		{
1724			cur_sainfo->lifetime = $3 * $4;
1725		}
1726		EOS
1727	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
1728		{
1729#if 1
1730			yyerror("byte lifetime support is deprecated");
1731			ABORT();
1732#else
1733			cur_sainfo->lifebyte = fix_lifebyte($3 * $4);
1734			if (cur_sainfo->lifebyte == 0)
1735				ABORT();
1736#endif
1737		}
1738		EOS
1739	|	ALGORITHM_CLASS {
1740			cur_algclass = $1;
1741		}
1742		algorithms EOS
1743	;
1744
1745algorithms
1746	:	algorithm
1747		{
1748			inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
1749		}
1750	|	algorithm
1751		{
1752			inssainfoalg(&cur_sainfo->algs[cur_algclass], $1);
1753		}
1754		COMMA algorithms
1755	;
1756algorithm
1757	:	ALGORITHMTYPE keylength
1758		{
1759			int defklen;
1760			int encklen_tmp;
1761
1762			$$ = newsainfoalg();
1763			if ($$ == NULL) {
1764				yyerror("failed to get algorithm allocation");
1765				ABORT();
1766			}
1767
1768			$$->alg = algtype2doi(cur_algclass, $1);
1769			if ($$->alg == -1) {
1770				yyerror("algorithm mismatched");
1771				ABORT_AND_RACOON_FREE($$);
1772			}
1773
1774			defklen = default_keylen(cur_algclass, $1);
1775			if (defklen == 0) {
1776				if ($2) {
1777					yyerror("keylen not allowed");
1778					ABORT_AND_RACOON_FREE($$);
1779				}
1780
1781			} else {
1782				if ($2 && check_keylen(cur_algclass, $1, $2) < 0) {
1783					yyerror("invalid keylen %d", $2);
1784					ABORT_AND_RACOON_FREE($$);
1785				}
1786			}
1787
1788			if ($2)
1789				$$->encklen = $2;
1790			else
1791				$$->encklen = defklen;
1792
1793			/* Check keymat size instead of "human" key size
1794			 * because kernel store keymat size instead of "human key size".
1795			 * For example, the keymat size of aes_gcm_16 128 is 160 bits
1796			 * (128 bits + 4 bytes) instead of 128 bits.
1797			 *
1798			 * Currently, it is only useful for aes_gcm_16 (ipsec_enc).
1799			 */
1800			if (cur_algclass == algclass_ipsec_enc)
1801			{
1802				encklen_tmp = alg_ipsec_encdef_keylen($$->alg, $$->encklen);
1803				if (encklen_tmp < 0)
1804				{
1805					yyerror("Failed to convert keylen %d to keymat len for alg %d",
1806						$$->encklen, $$->alg);
1807					racoon_free($$);
1808					$$ = NULL;
1809					return -1;
1810				}
1811			}
1812			else
1813			{
1814				/* XXX Convert key size to keymat size for other algorithm ?
1815				 */
1816				encklen_tmp = $$->encklen;
1817			}
1818
1819			/* check if it's supported algorithm by kernel */
1820			if (!(cur_algclass == algclass_ipsec_auth && $1 == algtype_non_auth)
1821			 && pk_checkalg(cur_algclass, $1, encklen_tmp)) {
1822				int a = algclass2doi(cur_algclass);
1823				int b = algtype2doi(cur_algclass, $1);
1824				if (a == IPSECDOI_ATTR_AUTH)
1825					a = IPSECDOI_PROTO_IPSEC_AH;
1826				yyerror("algorithm %s not supported by the kernel (missing module?)",
1827					s_ipsecdoi_trns(a, b));
1828				ABORT_AND_RACOON_FREE($$);
1829			}
1830		}
1831	;
1832prefix
1833	:	/* nothing */ { $$ = ~0; }
1834	|	PREFIX { $$ = $1; }
1835	;
1836port
1837	:	/* nothing */ { $$ = IPSEC_PORT_ANY; }
1838	|	PORT { $$ = $1; }
1839	|	PORTANY { $$ = IPSEC_PORT_ANY; }
1840	;
1841ul_proto
1842	:	NUMBER { $$ = $1; }
1843	|	UL_PROTO { $$ = $1; }
1844	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
1845	;
1846keylength
1847	:	/* nothing */ { $$ = 0; }
1848	|	NUMBER { $$ = $1; }
1849	;
1850
1851	/* remote */
1852remote_statement
1853	: REMOTE QUOTEDSTRING INHERIT QUOTEDSTRING
1854		{
1855			struct remoteconf *from, *new;
1856
1857			if (getrmconf_by_name($2->v) != NULL) {
1858				yyerror("named remoteconf \"%s\" already exists.",
1859					$2->v);
1860				ABORT_AND_VFREE2($2, $4);
1861			}
1862
1863			from = getrmconf_by_name($4->v);
1864			if (from == NULL) {
1865				yyerror("named parent remoteconf \"%s\" does not exist.",
1866					$4->v);
1867				ABORT_AND_VFREE2($2, $4);
1868			}
1869
1870			new = duprmconf_shallow(from);
1871			if (new == NULL) {
1872				yyerror("failed to duplicate remoteconf from \"%s\".",
1873					$4->v);
1874				ABORT_AND_VFREE2($2, $4);
1875			}
1876
1877			new->name = racoon_strdup($2->v);
1878
1879			delrmconf(cur_rmconf);
1880			cur_rmconf = new;
1881
1882			vfree($2);
1883			vfree($4);
1884		}
1885		remote_specs_inherit_block
1886	| REMOTE QUOTEDSTRING
1887		{
1888			struct remoteconf *new;
1889
1890			if (getrmconf_by_name($2->v) != NULL) {
1891				yyerror("Named remoteconf \"%s\" already exists.",
1892					$2->v);
1893				ABORT_AND_VFREE($2);
1894			}
1895
1896			new = newrmconf();
1897			if (new == NULL) {
1898				yyerror("failed to get new remoteconf.");
1899				ABORT_AND_VFREE($2);
1900			}
1901
1902			new->name = racoon_strdup($2->v);
1903
1904			delrmconf(cur_rmconf);
1905			cur_rmconf = new;
1906
1907			vfree($2);
1908		}
1909		remote_specs_block
1910	| REMOTE remote_index INHERIT remote_index
1911		{
1912			struct remoteconf *from, *new;
1913
1914			from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS);
1915			if (from == NULL) {
1916				yyerror("failed to get remoteconf for %s.",
1917					saddr2str($4));
1918				ABORT_AND_RACOON_FREE2($2, $4);
1919			}
1920
1921			new = duprmconf_shallow(from);
1922			if (new == NULL) {
1923				yyerror("failed to duplicate remoteconf from %s.",
1924					saddr2str($4));
1925				ABORT_AND_RACOON_FREE2($2, $4);
1926			}
1927
1928			racoon_free($4);
1929			new->remote = $2;
1930			delrmconf(cur_rmconf);
1931			cur_rmconf = new;
1932		}
1933		remote_specs_inherit_block
1934	|	REMOTE remote_index
1935		{
1936			struct remoteconf *new;
1937
1938			new = newrmconf();
1939			if (new == NULL) {
1940				yyerror("failed to get new remoteconf.");
1941				ABORT_AND_RACOON_FREE($2);
1942			}
1943
1944			new->remote = $2;
1945			delrmconf(cur_rmconf);
1946			cur_rmconf = new;
1947		}
1948		remote_specs_block
1949	;
1950
1951remote_specs_inherit_block
1952	:	remote_specs_block
1953	|	EOS /* inheritance without overriding any settings */
1954		{
1955			if (process_rmconf() != 0)
1956				ABORT();
1957		}
1958	;
1959
1960remote_specs_block
1961	:	BOC remote_specs EOC
1962		{
1963			if (process_rmconf() != 0)
1964				ABORT();
1965		}
1966	;
1967
1968remote_index
1969	:	ANONYMOUS ike_port
1970		{
1971			$$ = newsaddr(sizeof(struct sockaddr));
1972			$$->sa_family = AF_UNSPEC;
1973			((struct sockaddr_in *)$$)->sin_port = htons($2);
1974		}
1975	|	ike_addrinfo_port
1976		{
1977			$$ = $1;
1978			if ($$ == NULL) {
1979				yyerror("failed to allocate sockaddr\n");
1980				ABORT();
1981			}
1982		}
1983	;
1984remote_specs
1985	:	/* nothing */
1986	|	remote_specs remote_spec
1987	;
1988remote_spec
1989	:	REMOTE_ADDRESS ike_addrinfo_port
1990		{
1991			if (cur_rmconf->remote != NULL) {
1992				yyerror("remote_address already specified\n");
1993				ABORT_AND_RACOON_FREE($2);
1994			}
1995
1996			cur_rmconf->remote = $2;
1997		}
1998		EOS
1999	|	EXCHANGE_MODE
2000		{
2001			cur_rmconf->etypes = NULL;
2002		}
2003		exchange_types EOS
2004	|	DOI DOITYPE { cur_rmconf->doitype = $2; } EOS
2005	|	SITUATION SITUATIONTYPE { cur_rmconf->sittype = $2; } EOS
2006	|	CERTIFICATE_TYPE cert_spec
2007	|	PEERS_CERTFILE QUOTEDSTRING
2008		{
2009			yywarn("This directive without certtype will be removed!\n");
2010			yywarn("Please use 'peers_certfile x509 \"%s\";' instead\n", $2->v);
2011
2012			if (cur_rmconf->peerscert != NULL) {
2013				yyerror("peers_certfile already defined\n");
2014				ABORT_AND_VFREE($2);
2015			}
2016
2017			if (load_x509($2->v, &cur_rmconf->peerscertfile,
2018					&cur_rmconf->peerscert)) {
2019				yyerror("failed to load certificate \"%s\"\n",
2020					$2->v);
2021				ABORT_AND_VFREE($2);
2022			}
2023
2024			vfree($2);
2025		}
2026		EOS
2027	|	PEERS_CERTFILE CERT_X509 QUOTEDSTRING
2028		{
2029			if (cur_rmconf->peerscert != NULL) {
2030				yyerror("peers_certfile already defined\n");
2031				ABORT_AND_VFREE($3);
2032			}
2033
2034			if (load_x509($3->v, &cur_rmconf->peerscertfile,
2035					&cur_rmconf->peerscert)) {
2036				yyerror("failed to load certificate \"%s\"\n",
2037					$3->v);
2038				ABORT_AND_VFREE($3);
2039			}
2040			vfree($3);
2041		}
2042		EOS
2043	|	PEERS_CERTFILE CERT_PLAINRSA QUOTEDSTRING
2044		{
2045			char path[MAXPATHLEN];
2046
2047			if (cur_rmconf->peerscert != NULL) {
2048				yyerror("peers_certfile already defined\n");
2049				ABORT_AND_VFREE($3);
2050			}
2051
2052			cur_rmconf->peerscert = vmalloc(1);
2053			if (cur_rmconf->peerscert == NULL) {
2054				yyerror("failed to allocate peerscert\n");
2055				ABORT_AND_VFREE($3);
2056			}
2057
2058			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_PLAINRSA;
2059
2060			getpathname(path, sizeof(path),
2061				    LC_PATHTYPE_CERT, $3->v);
2062			if (rsa_parse_file(cur_rmconf->rsa_public, path,
2063					RSA_TYPE_PUBLIC)) {
2064				yyerror("Couldn't parse keyfile.\n", path);
2065				ABORT_AND_VFREE2(cur_rmconf->peerscert, $3);
2066			}
2067
2068			plog(LLV_DEBUG, LOCATION, NULL,
2069			     "Public PlainRSA keyfile parsed: %s\n", path);
2070
2071			vfree($3);
2072		}
2073		EOS
2074	|	PEERS_CERTFILE DNSSEC
2075		{
2076			if (cur_rmconf->peerscert != NULL) {
2077				yyerror("peers_certfile already defined\n");
2078				ABORT();
2079			}
2080
2081			cur_rmconf->peerscert = vmalloc(1);
2082			if (cur_rmconf->peerscert == NULL) {
2083				yyerror("failed to allocate peerscert\n");
2084				ABORT();
2085			}
2086
2087			cur_rmconf->peerscert->v[0] = ISAKMP_CERT_DNS;
2088		}
2089		EOS
2090	|	CA_TYPE CERT_X509 QUOTEDSTRING
2091		{
2092			if (cur_rmconf->cacert != NULL) {
2093				yyerror("ca_type already defined\n");
2094				ABORT_AND_VFREE($3);
2095			}
2096
2097			if (load_x509($3->v, &cur_rmconf->cacertfile,
2098					&cur_rmconf->cacert)) {
2099				yyerror("failed to load certificate \"%s\"\n",
2100					$3->v);
2101				ABORT_AND_VFREE($3);
2102			}
2103
2104			vfree($3);
2105		}
2106		EOS
2107	|	VERIFY_CERT SWITCH { cur_rmconf->verify_cert = $2; } EOS
2108	|	SEND_CERT SWITCH { cur_rmconf->send_cert = $2; } EOS
2109	|	SEND_CR SWITCH { cur_rmconf->send_cr = $2; } EOS
2110	|	MATCH_EMPTY_CR SWITCH { cur_rmconf->match_empty_cr = $2; } EOS
2111	|	MY_IDENTIFIER IDENTIFIERTYPE identifierstring
2112		{
2113			if (set_identifier(&cur_rmconf->idv, $2, $3) != 0) {
2114				yyerror("failed to set identifer.\n");
2115				ABORT_AND_VFREE($3);
2116			}
2117
2118			cur_rmconf->idvtype = $2;
2119			vfree($3);
2120		}
2121		EOS
2122	|	MY_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
2123		{
2124			if (set_identifier_qual(&cur_rmconf->idv, $2, $4, $3) != 0) {
2125				yyerror("failed to set identifer.\n");
2126				ABORT_AND_VFREE($4);
2127			}
2128
2129			cur_rmconf->idvtype = $2;
2130			vfree($4);
2131		}
2132		EOS
2133	|	XAUTH_LOGIN identifierstring
2134		{
2135#ifdef ENABLE_HYBRID
2136			/* formerly identifier type login */
2137			if (xauth_rmconf_used(&cur_rmconf->xauth) == -1) {
2138				yyerror("failed to allocate xauth state\n");
2139				ABORT_AND_VFREE($2);
2140			}
2141
2142			if ((cur_rmconf->xauth->login = vdup($2)) == NULL) {
2143				yyerror("failed to set identifer\n");
2144				ABORT_AND_VFREE($2);
2145			}
2146
2147#else
2148			yywarn(error_message_hybrid_config_not_configured);
2149#endif
2150			vfree($2);
2151		}
2152		EOS
2153	|	PEERS_IDENTIFIER IDENTIFIERTYPE identifierstring
2154		{
2155			struct idspec  *idspec = NULL;
2156			vchar_t* id = NULL;
2157			if (set_identifier(&id, $2, $3) != 0) {
2158				yyerror("failed to set identifer\n");
2159				ABORT_AND_VFREE2(id, $3);
2160			}
2161
2162			if ((idspec = newidspec()) == NULL) {
2163				yyerror("failed to allocate idspec\n");
2164				ABORT_AND_VFREE2(id, $3);
2165			}
2166
2167			idspec->id = id; /* hand over id to idspec. */
2168			idspec->idtype = $2;
2169			genlist_append (cur_rmconf->idvl_p, idspec);
2170			vfree($3);
2171		}
2172		EOS
2173	|	PEERS_IDENTIFIER IDENTIFIERTYPE IDENTIFIERQUAL identifierstring
2174		{
2175			struct idspec *idspec = NULL;
2176			{
2177				vchar_t* id = NULL;
2178				if (set_identifier_qual(&id, $2, $4, $3) != 0) {
2179					yyerror("failed to set identifer\n");
2180					ABORT_AND_VFREE2(id, $4);
2181				}
2182
2183				if ((idspec = newidspec()) == NULL) {
2184					yyerror("failed to allocate idspec\n");
2185					ABORT_AND_VFREE2(id, $4);
2186				}
2187
2188				idspec->id = id; /* hand over id to idspec. */
2189			}
2190			idspec->idtype = $2;
2191			genlist_append (cur_rmconf->idvl_p, idspec);
2192
2193			vfree($4);
2194		}
2195		EOS
2196	|	VERIFY_IDENTIFIER SWITCH { cur_rmconf->verify_identifier = $2; } EOS
2197	|	NONCE_SIZE NUMBER { cur_rmconf->nonce_size = $2; } EOS
2198	|	DH_GROUP
2199		{
2200			yyerror("dh_group cannot be defined here\n");
2201			ABORT();
2202		}
2203		dh_group_num EOS
2204	|	PASSIVE SWITCH { cur_rmconf->passive = $2; } EOS
2205	|	IKE_FRAG SWITCH { cur_rmconf->ike_frag = $2; } EOS
2206	|	IKE_FRAG REMOTE_FORCE_LEVEL { cur_rmconf->ike_frag = ISAKMP_FRAG_FORCE; } EOS
2207	|	ESP_FRAG NUMBER {
2208#ifdef SADB_X_EXT_NAT_T_FRAG
2209        	if (libipsec_opt & LIBIPSEC_OPT_FRAG)
2210				cur_rmconf->esp_frag = $2;
2211			else
2212            	yywarn("libipsec lacks IKE frag support\n");
2213#else
2214			yywarn("Your kernel does not support esp_frag\n");
2215#endif
2216		} EOS
2217	|	SCRIPT QUOTEDSTRING PHASE1_UP {
2218			if (cur_rmconf->script[SCRIPT_PHASE1_UP] != NULL)
2219				vfree(cur_rmconf->script[SCRIPT_PHASE1_UP]);
2220
2221			cur_rmconf->script[SCRIPT_PHASE1_UP] =
2222			    script_path_add(vdup($2));
2223
2224			vfree($2);
2225		} EOS
2226	|	SCRIPT QUOTEDSTRING PHASE1_DOWN {
2227			if (cur_rmconf->script[SCRIPT_PHASE1_DOWN] != NULL)
2228				vfree(cur_rmconf->script[SCRIPT_PHASE1_DOWN]);
2229
2230			cur_rmconf->script[SCRIPT_PHASE1_DOWN] =
2231			    script_path_add(vdup($2));
2232
2233			vfree($2);
2234		} EOS
2235	|	SCRIPT QUOTEDSTRING PHASE1_DEAD {
2236			if (cur_rmconf->script[SCRIPT_PHASE1_DEAD] != NULL)
2237				vfree(cur_rmconf->script[SCRIPT_PHASE1_DEAD]);
2238
2239			cur_rmconf->script[SCRIPT_PHASE1_DEAD] =
2240			    script_path_add(vdup($2));
2241
2242			vfree($2);
2243		} EOS
2244	|	MODE_CFG SWITCH { cur_rmconf->mode_cfg = $2; } EOS
2245	|	WEAK_PHASE1_CHECK SWITCH {
2246			cur_rmconf->weak_phase1_check = $2;
2247		} EOS
2248	|	GENERATE_POLICY SWITCH { cur_rmconf->gen_policy = $2; } EOS
2249	|	GENERATE_POLICY GENERATE_LEVEL { cur_rmconf->gen_policy = $2; } EOS
2250	|	SUPPORT_PROXY SWITCH { cur_rmconf->support_proxy = $2; } EOS
2251	|	INITIAL_CONTACT SWITCH { cur_rmconf->ini_contact = $2; } EOS
2252	|	NAT_TRAVERSAL SWITCH
2253		{
2254#ifdef ENABLE_NATT
2255			if (libipsec_opt & LIBIPSEC_OPT_NATT)
2256				cur_rmconf->nat_traversal = $2;
2257			else
2258				yywarn("libipsec lacks NAT-T support\n");
2259#else
2260			yywarn(error_message_natt_not_compiled_in);
2261#endif
2262		} EOS
2263	|	NAT_TRAVERSAL REMOTE_FORCE_LEVEL
2264		{
2265#ifdef ENABLE_NATT
2266			if (libipsec_opt & LIBIPSEC_OPT_NATT)
2267				cur_rmconf->nat_traversal = NATT_FORCE;
2268			else
2269				yyerror("libipsec lacks NAT-T support");
2270#else
2271			yywarn(error_message_natt_not_compiled_in);
2272#endif
2273		} EOS
2274	|	DPD SWITCH
2275		{
2276#ifdef ENABLE_DPD
2277			cur_rmconf->dpd = $2;
2278#else
2279			yywarn(error_message_dpd_not_compiled_in);
2280#endif
2281		} EOS
2282	|	DPD_DELAY NUMBER
2283		{
2284#ifdef ENABLE_DPD
2285			cur_rmconf->dpd_interval = $2;
2286#else
2287			yywarn(error_message_dpd_not_compiled_in);
2288#endif
2289		}
2290		EOS
2291	|	DPD_RETRY NUMBER
2292		{
2293#ifdef ENABLE_DPD
2294			cur_rmconf->dpd_retry = $2;
2295#else
2296			yywarn(error_message_dpd_not_compiled_in);
2297#endif
2298		}
2299		EOS
2300	|	DPD_MAXFAIL NUMBER
2301		{
2302#ifdef ENABLE_DPD
2303			cur_rmconf->dpd_maxfails = $2;
2304#else
2305			yywarn(error_message_dpd_not_compiled_in);
2306#endif
2307		}
2308		EOS
2309	|	REKEY SWITCH { cur_rmconf->rekey = $2; } EOS
2310	|	REKEY REMOTE_FORCE_LEVEL { cur_rmconf->rekey = REKEY_FORCE; } EOS
2311	|	PH1ID NUMBER
2312		{
2313			cur_rmconf->ph1id = $2;
2314		}
2315		EOS
2316	|	LIFETIME LIFETYPE_TIME NUMBER unittype_time
2317		{
2318			cur_rmconf->lifetime = $3 * $4;
2319		}
2320		EOS
2321	|	PROPOSAL_CHECK PROPOSAL_CHECK_LEVEL { cur_rmconf->pcheck_level = $2; } EOS
2322	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
2323		{
2324#if 1
2325			yyerror("byte lifetime support is deprecated in Phase1");
2326			return -1;
2327#else
2328			yywarn("the lifetime of bytes in phase 1 "
2329				"will be ignored at the moment.");
2330			cur_rmconf->lifebyte = fix_lifebyte($3 * $4);
2331			if (cur_rmconf->lifebyte == 0)
2332				ABORT();
2333#endif
2334		}
2335		EOS
2336	|	PROPOSAL
2337		{
2338			struct secprotospec *spspec = newspspec();
2339			if (spspec == NULL)
2340				ABORT();
2341
2342			insspspec(cur_rmconf, spspec);
2343		}
2344		BOC isakmpproposal_specs EOC
2345	;
2346exchange_types
2347	:	/* nothing */
2348	|	exchange_types EXCHANGETYPE
2349		{
2350			struct etypes *new = racoon_malloc(sizeof(struct etypes));
2351			if (new == NULL) {
2352				yyerror("failed to allocate etypes");
2353				ABORT();
2354			}
2355
2356			new->next = NULL; new->type = $2;
2357			if (cur_rmconf->etypes == NULL)
2358				cur_rmconf->etypes = new;
2359			else {
2360				struct etypes *p;
2361				for (p = cur_rmconf->etypes;
2362				     p->next != NULL;
2363				     p = p->next)
2364					;
2365				p->next = new;
2366			}
2367		}
2368	;
2369cert_spec
2370	:	CERT_X509 QUOTEDSTRING QUOTEDSTRING
2371		{
2372			if (cur_rmconf->mycert != NULL) {
2373				yyerror("certificate_type already defined\n");
2374				ABORT_AND_VFREE2($2, $3);
2375			}
2376
2377			if (load_x509($2->v, &cur_rmconf->mycertfile,
2378					&cur_rmconf->mycert)) {
2379				yyerror("failed to load certificate \"%s\"\n",
2380					$2->v);
2381				ABORT_AND_VFREE2($2, $3);
2382			}
2383
2384			cur_rmconf->myprivfile = racoon_strdup($3->v);
2385			if (!cur_rmconf->myprivfile) {
2386				yyerror("failed to allocate myprivfile\n");
2387				ABORT_AND_VFREE2($2, $3);
2388			}
2389
2390			vfree($2);
2391			vfree($3);
2392		}
2393		EOS
2394	|	CERT_PLAINRSA QUOTEDSTRING
2395		{
2396			char path[MAXPATHLEN];
2397
2398			if (cur_rmconf->mycert != NULL) {
2399				yyerror("certificate_type already defined\n");
2400				ABORT_AND_VFREE($2);
2401			}
2402
2403			cur_rmconf->mycert = vmalloc(1);
2404			if (cur_rmconf->mycert == NULL) {
2405				yyerror("failed to allocate mycert\n");
2406				ABORT_AND_VFREE($2);
2407			}
2408
2409			cur_rmconf->mycert->v[0] = ISAKMP_CERT_PLAINRSA;
2410
2411			getpathname(path, sizeof(path),
2412				    LC_PATHTYPE_CERT, $2->v);
2413			cur_rmconf->send_cr = FALSE;
2414			cur_rmconf->send_cert = FALSE;
2415			cur_rmconf->verify_cert = FALSE;
2416			if (rsa_parse_file(cur_rmconf->rsa_private, path,
2417					RSA_TYPE_PRIVATE)) {
2418				yyerror("Couldn't parse keyfile %s\n", path);
2419				ABORT_AND_VFREE($2);
2420			}
2421
2422			plog(LLV_DEBUG, LOCATION, NULL,
2423			     "Private PlainRSA keyfile parsed: %s\n", path);
2424			vfree($2);
2425		}
2426		EOS
2427	;
2428dh_group_num
2429	:	ALGORITHMTYPE
2430		{
2431			$$ = algtype2doi(algclass_isakmp_dh, $1);
2432			if ($$ == -1) {
2433				yyerror("must be DH group\n");
2434				ABORT();
2435			}
2436		}
2437	|	NUMBER
2438		{
2439			if (ARRAYLEN(num2dhgroup) > $1 && num2dhgroup[$1] != 0) {
2440				$$ = num2dhgroup[$1];
2441			} else {
2442				$$ = 0;
2443				yyerror("must be DH group\n");
2444				ABORT();
2445			}
2446		}
2447	;
2448identifierstring
2449	:	/* nothing */ { $$ = NULL; }
2450	|	ADDRSTRING { $$ = $1; }
2451	|	QUOTEDSTRING { $$ = $1; }
2452	;
2453isakmpproposal_specs
2454	:	/* nothing */
2455	|	isakmpproposal_specs isakmpproposal_spec
2456	;
2457isakmpproposal_spec
2458	:	LIFETIME LIFETYPE_TIME NUMBER unittype_time
2459		{
2460			cur_rmconf->spspec->lifetime = $3 * $4;
2461		}
2462		EOS
2463	|	LIFETIME LIFETYPE_BYTE NUMBER unittype_byte
2464		{
2465#if 1
2466			yyerror("byte lifetime support is deprecated\n");
2467			ABORT();
2468#else
2469			cur_rmconf->spspec->lifebyte = fix_lifebyte($3 * $4);
2470			if (cur_rmconf->spspec->lifebyte == 0)
2471				ABORT();
2472#endif
2473		}
2474		EOS
2475	|	DH_GROUP dh_group_num
2476		{
2477			cur_rmconf->spspec->algclass[algclass_isakmp_dh] = $2;
2478		}
2479		EOS
2480	|	GSS_ID QUOTEDSTRING
2481		{
2482			if (cur_rmconf->spspec->vendorid != VENDORID_GSSAPI) {
2483				yyerror("wrong Vendor ID for gssapi_id\n");
2484				ABORT_AND_VFREE($2);
2485			}
2486
2487			if (cur_rmconf->spspec->gssid != NULL)
2488				racoon_free(cur_rmconf->spspec->gssid);
2489			cur_rmconf->spspec->gssid =
2490			    racoon_strdup($2->v);
2491			if (!cur_rmconf->spspec->gssid) {
2492				yyerror("failed to allocate gssid\n");
2493				ABORT_AND_VFREE($2);
2494			}
2495		}
2496		EOS
2497	|	ALGORITHM_CLASS ALGORITHMTYPE keylength
2498		{
2499			int doi;
2500			int defklen;
2501
2502			doi = algtype2doi($1, $2);
2503			if (doi == -1) {
2504				yyerror("algorithm mismatched 1\n");
2505				ABORT();
2506			}
2507
2508			switch ($1) {
2509			case algclass_isakmp_enc:
2510			/* reject suppressed algorithms */
2511#ifndef HAVE_OPENSSL_RC5_H
2512				if ($2 == algtype_rc5) {
2513					yyerror("algorithm %s not supported\n",
2514						s_attr_isakmp_enc(doi));
2515					ABORT();
2516				}
2517#endif
2518#ifndef HAVE_OPENSSL_IDEA_H
2519				if ($2 == algtype_idea) {
2520					yyerror("algorithm %s not supported\n",
2521						s_attr_isakmp_enc(doi));
2522					ABORT();
2523				}
2524#endif
2525
2526				cur_rmconf->spspec->algclass[algclass_isakmp_enc] = doi;
2527				defklen = default_keylen($1, $2);
2528				if (defklen == 0) {
2529					if ($3) {
2530						yyerror("keylen not allowed\n");
2531						ABORT();
2532					}
2533				} else {
2534					if ($3 && check_keylen($1, $2, $3) < 0) {
2535						yyerror("invalid keylen %d\n", $3);
2536						ABORT();
2537					}
2538				}
2539				if ($3)
2540					cur_rmconf->spspec->encklen = $3;
2541				else
2542					cur_rmconf->spspec->encklen = defklen;
2543				break;
2544			case algclass_isakmp_hash:
2545				cur_rmconf->spspec->algclass[algclass_isakmp_hash] = doi;
2546				break;
2547			case algclass_isakmp_ameth:
2548				cur_rmconf->spspec->algclass[algclass_isakmp_ameth] = doi;
2549				/*
2550				 * We may have to set the Vendor ID for the
2551				 * authentication method we're using.
2552				 */
2553				switch ($2) {
2554				case algtype_gssapikrb:
2555					if (cur_rmconf->spspec->vendorid !=
2556						VENDORID_UNKNOWN) {
2557						yyerror("Vendor ID mismatch for auth method\n");
2558						ABORT();
2559					}
2560					/*
2561					 * For interoperability with Win2k,
2562					 * we set the Vendor ID to "GSSAPI".
2563					 */
2564					cur_rmconf->spspec->vendorid =
2565					    VENDORID_GSSAPI;
2566					break;
2567				case algtype_rsasig:
2568					if (oakley_get_certtype(cur_rmconf->peerscert) == ISAKMP_CERT_PLAINRSA) {
2569						if (rsa_list_count(cur_rmconf->rsa_private) == 0) {
2570							yyerror ("Private PlainRSA key not set."
2571								"Use directive 'certificate_type plainrsa ...'\n");
2572							ABORT();
2573						}
2574
2575						if (rsa_list_count(cur_rmconf->rsa_public) == 0) {
2576							yyerror ("Public PlainRSA keys not set."
2577								"Use directive 'peers_certfile plainrsa ...'\n");
2578							ABORT();
2579						}
2580					}
2581					break;
2582				default:
2583					break;
2584				}
2585				break;
2586			default:
2587				yyerror("algorithm mismatched 2\n");
2588				ABORT();
2589			}
2590		}
2591		EOS
2592	;
2593
2594unittype_time
2595	:	UNITTYPE_SEC	{ $$ = 1; }
2596	|	UNITTYPE_MIN	{ $$ = 60; }
2597	|	UNITTYPE_HOUR	{ $$ = (60 * 60); }
2598	;
2599unittype_byte
2600	:	UNITTYPE_BYTE	{ $$ = 1; }
2601	|	UNITTYPE_KBYTES	{ $$ = 1024; }
2602	|	UNITTYPE_MBYTES	{ $$ = (1024 * 1024); }
2603	|	UNITTYPE_TBYTES	{ $$ = (1024 * 1024 * 1024); }
2604	;
2605%%
2606
2607static struct secprotospec *
2608newspspec()
2609{
2610	struct secprotospec *new;
2611
2612	new = racoon_calloc(1, sizeof(*new));
2613	if (new == NULL) {
2614		yyerror("failed to allocate spproto");
2615		return NULL;
2616	}
2617
2618	new->encklen = 0;	/*XXX*/
2619
2620	/*
2621	 * Default to "uknown" vendor -- we will override this
2622	 * as necessary.  When we send a Vendor ID payload, an
2623	 * "unknown" will be translated to a KAME/racoon ID.
2624	 */
2625	new->vendorid = VENDORID_UNKNOWN;
2626
2627	return new;
2628}
2629
2630/*
2631 * insert into head of list.
2632 */
2633static void
2634insspspec(rmconf, spspec)
2635	struct remoteconf *rmconf;
2636	struct secprotospec *spspec;
2637{
2638	if (rmconf->spspec != NULL)
2639		rmconf->spspec->prev = spspec;
2640	spspec->next = rmconf->spspec;
2641	rmconf->spspec = spspec;
2642}
2643
2644static struct secprotospec *
2645dupspspec(struct secprotospec *spspec)
2646{
2647	struct secprotospec *new;
2648
2649	new = newspspec();
2650	if (new == NULL) {
2651		plog(LLV_ERROR, LOCATION, NULL,
2652		    "dupspspec: malloc failed\n");
2653		return NULL;
2654	}
2655	memcpy(new, spspec, sizeof(*new));
2656
2657	if (spspec->gssid) {
2658		new->gssid = racoon_strdup(spspec->gssid);
2659		STRDUP_FATAL(new->gssid);
2660	}
2661	if (spspec->remote) {
2662		new->remote = racoon_malloc(sizeof(*new->remote));
2663		if (new->remote == NULL) {
2664			plog(LLV_ERROR, LOCATION, NULL,
2665			    "dupspspec: malloc failed (remote)\n");
2666			return NULL;
2667		}
2668		memcpy(new->remote, spspec->remote, sizeof(*new->remote));
2669	}
2670
2671	return new;
2672}
2673
2674/*
2675 * copy the whole list
2676 */
2677void
2678dupspspec_list(dst, src)
2679	struct remoteconf *dst, *src;
2680{
2681	struct secprotospec *p, *new, *last;
2682
2683	for(p = src->spspec, last = NULL; p; p = p->next, last = new) {
2684		new = dupspspec(p);
2685		if (new == NULL)
2686			exit(1);
2687
2688		new->prev = last;
2689		new->next = NULL; /* not necessary but clean */
2690
2691		if (last)
2692			last->next = new;
2693		else /* first element */
2694			dst->spspec = new;
2695
2696	}
2697}
2698
2699/*
2700 * delete the whole list
2701 */
2702void
2703flushspspec(rmconf)
2704	struct remoteconf *rmconf;
2705{
2706	struct secprotospec *p;
2707
2708	while(rmconf->spspec != NULL) {
2709		p = rmconf->spspec;
2710		rmconf->spspec = p->next;
2711		if (p->next != NULL)
2712			p->next->prev = NULL; /* not necessary but clean */
2713
2714		if (p->gssid)
2715			racoon_free(p->gssid);
2716		if (p->remote)
2717			racoon_free(p->remote);
2718		racoon_free(p);
2719	}
2720	rmconf->spspec = NULL;
2721}
2722
2723/* set final acceptable proposal */
2724static int
2725set_isakmp_proposal(rmconf)
2726	struct remoteconf *rmconf;
2727{
2728	struct secprotospec *s;
2729	int prop_no = 1;
2730	int trns_no = 1;
2731	int32_t types[MAXALGCLASS];
2732
2733	/* mandatory check */
2734	if (rmconf->spspec == NULL) {
2735		yyerror("no remote specification found: %s.\n",
2736			saddr2str(rmconf->remote));
2737		return -1;
2738	}
2739	for (s = rmconf->spspec; s != NULL; s = s->next) {
2740		/* XXX need more to check */
2741		if (s->algclass[algclass_isakmp_enc] == 0) {
2742			yyerror("encryption algorithm required.");
2743			return -1;
2744		}
2745		if (s->algclass[algclass_isakmp_hash] == 0) {
2746			yyerror("hash algorithm required.");
2747			return -1;
2748		}
2749		if (s->algclass[algclass_isakmp_dh] == 0) {
2750			yyerror("DH group required.");
2751			return -1;
2752		}
2753		if (s->algclass[algclass_isakmp_ameth] == 0) {
2754			yyerror("authentication method required.");
2755			return -1;
2756		}
2757	}
2758
2759	/* skip to last part */
2760	for (s = rmconf->spspec; s->next != NULL; s = s->next)
2761		;
2762
2763	while (s != NULL) {
2764		plog(LLV_DEBUG2, LOCATION, NULL,
2765			"lifetime = %ld\n", (long)
2766			(s->lifetime ? s->lifetime : rmconf->lifetime));
2767		plog(LLV_DEBUG2, LOCATION, NULL,
2768			"lifebyte = %d\n",
2769			s->lifebyte ? s->lifebyte : rmconf->lifebyte);
2770		plog(LLV_DEBUG2, LOCATION, NULL,
2771			"encklen=%d\n", s->encklen);
2772
2773		memset(types, 0, ARRAYLEN(types));
2774		types[algclass_isakmp_enc] = s->algclass[algclass_isakmp_enc];
2775		types[algclass_isakmp_hash] = s->algclass[algclass_isakmp_hash];
2776		types[algclass_isakmp_dh] = s->algclass[algclass_isakmp_dh];
2777		types[algclass_isakmp_ameth] =
2778		    s->algclass[algclass_isakmp_ameth];
2779
2780		/* expanding spspec */
2781		clean_tmpalgtype();
2782		trns_no = expand_isakmpspec(prop_no, trns_no, types,
2783				algclass_isakmp_enc, algclass_isakmp_ameth + 1,
2784				s->lifetime ? s->lifetime : rmconf->lifetime,
2785				s->lifebyte ? s->lifebyte : rmconf->lifebyte,
2786				s->encklen, s->vendorid, s->gssid,
2787				rmconf);
2788		if (trns_no == -1) {
2789			plog(LLV_ERROR, LOCATION, NULL,
2790				"failed to expand isakmp proposal.\n");
2791			return -1;
2792		}
2793
2794		s = s->prev;
2795	}
2796
2797	if (rmconf->proposal == NULL) {
2798		plog(LLV_ERROR, LOCATION, NULL,
2799			"no proposal found.\n");
2800		return -1;
2801	}
2802
2803	return 0;
2804}
2805
2806static void
2807clean_tmpalgtype()
2808{
2809	int i;
2810	for (i = 0; i < MAXALGCLASS; i++)
2811		tmpalgtype[i] = 0;	/* means algorithm undefined. */
2812}
2813
2814static int
2815expand_isakmpspec(prop_no, trns_no, types,
2816		class, last, lifetime, lifebyte, encklen, vendorid, gssid,
2817		rmconf)
2818	int prop_no, trns_no;
2819	int *types, class, last;
2820	time_t lifetime;
2821	int lifebyte;
2822	int encklen;
2823	int vendorid;
2824	char *gssid;
2825	struct remoteconf *rmconf;
2826{
2827	struct isakmpsa *new;
2828
2829	/* debugging */
2830    {
2831	int j;
2832	char tb[10];
2833	plog(LLV_DEBUG2, LOCATION, NULL,
2834		"p:%d t:%d\n", prop_no, trns_no);
2835	for (j = class; j < MAXALGCLASS; j++) {
2836		snprintf(tb, sizeof(tb), "%d", types[j]);
2837		plog(LLV_DEBUG2, LOCATION, NULL,
2838			"%s%s%s%s\n",
2839			s_algtype(j, types[j]),
2840			types[j] ? "(" : "",
2841			tb[0] == '0' ? "" : tb,
2842			types[j] ? ")" : "");
2843	}
2844	plog(LLV_DEBUG2, LOCATION, NULL, "\n");
2845    }
2846
2847#define TMPALGTYPE2STR(n) \
2848	s_algtype(algclass_isakmp_##n, types[algclass_isakmp_##n])
2849		/* check mandatory values */
2850		if (types[algclass_isakmp_enc] == 0
2851		 || types[algclass_isakmp_ameth] == 0
2852		 || types[algclass_isakmp_hash] == 0
2853		 || types[algclass_isakmp_dh] == 0) {
2854			yyerror("few definition of algorithm "
2855				"enc=%s ameth=%s hash=%s dhgroup=%s.\n",
2856				TMPALGTYPE2STR(enc),
2857				TMPALGTYPE2STR(ameth),
2858				TMPALGTYPE2STR(hash),
2859				TMPALGTYPE2STR(dh));
2860			return -1;
2861		}
2862#undef TMPALGTYPE2STR
2863
2864	/* set new sa */
2865	new = newisakmpsa();
2866	if (new == NULL) {
2867		yyerror("failed to allocate isakmp sa");
2868		return -1;
2869	}
2870	new->prop_no = prop_no;
2871	new->trns_no = trns_no++;
2872	new->lifetime = lifetime;
2873	new->lifebyte = lifebyte;
2874	new->enctype = types[algclass_isakmp_enc];
2875	new->encklen = encklen;
2876	new->authmethod = types[algclass_isakmp_ameth];
2877	new->hashtype = types[algclass_isakmp_hash];
2878	new->dh_group = types[algclass_isakmp_dh];
2879	new->vendorid = vendorid;
2880#ifdef HAVE_GSSAPI
2881	if (new->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
2882		if (gssid != NULL) {
2883			if ((new->gssid = vmalloc(strlen(gssid))) == NULL) {
2884				racoon_free(new);
2885				yyerror("failed to allocate gssid");
2886				return -1;
2887			}
2888			memcpy(new->gssid->v, gssid, new->gssid->l);
2889			racoon_free(gssid);
2890		} else {
2891			/*
2892			 * Allocate the default ID so that it gets put
2893			 * into a GSS ID attribute during the Phase 1
2894			 * exchange.
2895			 */
2896			new->gssid = gssapi_get_default_gss_id();
2897		}
2898	}
2899#endif
2900	insisakmpsa(new, rmconf);
2901
2902	return trns_no;
2903}
2904
2905#if 0
2906/*
2907 * fix lifebyte.
2908 * Must be more than 1024B because its unit is kilobytes.
2909 * That is defined RFC2407.
2910 */
2911static int
2912fix_lifebyte(t)
2913	unsigned long t;
2914{
2915	if (t < 1024) {
2916		yyerror("byte size should be more than 1024B.");
2917		return 0;
2918	}
2919
2920	return(t / 1024);
2921}
2922#endif
2923
2924int
2925cfparse()
2926{
2927	int error;
2928
2929	yyerrorcount = 0;
2930	yycf_init_buffer();
2931
2932	if (yycf_switch_buffer(lcconf->racoon_conf) != 0) {
2933		plog(LLV_ERROR, LOCATION, NULL,
2934		    "could not read configuration file \"%s\"\n",
2935		    lcconf->racoon_conf);
2936		return -1;
2937	}
2938
2939	error = yyparse();
2940	if (error != 0) {
2941		if (yyerrorcount) {
2942			plog(LLV_ERROR, LOCATION, NULL,
2943				"fatal parse failure (%d errors)\n",
2944				yyerrorcount);
2945		} else {
2946			plog(LLV_ERROR, LOCATION, NULL,
2947				"fatal parse failure.\n");
2948		}
2949		return -1;
2950	}
2951
2952	if (error == 0 && yyerrorcount) {
2953		plog(LLV_ERROR, LOCATION, NULL,
2954			"parse error is nothing, but yyerrorcount is %d.\n",
2955				yyerrorcount);
2956		exit(1);
2957	}
2958
2959	yycf_clean_buffer();
2960
2961	plog(LLV_DEBUG2, LOCATION, NULL, "parse successed.\n");
2962
2963	return 0;
2964}
2965
2966int
2967cfreparse()
2968{
2969	flushph2();
2970	flushph1();
2971	flushrmconf();
2972	flushsainfo();
2973	clean_tmpalgtype();
2974	return(cfparse());
2975}
2976
2977#ifdef ENABLE_ADMINPORT
2978static void
2979adminsock_conf(path, owner, group, mode_dec)
2980	vchar_t *path;
2981	vchar_t *owner;
2982	vchar_t *group;
2983	int mode_dec;
2984{
2985	struct passwd *pw = NULL;
2986	struct group *gr = NULL;
2987	mode_t mode = 0;
2988	uid_t uid;
2989	gid_t gid;
2990	int isnum;
2991
2992	adminsock_path = path->v;
2993
2994	if (owner == NULL)
2995		return;
2996
2997	errno = 0;
2998	uid = atoi(owner->v);
2999	isnum = !errno;
3000	if (((pw = getpwnam(owner->v)) == NULL) && !isnum)
3001		yywarn("User \"%s\" does not exist\n", owner->v);
3002
3003	if (pw)
3004		adminsock_owner = pw->pw_uid;
3005	else
3006		adminsock_owner = uid;
3007
3008	if (group == NULL)
3009		return;
3010
3011	errno = 0;
3012	gid = atoi(group->v);
3013	isnum = !errno;
3014	if (((gr = getgrnam(group->v)) == NULL) && !isnum)
3015		yywarn("Group \"%s\" does not exist\n", group->v);
3016
3017	if (gr)
3018		adminsock_group = gr->gr_gid;
3019	else
3020		adminsock_group = gid;
3021
3022	if (mode_dec == -1)
3023		return;
3024
3025	if (mode_dec > 777)
3026		yywarn("Mode 0%03o is invalid\n", mode_dec);
3027
3028	if (mode_dec >= 400) { mode += 0400; mode_dec -= 400; }
3029	if (mode_dec >= 200) { mode += 0200; mode_dec -= 200; }
3030	if (mode_dec >= 100) { mode += 0200; mode_dec -= 100; }
3031
3032	if (mode_dec > 77)
3033		yywarn("Mode 0%03o is invalid\n", mode_dec);
3034
3035	if (mode_dec >= 40) { mode += 040; mode_dec -= 40; }
3036	if (mode_dec >= 20) { mode += 020; mode_dec -= 20; }
3037	if (mode_dec >= 10) { mode += 020; mode_dec -= 10; }
3038
3039	if (mode_dec > 7)
3040		yywarn("Mode 0%03o is invalid\n", mode_dec);
3041
3042	if (mode_dec >= 4) { mode += 04; mode_dec -= 4; }
3043	if (mode_dec >= 2) { mode += 02; mode_dec -= 2; }
3044	if (mode_dec >= 1) { mode += 02; mode_dec -= 1; }
3045
3046	adminsock_mode = mode;
3047
3048	return;
3049}
3050#endif
3051