1/*	$KAME: parse.y,v 1.83 2004/05/18 08:48:23 sakane Exp $	*/
2
3/*-
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34%{
35#include <sys/types.h>
36#include <sys/param.h>
37#include <sys/socket.h>
38
39#include <net/route.h>
40#include <netinet/in.h>
41#include <net/pfkeyv2.h>
42#include <netipsec/key_var.h>
43#include <netipsec/ipsec.h>
44#include <arpa/inet.h>
45#include <netinet/udp.h>
46
47#include <string.h>
48#include <unistd.h>
49#include <stdio.h>
50#include <stdint.h>
51#include <netdb.h>
52#include <ctype.h>
53#include <errno.h>
54
55#include "libpfkey.h"
56#include "vchar.h"
57
58#define ATOX(c) \
59  (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10)))
60
61u_int32_t p_spi;
62u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
63u_int32_t p_reqid;
64u_int p_key_enc_len, p_key_auth_len;
65caddr_t p_key_enc, p_key_auth;
66time_t p_lt_hard, p_lt_soft;
67u_int p_natt_type;
68struct addrinfo *p_natt_oai, *p_natt_oar;
69int p_natt_sport, p_natt_dport;
70int p_natt_fraglen;
71
72static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
73
74static struct addrinfo *parse_addr(char *, char *);
75static int fix_portstr(vchar_t *, vchar_t *, vchar_t *);
76static int setvarbuf(char *, int *, struct sadb_ext *, int, caddr_t, int);
77void parse_init(void);
78void free_buffer(void);
79
80int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
81static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
82	struct addrinfo *, int, struct addrinfo *, int);
83static int setkeymsg_addr(unsigned int, unsigned int,
84	struct addrinfo *, struct addrinfo *, int);
85static int setkeymsg_add(unsigned int, unsigned int,
86	struct addrinfo *, struct addrinfo *);
87extern int setkeymsg(char *, size_t *);
88extern int sendkeymsg(char *, size_t);
89
90extern int yylex(void);
91extern void yyfatal(const char *);
92extern void yyerror(const char *);
93%}
94
95%union {
96	int num;
97	unsigned long ulnum;
98	vchar_t val;
99	struct addrinfo *res;
100}
101
102%token EOT SLASH BLCL ELCL
103%token ADD GET DELETE DELETEALL FLUSH DUMP
104%token PR_ESP PR_AH PR_IPCOMP PR_TCP
105%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
106%token F_MODE MODE F_REQID
107%token F_EXT EXTENSION NOCYCLICSEQ
108%token ALG_AUTH ALG_AUTH_NOKEY
109%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
110%token ALG_ENC_SALT
111%token ALG_COMP
112%token F_LIFETIME_HARD F_LIFETIME_SOFT
113%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
114	/* SPD management */
115%token SPDADD SPDDELETE SPDDUMP SPDFLUSH
116%token F_POLICY PL_REQUESTS
117%token F_AIFLAGS F_NATT F_NATT_MTU
118%token TAGGED
119
120%type <num> prefix protocol_spec upper_spec
121%type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
122%type <num> ALG_ENC_SALT
123%type <num> ALG_AUTH ALG_AUTH_NOKEY
124%type <num> ALG_COMP
125%type <num> PR_ESP PR_AH PR_IPCOMP PR_TCP
126%type <num> EXTENSION MODE
127%type <ulnum> DECSTRING
128%type <val> PL_REQUESTS portstr key_string
129%type <val> policy_requests
130%type <val> QUOTEDSTRING HEXSTRING STRING
131%type <val> F_AIFLAGS
132%type <val> upper_misc_spec policy_spec
133%type <res> ipaddr
134
135%%
136commands
137	:	/*NOTHING*/
138	|	commands command
139		{
140			free_buffer();
141			parse_init();
142		}
143	;
144
145command
146	:	add_command
147	|	get_command
148	|	delete_command
149	|	deleteall_command
150	|	flush_command
151	|	dump_command
152	|	spdadd_command
153	|	spddelete_command
154	|	spddump_command
155	|	spdflush_command
156	;
157	/* commands concerned with management, there is in tail of this file. */
158
159	/* add command */
160add_command
161	:	ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT
162		{
163			int status;
164
165			status = setkeymsg_add(SADB_ADD, $5, $3, $4);
166			if (status < 0)
167				return -1;
168		}
169	;
170
171	/* delete */
172delete_command
173	:	DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
174		{
175			int status;
176
177			if ($3->ai_next || $4->ai_next) {
178				yyerror("multiple address specified");
179				return -1;
180			}
181			if (p_mode != IPSEC_MODE_ANY)
182				yyerror("WARNING: mode is obsolete");
183
184			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
185			if (status < 0)
186				return -1;
187		}
188	;
189
190	/* deleteall command */
191deleteall_command
192	:	DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
193		{
194			int status;
195
196			status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1);
197			if (status < 0)
198				return -1;
199		}
200	;
201
202	/* get command */
203get_command
204	:	GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT
205		{
206			int status;
207
208			if (p_mode != IPSEC_MODE_ANY)
209				yyerror("WARNING: mode is obsolete");
210
211			status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
212			if (status < 0)
213				return -1;
214		}
215	;
216
217	/* flush */
218flush_command
219	:	FLUSH protocol_spec EOT
220		{
221			struct sadb_msg msg;
222			setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
223			sendkeymsg((char *)&msg, sizeof(msg));
224		}
225	;
226
227	/* dump */
228dump_command
229	:	DUMP protocol_spec EOT
230		{
231			struct sadb_msg msg;
232			setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
233			sendkeymsg((char *)&msg, sizeof(msg));
234		}
235	;
236
237protocol_spec
238	:	/*NOTHING*/
239		{
240			$$ = SADB_SATYPE_UNSPEC;
241		}
242	|	PR_ESP
243		{
244			$$ = SADB_SATYPE_ESP;
245			if ($1 == 1)
246				p_ext |= SADB_X_EXT_OLD;
247			else
248				p_ext &= ~SADB_X_EXT_OLD;
249		}
250	|	PR_AH
251		{
252			$$ = SADB_SATYPE_AH;
253			if ($1 == 1)
254				p_ext |= SADB_X_EXT_OLD;
255			else
256				p_ext &= ~SADB_X_EXT_OLD;
257		}
258	|	PR_IPCOMP
259		{
260			$$ = SADB_X_SATYPE_IPCOMP;
261		}
262	|	PR_TCP
263		{
264			$$ = SADB_X_SATYPE_TCPSIGNATURE;
265		}
266	;
267
268spi
269	:	DECSTRING { p_spi = $1; }
270	|	HEXSTRING
271		{
272			char *ep;
273			unsigned long v;
274
275			ep = NULL;
276			v = strtoul($1.buf, &ep, 16);
277			if (!ep || *ep) {
278				yyerror("invalid SPI");
279				return -1;
280			}
281			if (v & ~0xffffffff) {
282				yyerror("SPI too big.");
283				return -1;
284			}
285
286			p_spi = v;
287		}
288	;
289
290algorithm_spec
291	:	esp_spec
292	|	ah_spec
293	|	ipcomp_spec
294	;
295
296esp_spec
297	:	F_ENC enc_alg F_AUTH auth_alg
298	|	F_ENC enc_alg
299	;
300
301ah_spec
302	:	F_AUTH auth_alg
303	;
304
305ipcomp_spec
306	:	F_COMP ALG_COMP
307		{
308			if ($2 < 0) {
309				yyerror("unsupported algorithm");
310				return -1;
311			}
312			p_alg_enc = $2;
313		}
314	|	F_COMP ALG_COMP F_RAWCPI
315		{
316			if ($2 < 0) {
317				yyerror("unsupported algorithm");
318				return -1;
319			}
320			p_alg_enc = $2;
321			p_ext |= SADB_X_EXT_RAWCPI;
322		}
323	;
324
325enc_alg
326	:	ALG_ENC_NOKEY {
327			if ($1 < 0) {
328				yyerror("unsupported algorithm");
329				return -1;
330			}
331			p_alg_enc = $1;
332
333			p_key_enc_len = 0;
334			p_key_enc = NULL;
335			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
336			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
337				yyerror(ipsec_strerror());
338				return -1;
339			}
340		}
341	|	ALG_ENC key_string {
342			if ($1 < 0) {
343				yyerror("unsupported algorithm");
344				return -1;
345			}
346			p_alg_enc = $1;
347
348			p_key_enc_len = $2.len;
349			p_key_enc = $2.buf;
350			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
351			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
352				yyerror(ipsec_strerror());
353				return -1;
354			}
355		}
356	|	ALG_ENC_OLD {
357			if ($1 < 0) {
358				yyerror("unsupported algorithm");
359				return -1;
360			}
361			yyerror("WARNING: obsolete algorithm");
362			p_alg_enc = $1;
363
364			p_key_enc_len = 0;
365			p_key_enc = NULL;
366			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
367			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
368				yyerror(ipsec_strerror());
369				return -1;
370			}
371		}
372	|	ALG_ENC_DESDERIV key_string
373		{
374			if ($1 < 0) {
375				yyerror("unsupported algorithm");
376				return -1;
377			}
378			p_alg_enc = $1;
379			if (p_ext & SADB_X_EXT_OLD) {
380				yyerror("algorithm mismatched");
381				return -1;
382			}
383			p_ext |= SADB_X_EXT_DERIV;
384
385			p_key_enc_len = $2.len;
386			p_key_enc = $2.buf;
387			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
388			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
389				yyerror(ipsec_strerror());
390				return -1;
391			}
392		}
393	|	ALG_ENC_DES32IV key_string
394		{
395			if ($1 < 0) {
396				yyerror("unsupported algorithm");
397				return -1;
398			}
399			p_alg_enc = $1;
400			if (!(p_ext & SADB_X_EXT_OLD)) {
401				yyerror("algorithm mismatched");
402				return -1;
403			}
404			p_ext |= SADB_X_EXT_IV4B;
405
406			p_key_enc_len = $2.len;
407			p_key_enc = $2.buf;
408			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
409			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
410				yyerror(ipsec_strerror());
411				return -1;
412			}
413		}
414	|	ALG_ENC_SALT key_string
415		{
416			if ($1 < 0) {
417				yyerror("unsupported algorithm");
418				return -1;
419			}
420			p_alg_enc = $1;
421
422			p_key_enc_len = $2.len;
423
424			p_key_enc = $2.buf;
425			/*
426			 * Salted keys include a 4 byte value that is
427			 * not part of the key.
428			 */
429			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
430			    p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len - 4)) < 0) {
431				yyerror(ipsec_strerror());
432				return -1;
433			}
434		}
435	;
436
437auth_alg
438	:	ALG_AUTH key_string {
439			if ($1 < 0) {
440				yyerror("unsupported algorithm");
441				return -1;
442			}
443			p_alg_auth = $1;
444
445			p_key_auth_len = $2.len;
446			p_key_auth = $2.buf;
447
448			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
449				if ((p_key_auth_len < 1) || (p_key_auth_len >
450				    80))
451					return -1;
452			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
453			    p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
454				yyerror(ipsec_strerror());
455				return -1;
456			}
457		}
458	|	ALG_AUTH_NOKEY {
459			if ($1 < 0) {
460				yyerror("unsupported algorithm");
461				return -1;
462			}
463			p_alg_auth = $1;
464
465			p_key_auth_len = 0;
466			p_key_auth = NULL;
467		}
468	;
469
470key_string
471	:	QUOTEDSTRING
472		{
473			$$ = $1;
474		}
475	|	HEXSTRING
476		{
477			caddr_t pp_key;
478			caddr_t bp;
479			caddr_t yp = $1.buf;
480			int l;
481
482			l = strlen(yp) % 2 + strlen(yp) / 2;
483			if ((pp_key = malloc(l)) == 0) {
484				yyerror("not enough core");
485				return -1;
486			}
487			memset(pp_key, 0, l);
488
489			bp = pp_key;
490			if (strlen(yp) % 2) {
491				*bp = ATOX(yp[0]);
492				yp++, bp++;
493			}
494			while (*yp) {
495				*bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
496				yp += 2, bp++;
497			}
498
499			$$.len = l;
500			$$.buf = pp_key;
501		}
502	;
503
504extension_spec
505	:	/*NOTHING*/
506	|	extension_spec extension
507	;
508
509extension
510	:	F_EXT EXTENSION { p_ext |= $2; }
511	|	F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
512	|	F_MODE MODE { p_mode = $2; }
513	|	F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
514	|	F_REQID DECSTRING { p_reqid = $2; }
515	|	F_REPLAY DECSTRING
516		{
517			if ((p_ext & SADB_X_EXT_OLD) != 0) {
518				yyerror("replay prevention cannot be used with "
519				    "ah/esp-old");
520				return -1;
521			}
522			p_replay = $2;
523			if (p_replay > (UINT32_MAX - 32) >> 3)
524				yyerror("replay window is too large");
525		}
526	|	F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
527	|	F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
528	|	F_NATT ipaddr BLCL DECSTRING ELCL ipaddr BLCL DECSTRING ELCL
529		{
530			p_natt_type = UDP_ENCAP_ESPINUDP;
531			p_natt_oai = $2;
532			p_natt_oar = $6;
533			if (p_natt_oai == NULL || p_natt_oar == NULL)
534				return (-1);
535			p_natt_sport = $4;
536			p_natt_dport = $8;
537		}
538	|	F_NATT_MTU DECSTRING
539		{
540			p_natt_fraglen = $2;
541		}
542	;
543
544	/* definition about command for SPD management */
545	/* spdadd */
546spdadd_command
547	:	SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
548		{
549			int status;
550			struct addrinfo *src, *dst;
551
552			/* fixed port fields if ulp is icmpv6 */
553			if ($10.buf != NULL) {
554				if ($9 != IPPROTO_ICMPV6)
555					return -1;
556				free($5.buf);
557				free($8.buf);
558				if (fix_portstr(&$10, &$5, &$8))
559					return -1;
560			}
561
562			src = parse_addr($3.buf, $5.buf);
563			dst = parse_addr($6.buf, $8.buf);
564			if (!src || !dst) {
565				/* yyerror is already called */
566				return -1;
567			}
568			if (src->ai_next || dst->ai_next) {
569				yyerror("multiple address specified");
570				freeaddrinfo(src);
571				freeaddrinfo(dst);
572				return -1;
573			}
574
575			status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11,
576			    src, $4, dst, $7);
577			freeaddrinfo(src);
578			freeaddrinfo(dst);
579			if (status < 0)
580				return -1;
581		}
582	|	SPDADD TAGGED QUOTEDSTRING policy_spec EOT
583		{
584			return -1;
585		}
586	;
587
588spddelete_command
589	:	SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT
590		{
591			int status;
592			struct addrinfo *src, *dst;
593
594			/* fixed port fields if ulp is icmpv6 */
595			if ($10.buf != NULL) {
596				if ($9 != IPPROTO_ICMPV6)
597					return -1;
598				free($5.buf);
599				free($8.buf);
600				if (fix_portstr(&$10, &$5, &$8))
601					return -1;
602			}
603
604			src = parse_addr($3.buf, $5.buf);
605			dst = parse_addr($6.buf, $8.buf);
606			if (!src || !dst) {
607				/* yyerror is already called */
608				return -1;
609			}
610			if (src->ai_next || dst->ai_next) {
611				yyerror("multiple address specified");
612				freeaddrinfo(src);
613				freeaddrinfo(dst);
614				return -1;
615			}
616
617			status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11,
618			    src, $4, dst, $7);
619			freeaddrinfo(src);
620			freeaddrinfo(dst);
621			if (status < 0)
622				return -1;
623		}
624	;
625
626spddump_command:
627		SPDDUMP EOT
628		{
629			struct sadb_msg msg;
630			setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
631			    sizeof(msg));
632			sendkeymsg((char *)&msg, sizeof(msg));
633		}
634	;
635
636spdflush_command:
637		SPDFLUSH EOT
638		{
639			struct sadb_msg msg;
640			setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
641			    sizeof(msg));
642			sendkeymsg((char *)&msg, sizeof(msg));
643		}
644	;
645
646ipaddropts
647	:	/* nothing */
648	|	ipaddropts ipaddropt
649	;
650
651ipaddropt
652	:	F_AIFLAGS
653		{
654			char *p;
655
656			for (p = $1.buf + 1; *p; p++)
657				switch (*p) {
658				case '4':
659					p_aifamily = AF_INET;
660					break;
661#ifdef INET6
662				case '6':
663					p_aifamily = AF_INET6;
664					break;
665#endif
666				case 'n':
667					p_aiflags = AI_NUMERICHOST;
668					break;
669				default:
670					yyerror("invalid flag");
671					return -1;
672				}
673		}
674	;
675
676ipaddr
677	:	STRING
678		{
679			$$ = parse_addr($1.buf, NULL);
680			if ($$ == NULL) {
681				/* yyerror already called by parse_addr */
682				return -1;
683			}
684		}
685	;
686
687prefix
688	:	/*NOTHING*/ { $$ = -1; }
689	|	SLASH DECSTRING { $$ = $2; }
690	;
691
692portstr
693	:	/*NOTHING*/
694		{
695			$$.buf = strdup("0");
696			if (!$$.buf) {
697				yyerror("insufficient memory");
698				return -1;
699			}
700			$$.len = strlen($$.buf);
701		}
702	|	BLCL ANY ELCL
703		{
704			$$.buf = strdup("0");
705			if (!$$.buf) {
706				yyerror("insufficient memory");
707				return -1;
708			}
709			$$.len = strlen($$.buf);
710		}
711	|	BLCL DECSTRING ELCL
712		{
713			char buf[20];
714			snprintf(buf, sizeof(buf), "%lu", $2);
715			$$.buf = strdup(buf);
716			if (!$$.buf) {
717				yyerror("insufficient memory");
718				return -1;
719			}
720			$$.len = strlen($$.buf);
721		}
722	|	BLCL STRING ELCL
723		{
724			$$ = $2;
725		}
726	;
727
728upper_spec
729	:	DECSTRING { $$ = $1; }
730	|	ANY { $$ = IPSEC_ULPROTO_ANY; }
731	|	PR_TCP { $$ = IPPROTO_TCP; }
732	|	PR_ESP { $$ = IPPROTO_ESP; }
733	|	STRING
734		{
735			struct protoent *ent;
736
737			ent = getprotobyname($1.buf);
738			if (ent)
739				$$ = ent->p_proto;
740			else {
741				if (strcmp("icmp6", $1.buf) == 0) {
742					$$ = IPPROTO_ICMPV6;
743				} else if(strcmp("ip4", $1.buf) == 0) {
744					$$ = IPPROTO_IPV4;
745				} else {
746					yyerror("invalid upper layer protocol");
747					return -1;
748				}
749			}
750			endprotoent();
751		}
752	;
753
754upper_misc_spec
755	:	/*NOTHING*/
756		{
757			$$.buf = NULL;
758			$$.len = 0;
759		}
760	|	STRING
761		{
762			$$.buf = strdup($1.buf);
763			if (!$$.buf) {
764				yyerror("insufficient memory");
765				return -1;
766			}
767			$$.len = strlen($$.buf);
768		}
769	;
770
771policy_spec
772	:	F_POLICY policy_requests
773		{
774			char *policy;
775
776			policy = ipsec_set_policy($2.buf, $2.len);
777			if (policy == NULL) {
778				yyerror(ipsec_strerror());
779				return -1;
780			}
781
782			$$.buf = policy;
783			$$.len = ipsec_get_policylen(policy);
784		}
785	;
786
787policy_requests
788	:	PL_REQUESTS { $$ = $1; }
789	;
790
791%%
792
793int
794setkeymsg0(struct sadb_msg *msg, unsigned type, unsigned satype, size_t l)
795{
796
797	msg->sadb_msg_version = PF_KEY_V2;
798	msg->sadb_msg_type = type;
799	msg->sadb_msg_errno = 0;
800	msg->sadb_msg_satype = satype;
801	msg->sadb_msg_reserved = 0;
802	msg->sadb_msg_seq = 0;
803	msg->sadb_msg_pid = getpid();
804	msg->sadb_msg_len = PFKEY_UNIT64(l);
805	return 0;
806}
807
808static int
809setkeymsg_plen(struct addrinfo *s)
810{
811	switch (s->ai_addr->sa_family) {
812#ifdef INET
813	case AF_INET:
814		return (sizeof(struct in_addr) << 3);
815#endif
816#ifdef INET6
817	case AF_INET6:
818		return (sizeof(struct in6_addr) << 3);
819#endif
820	default:
821		return (-1);
822	}
823}
824
825/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
826static int
827setkeymsg_spdaddr(unsigned type, unsigned upper, vchar_t *policy,
828    struct addrinfo *srcs, int splen, struct addrinfo *dsts, int dplen)
829{
830	struct sadb_msg *msg;
831	char buf[BUFSIZ];
832	int l, l0;
833	struct sadb_address m_addr;
834	struct addrinfo *s, *d;
835	int n;
836	int plen;
837	struct sockaddr *sa;
838	int salen;
839
840	msg = (struct sadb_msg *)buf;
841
842	if (!srcs || !dsts)
843		return -1;
844
845	/* fix up length afterwards */
846	setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
847	l = sizeof(struct sadb_msg);
848
849	memcpy(buf + l, policy->buf, policy->len);
850	l += policy->len;
851
852	l0 = l;
853	n = 0;
854
855	/* do it for all src/dst pairs */
856	for (s = srcs; s; s = s->ai_next) {
857		for (d = dsts; d; d = d->ai_next) {
858			/* rewind pointer */
859			l = l0;
860
861			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
862				continue;
863			plen = setkeymsg_plen(s);
864			if (plen == -1)
865				continue;
866
867			/* set src */
868			sa = s->ai_addr;
869			salen = s->ai_addr->sa_len;
870			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
871			    PFKEY_ALIGN8(salen));
872			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
873			m_addr.sadb_address_proto = upper;
874			m_addr.sadb_address_prefixlen =
875			    (splen >= 0 ? splen : plen);
876			m_addr.sadb_address_reserved = 0;
877
878			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
879			    sizeof(m_addr), (caddr_t)sa, salen);
880
881			/* set dst */
882			sa = d->ai_addr;
883			salen = d->ai_addr->sa_len;
884			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
885			    PFKEY_ALIGN8(salen));
886			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
887			m_addr.sadb_address_proto = upper;
888			m_addr.sadb_address_prefixlen =
889			    (dplen >= 0 ? dplen : plen);
890			m_addr.sadb_address_reserved = 0;
891
892			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
893			    sizeof(m_addr), (caddr_t)sa, salen);
894
895			msg->sadb_msg_len = PFKEY_UNIT64(l);
896
897			sendkeymsg(buf, l);
898
899			n++;
900		}
901	}
902
903	if (n == 0)
904		return -1;
905	else
906		return 0;
907}
908
909/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
910static int
911setkeymsg_addr(unsigned type, unsigned satype, struct addrinfo *srcs,
912    struct addrinfo *dsts, int no_spi)
913{
914	struct sadb_msg *msg;
915	char buf[BUFSIZ];
916	int l, l0, len;
917	struct sadb_sa m_sa;
918	struct sadb_x_sa2 m_sa2;
919	struct sadb_x_sa_replay m_replay;
920	struct sadb_address m_addr;
921	struct addrinfo *s, *d;
922	int n;
923	int plen;
924	struct sockaddr *sa;
925	int salen;
926
927	msg = (struct sadb_msg *)buf;
928
929	if (!srcs || !dsts)
930		return -1;
931
932	/* fix up length afterwards */
933	setkeymsg0(msg, type, satype, 0);
934	l = sizeof(struct sadb_msg);
935
936	if (!no_spi) {
937		len = sizeof(struct sadb_sa);
938		m_sa.sadb_sa_len = PFKEY_UNIT64(len);
939		m_sa.sadb_sa_exttype = SADB_EXT_SA;
940		m_sa.sadb_sa_spi = htonl(p_spi);
941		m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX:
942		    p_replay;
943		m_sa.sadb_sa_state = 0;
944		m_sa.sadb_sa_auth = p_alg_auth;
945		m_sa.sadb_sa_encrypt = p_alg_enc;
946		m_sa.sadb_sa_flags = p_ext;
947
948		memcpy(buf + l, &m_sa, len);
949		l += len;
950
951		len = sizeof(struct sadb_x_sa2);
952		m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
953		m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
954		m_sa2.sadb_x_sa2_mode = p_mode;
955		m_sa2.sadb_x_sa2_reqid = p_reqid;
956
957		memcpy(buf + l, &m_sa2, len);
958		l += len;
959
960		if (p_replay > UINT8_MAX) {
961			len = sizeof(struct sadb_x_sa_replay);
962			m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
963			m_replay.sadb_x_sa_replay_exttype =
964			    SADB_X_EXT_SA_REPLAY;
965			m_replay.sadb_x_sa_replay_replay = p_replay << 3;
966
967			memcpy(buf + l, &m_replay, len);
968			l += len;
969		}
970	}
971
972	l0 = l;
973	n = 0;
974
975	/* do it for all src/dst pairs */
976	for (s = srcs; s; s = s->ai_next) {
977		for (d = dsts; d; d = d->ai_next) {
978			/* rewind pointer */
979			l = l0;
980
981			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
982				continue;
983			plen = setkeymsg_plen(s);
984			if (plen == -1)
985				continue;
986
987			/* set src */
988			sa = s->ai_addr;
989			salen = s->ai_addr->sa_len;
990			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
991			    PFKEY_ALIGN8(salen));
992			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
993			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
994			m_addr.sadb_address_prefixlen = plen;
995			m_addr.sadb_address_reserved = 0;
996
997			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
998			    sizeof(m_addr), (caddr_t)sa, salen);
999
1000			/* set dst */
1001			sa = d->ai_addr;
1002			salen = d->ai_addr->sa_len;
1003			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1004			    PFKEY_ALIGN8(salen));
1005			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1006			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1007			m_addr.sadb_address_prefixlen = plen;
1008			m_addr.sadb_address_reserved = 0;
1009
1010			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1011			    sizeof(m_addr), (caddr_t)sa, salen);
1012
1013			msg->sadb_msg_len = PFKEY_UNIT64(l);
1014
1015			sendkeymsg(buf, l);
1016
1017			n++;
1018		}
1019	}
1020
1021	if (n == 0)
1022		return -1;
1023	else
1024		return 0;
1025}
1026
1027/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1028static int
1029setkeymsg_add(unsigned type, unsigned satype, struct addrinfo *srcs,
1030    struct addrinfo *dsts)
1031{
1032	struct sadb_msg *msg;
1033	char buf[BUFSIZ];
1034	int l, l0, len;
1035	struct sadb_sa m_sa;
1036	struct sadb_x_sa2 m_sa2;
1037	struct sadb_address m_addr;
1038	struct sadb_x_sa_replay m_replay;
1039	struct addrinfo *s, *d;
1040	struct sadb_x_nat_t_type m_natt_type;
1041	struct sadb_x_nat_t_port m_natt_port;
1042	struct sadb_x_nat_t_frag m_natt_frag;
1043	int n;
1044	int plen;
1045	struct sockaddr *sa;
1046	int salen;
1047
1048	msg = (struct sadb_msg *)buf;
1049
1050	if (!srcs || !dsts)
1051		return -1;
1052
1053	/* fix up length afterwards */
1054	setkeymsg0(msg, type, satype, 0);
1055	l = sizeof(struct sadb_msg);
1056
1057	/* set encryption algorithm, if present. */
1058	if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1059		struct sadb_key m_key;
1060
1061		m_key.sadb_key_len =
1062			PFKEY_UNIT64(sizeof(m_key)
1063				   + PFKEY_ALIGN8(p_key_enc_len));
1064		m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1065		m_key.sadb_key_bits = p_key_enc_len * 8;
1066		m_key.sadb_key_reserved = 0;
1067
1068		setvarbuf(buf, &l,
1069			(struct sadb_ext *)&m_key, sizeof(m_key),
1070			(caddr_t)p_key_enc, p_key_enc_len);
1071	}
1072
1073	/* set authentication algorithm, if present. */
1074	if (p_key_auth) {
1075		struct sadb_key m_key;
1076
1077		m_key.sadb_key_len =
1078			PFKEY_UNIT64(sizeof(m_key)
1079				   + PFKEY_ALIGN8(p_key_auth_len));
1080		m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1081		m_key.sadb_key_bits = p_key_auth_len * 8;
1082		m_key.sadb_key_reserved = 0;
1083
1084		setvarbuf(buf, &l,
1085			(struct sadb_ext *)&m_key, sizeof(m_key),
1086			(caddr_t)p_key_auth, p_key_auth_len);
1087	}
1088
1089	/* set lifetime for HARD */
1090	if (p_lt_hard != 0) {
1091		struct sadb_lifetime m_lt;
1092		u_int slen = sizeof(struct sadb_lifetime);
1093
1094		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1095		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1096		m_lt.sadb_lifetime_allocations = 0;
1097		m_lt.sadb_lifetime_bytes = 0;
1098		m_lt.sadb_lifetime_addtime = p_lt_hard;
1099		m_lt.sadb_lifetime_usetime = 0;
1100
1101		memcpy(buf + l, &m_lt, slen);
1102		l += slen;
1103	}
1104
1105	/* set lifetime for SOFT */
1106	if (p_lt_soft != 0) {
1107		struct sadb_lifetime m_lt;
1108		u_int slen = sizeof(struct sadb_lifetime);
1109
1110		m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1111		m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1112		m_lt.sadb_lifetime_allocations = 0;
1113		m_lt.sadb_lifetime_bytes = 0;
1114		m_lt.sadb_lifetime_addtime = p_lt_soft;
1115		m_lt.sadb_lifetime_usetime = 0;
1116
1117		memcpy(buf + l, &m_lt, slen);
1118		l += slen;
1119	}
1120
1121	len = sizeof(struct sadb_sa);
1122	m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1123	m_sa.sadb_sa_exttype = SADB_EXT_SA;
1124	m_sa.sadb_sa_spi = htonl(p_spi);
1125	m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay;
1126	m_sa.sadb_sa_state = 0;
1127	m_sa.sadb_sa_auth = p_alg_auth;
1128	m_sa.sadb_sa_encrypt = p_alg_enc;
1129	m_sa.sadb_sa_flags = p_ext;
1130
1131	memcpy(buf + l, &m_sa, len);
1132	l += len;
1133
1134	len = sizeof(struct sadb_x_sa2);
1135	m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1136	m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1137	m_sa2.sadb_x_sa2_mode = p_mode;
1138	m_sa2.sadb_x_sa2_reqid = p_reqid;
1139
1140	memcpy(buf + l, &m_sa2, len);
1141	l += len;
1142
1143	if (p_replay > UINT8_MAX) {
1144		len = sizeof(struct sadb_x_sa_replay);
1145		m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len);
1146		m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY;
1147		m_replay.sadb_x_sa_replay_replay = p_replay << 3;
1148
1149		memcpy(buf + l, &m_replay, len);
1150		l += len;
1151	}
1152
1153	if (p_natt_type != 0) {
1154		len = sizeof(m_natt_type);
1155		memset(&m_natt_type, 0, sizeof(m_natt_type));
1156		m_natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1157		m_natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1158		m_natt_type.sadb_x_nat_t_type_type = p_natt_type;
1159		memcpy(buf + l, &m_natt_type, len);
1160		l += len;
1161
1162		memset(&m_addr, 0, sizeof(m_addr));
1163		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAI;
1164		sa = p_natt_oai->ai_addr;
1165		salen = p_natt_oai->ai_addr->sa_len;
1166		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1167		    PFKEY_ALIGN8(salen));
1168		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oai);
1169		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1170		    sizeof(m_addr), (caddr_t)sa, salen);
1171
1172		len = sizeof(m_natt_port);
1173		memset(&m_natt_port, 0, sizeof(m_natt_port));
1174		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1175		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
1176		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_sport);
1177		memcpy(buf + l, &m_natt_port, len);
1178		l += len;
1179
1180		memset(&m_addr, 0, sizeof(m_addr));
1181		m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OAR;
1182		sa = p_natt_oar->ai_addr;
1183		salen = p_natt_oar->ai_addr->sa_len;
1184		m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1185		    PFKEY_ALIGN8(salen));
1186		m_addr.sadb_address_prefixlen = setkeymsg_plen(p_natt_oar);
1187		setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1188		    sizeof(m_addr), (caddr_t)sa, salen);
1189
1190		len = sizeof(m_natt_port);
1191		memset(&m_natt_port, 0, sizeof(m_natt_port));
1192		m_natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1193		m_natt_port.sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
1194		m_natt_port.sadb_x_nat_t_port_port = htons(p_natt_dport);
1195		memcpy(buf + l, &m_natt_port, len);
1196		l += len;
1197
1198		if (p_natt_fraglen != -1) {
1199			len = sizeof(m_natt_frag);
1200			memset(&m_natt_port, 0, sizeof(m_natt_frag));
1201			m_natt_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
1202			m_natt_frag.sadb_x_nat_t_frag_exttype =
1203			    SADB_X_EXT_NAT_T_FRAG;
1204			m_natt_frag.sadb_x_nat_t_frag_fraglen = p_natt_fraglen;
1205			memcpy(buf + l, &m_natt_frag, len);
1206			l += len;
1207		}
1208	}
1209
1210	l0 = l;
1211	n = 0;
1212
1213	/* do it for all src/dst pairs */
1214	for (s = srcs; s; s = s->ai_next) {
1215		for (d = dsts; d; d = d->ai_next) {
1216			/* rewind pointer */
1217			l = l0;
1218
1219			if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1220				continue;
1221			plen = setkeymsg_plen(s);
1222			if (plen == -1)
1223				continue;
1224
1225			/* set src */
1226			sa = s->ai_addr;
1227			salen = s->ai_addr->sa_len;
1228			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1229			    PFKEY_ALIGN8(salen));
1230			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1231			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1232			m_addr.sadb_address_prefixlen = plen;
1233			m_addr.sadb_address_reserved = 0;
1234
1235			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1236			    sizeof(m_addr), (caddr_t)sa, salen);
1237
1238			/* set dst */
1239			sa = d->ai_addr;
1240			salen = d->ai_addr->sa_len;
1241			m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1242			    PFKEY_ALIGN8(salen));
1243			m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1244			m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1245			m_addr.sadb_address_prefixlen = plen;
1246			m_addr.sadb_address_reserved = 0;
1247
1248			setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1249			    sizeof(m_addr), (caddr_t)sa, salen);
1250
1251			msg->sadb_msg_len = PFKEY_UNIT64(l);
1252
1253			sendkeymsg(buf, l);
1254
1255			n++;
1256		}
1257	}
1258
1259	if (n == 0)
1260		return -1;
1261	else
1262		return 0;
1263}
1264
1265static struct addrinfo *
1266parse_addr(char *host, char *port)
1267{
1268	struct addrinfo hints, *res = NULL;
1269	int error;
1270
1271	memset(&hints, 0, sizeof(hints));
1272	hints.ai_family = p_aifamily;
1273	hints.ai_socktype = SOCK_DGRAM;		/*dummy*/
1274	hints.ai_protocol = IPPROTO_UDP;	/*dummy*/
1275	hints.ai_flags = p_aiflags;
1276	error = getaddrinfo(host, port, &hints, &res);
1277	if (error != 0) {
1278		yyerror(gai_strerror(error));
1279		return NULL;
1280	}
1281	return res;
1282}
1283
1284static int
1285fix_portstr(vchar_t *spec, vchar_t *sport, vchar_t *dport)
1286{
1287	char *p, *p2;
1288	u_int l;
1289
1290	l = 0;
1291	for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++)
1292		;
1293	if (*p == '\0') {
1294		p2 = "0";
1295	} else {
1296		if (*p == ',') {
1297			*p = '\0';
1298			p2 = ++p;
1299		}
1300		for (p = p2; *p != '\0' && l < spec->len; p++, l++)
1301			;
1302		if (*p != '\0' || *p2 == '\0') {
1303			yyerror("invalid an upper layer protocol spec");
1304			return -1;
1305		}
1306	}
1307
1308	sport->buf = strdup(spec->buf);
1309	if (!sport->buf) {
1310		yyerror("insufficient memory");
1311		return -1;
1312	}
1313	sport->len = strlen(sport->buf);
1314	dport->buf = strdup(p2);
1315	if (!dport->buf) {
1316		yyerror("insufficient memory");
1317		return -1;
1318	}
1319	dport->len = strlen(dport->buf);
1320
1321	return 0;
1322}
1323
1324static int
1325setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen, caddr_t vbuf,
1326    int vlen)
1327{
1328	memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1329	memcpy(buf + *off, (caddr_t)ebuf, elen);
1330	memcpy(buf + *off + elen, vbuf, vlen);
1331	(*off) += PFKEY_ALIGN8(elen + vlen);
1332
1333	return 0;
1334}
1335
1336void
1337parse_init(void)
1338{
1339	p_spi = 0;
1340
1341	p_ext = SADB_X_EXT_CYCSEQ;
1342	p_alg_enc = SADB_EALG_NONE;
1343	p_alg_auth = SADB_AALG_NONE;
1344	p_mode = IPSEC_MODE_ANY;
1345	p_reqid = 0;
1346	p_replay = 0;
1347	p_key_enc_len = p_key_auth_len = 0;
1348	p_key_enc = p_key_auth = 0;
1349	p_lt_hard = p_lt_soft = 0;
1350
1351	p_aiflags = 0;
1352	p_aifamily = PF_UNSPEC;
1353
1354	p_natt_type = 0;
1355	p_natt_oai = p_natt_oar = NULL;
1356	p_natt_sport = p_natt_dport = 0;
1357	p_natt_fraglen = -1;
1358}
1359
1360void
1361free_buffer(void)
1362{
1363	/* we got tons of memory leaks in the parser anyways, leave them */
1364}
1365