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