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