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