1 /* $NetBSD: parse.y,v 1.23 2019/07/23 04:30:32 ozaki-r Exp $ */
2 /* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun 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 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41
42 #include <netinet/in.h>
43 #include <net/pfkeyv2.h>
44 #include PATH_IPSEC_H
45 #include <arpa/inet.h>
46
47 #include <string.h>
48 #include <unistd.h>
49 #include <stdio.h>
50 #include <netdb.h>
51 #include <ctype.h>
52 #include <errno.h>
53 #include <stdlib.h>
54
55 #include "libpfkey.h"
56 #include "vchar.h"
57 #include "extern.h"
58
59 #define DEFAULT_NATT_PORT 4500
60
61 #ifndef UDP_ENCAP_ESPINUDP
62 #define UDP_ENCAP_ESPINUDP 2
63 #endif
64
65 #define ATOX(c) \
66 (isdigit((int)c) ? (c - '0') : \
67 (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
68
69 u_int32_t p_spi;
70 u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
71 u_int32_t p_reqid;
72 u_int p_key_enc_len, p_key_auth_len;
73 const char *p_key_enc;
74 const char *p_key_auth;
75 time_t p_lt_hard, p_lt_soft;
76 size_t p_lb_hard, p_lb_soft;
77
78 struct security_ctx {
79 u_int8_t doi;
80 u_int8_t alg;
81 u_int16_t len;
82 char *buf;
83 };
84
85 struct security_ctx sec_ctx;
86
87 static u_int p_natt_type, p_esp_frag;
88 static struct addrinfo * p_natt_oa = NULL;
89
90 static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
91
92 static struct addrinfo *parse_addr(char *, char *);
93 static int fix_portstr(int, vchar_t *, vchar_t *, vchar_t *);
94 static int setvarbuf(char *, int *, struct sadb_ext *, int,
95 const void *, int);
96 void parse_init(void);
97 void free_buffer(void);
98
99 int setkeymsg0(struct sadb_msg *, unsigned int, unsigned int, size_t);
100 static int setkeymsg_spdaddr(unsigned int, unsigned int, vchar_t *,
101 struct addrinfo *, int, struct addrinfo *, int);
102 static int setkeymsg_spdaddr_tag(unsigned int, char *, vchar_t *);
103 static int setkeymsg_addr(unsigned int, unsigned int,
104 struct addrinfo *, struct addrinfo *, int);
105 static int setkeymsg_add(unsigned int, unsigned int,
106 struct addrinfo *, struct addrinfo *);
107 %}
108
109 %union {
110 int num;
111 unsigned long ulnum;
112 vchar_t val;
113 struct addrinfo *res;
114 }
115
116 %token EOT SLASH BLCL ELCL
117 %token ADD UPDATE GET GETSPI DELETE DELETEALL FLUSH DUMP EXIT
118 %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
119 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
120 %token F_MODE MODE F_REQID
121 %token F_EXT EXTENSION NOCYCLICSEQ
122 %token ALG_AUTH ALG_AUTH_NOKEY
123 %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
124 %token ALG_COMP
125 %token F_LIFETIME_HARD F_LIFETIME_SOFT
126 %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
127 %token F_ESPFRAG
128 %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
129 /* SPD management */
130 %token SPDADD SPDUPDATE SPDDELETE SPDDUMP SPDFLUSH
131 %token F_POLICY PL_REQUESTS
132 %token F_AIFLAGS
133 %token TAGGED
134 %token SECURITY_CTX
135
136 %type <num> prefix protocol_spec upper_spec
137 %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
138 %type <num> ALG_AUTH ALG_AUTH_NOKEY
139 %type <num> ALG_COMP
140 %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
141 %type <num> EXTENSION MODE
142 %type <ulnum> DECSTRING
143 %type <val> PL_REQUESTS portstr portstr_notempty key_string
144 %type <val> policy_requests
145 %type <val> QUOTEDSTRING HEXSTRING STRING
146 %type <val> F_AIFLAGS
147 %type <val> upper_misc_spec policy_spec
148 %type <res> ipaddr ipandport
149
150 %%
151 commands
152 : /*NOTHING*/
153 | commands command
154 {
155 free_buffer();
156 parse_init();
157 }
158 ;
159
160 command
161 : add_command
162 | update_command
163 | get_command
164 | getspi_command
165 | delete_command
166 | deleteall_command
167 | flush_command
168 | dump_command
169 | exit_command
170 | spdadd_command
171 | spdupdate_command
172 | spddelete_command
173 | spddump_command
174 | spdflush_command
175 ;
176 /* commands concerned with management, there is in tail of this file. */
177
178 /* add command */
179 add_command
180 : ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
181 {
182 int status;
183
184 status = setkeymsg_add(SADB_ADD, $5, $3, $4);
185 if (status < 0)
186 return -1;
187 }
188 ;
189
190 /* update */
191 update_command
192 : UPDATE ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
193 {
194 int status;
195
196 status = setkeymsg_add(SADB_UPDATE, $5, $3, $4);
197 if (status < 0)
198 return -1;
199 }
200 ;
201
202 /* delete */
203 delete_command
204 : DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
205 {
206 int status;
207
208 if ($3->ai_next || $4->ai_next) {
209 yyerror("multiple address specified");
210 return -1;
211 }
212 if (p_mode != IPSEC_MODE_ANY)
213 yyerror("WARNING: mode is obsolete");
214
215 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
216 if (status < 0)
217 return -1;
218 }
219 ;
220
221 /* deleteall command */
222 deleteall_command
223 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
224 {
225 #ifndef __linux__
226 if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0)
227 return -1;
228 #else /* __linux__ */
229 /* linux strictly adheres to RFC2367, and returns
230 * an error if we send an SADB_DELETE request without
231 * an SPI. Therefore, we must first retrieve a list
232 * of SPIs for all matching SADB entries, and then
233 * delete each one separately. */
234 u_int32_t *spi;
235 int i, n;
236
237 spi = sendkeymsg_spigrep($5, $3, $4, &n);
238 for (i = 0; i < n; i++) {
239 p_spi = spi[i];
240 if (setkeymsg_addr(SADB_DELETE,
241 $5, $3, $4, 0) < 0)
242 return -1;
243 }
244 free(spi);
245 #endif /* __linux__ */
246 }
247 ;
248
249 /* get command */
250 get_command
251 : GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
252 {
253 int status;
254
255 if (p_mode != IPSEC_MODE_ANY)
256 yyerror("WARNING: mode is obsolete");
257
258 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
259 if (status < 0)
260 return -1;
261 }
262 ;
263
264 /* getspi command */
265 getspi_command
266 : GETSPI ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
267 {
268 int status;
269
270 status = setkeymsg_add(SADB_GETSPI, $5, $3, $4);
271 if (status < 0)
272 return -1;
273 }
274
275 /* flush */
276 flush_command
277 : FLUSH protocol_spec EOT
278 {
279 struct sadb_msg msg;
280 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
281 sendkeymsg((char *)&msg, sizeof(msg));
282 }
283 ;
284
285 /* dump */
286 dump_command
287 : DUMP protocol_spec EOT
288 {
289 struct sadb_msg msg;
290 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
291 sendkeymsg((char *)&msg, sizeof(msg));
292 }
293 ;
294
295 protocol_spec
296 : /*NOTHING*/
297 {
298 $$ = SADB_SATYPE_UNSPEC;
299 }
300 | PR_ESP
301 {
302 $$ = SADB_SATYPE_ESP;
303 if ($1 == 1)
304 p_ext |= SADB_X_EXT_OLD;
305 else
306 p_ext &= ~SADB_X_EXT_OLD;
307 }
308 | PR_AH
309 {
310 $$ = SADB_SATYPE_AH;
311 if ($1 == 1)
312 p_ext |= SADB_X_EXT_OLD;
313 else
314 p_ext &= ~SADB_X_EXT_OLD;
315 }
316 | PR_IPCOMP
317 {
318 $$ = SADB_X_SATYPE_IPCOMP;
319 }
320 | PR_ESPUDP
321 {
322 $$ = SADB_SATYPE_ESP;
323 p_ext &= ~SADB_X_EXT_OLD;
324 p_natt_oa = 0;
325 p_natt_type = UDP_ENCAP_ESPINUDP;
326 }
327 | PR_ESPUDP ipaddr
328 {
329 $$ = SADB_SATYPE_ESP;
330 p_ext &= ~SADB_X_EXT_OLD;
331 p_natt_oa = $2;
332 p_natt_type = UDP_ENCAP_ESPINUDP;
333 }
334 | PR_TCP
335 {
336 #ifdef SADB_X_SATYPE_TCPSIGNATURE
337 $$ = SADB_X_SATYPE_TCPSIGNATURE;
338 #endif
339 }
340 ;
341
342 spi
343 : DECSTRING { p_spi = $1; }
344 | HEXSTRING
345 {
346 char *ep;
347 unsigned long v;
348
349 ep = NULL;
350 v = strtoul($1.buf, &ep, 16);
351 if (!ep || *ep) {
352 yyerror("invalid SPI");
353 return -1;
354 }
355 if (v & ~0xffffffff) {
356 yyerror("SPI too big.");
357 return -1;
358 }
359
360 p_spi = v;
361 }
362 ;
363
364 algorithm_spec
365 : esp_spec
366 | ah_spec
367 | ipcomp_spec
368 ;
369
370 esp_spec
371 : F_ENC enc_alg F_AUTH auth_alg
372 | F_ENC enc_alg
373 ;
374
375 ah_spec
376 : F_AUTH auth_alg
377 ;
378
379 ipcomp_spec
380 : F_COMP ALG_COMP
381 {
382 if ($2 < 0) {
383 yyerror("unsupported algorithm");
384 return -1;
385 }
386 p_alg_enc = $2;
387 }
388 | F_COMP ALG_COMP F_RAWCPI
389 {
390 if ($2 < 0) {
391 yyerror("unsupported algorithm");
392 return -1;
393 }
394 p_alg_enc = $2;
395 p_ext |= SADB_X_EXT_RAWCPI;
396 }
397 ;
398
399 enc_alg
400 : ALG_ENC_NOKEY {
401 if ($1 < 0) {
402 yyerror("unsupported algorithm");
403 return -1;
404 }
405 p_alg_enc = $1;
406
407 p_key_enc_len = 0;
408 p_key_enc = "";
409 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
410 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
411 yyerror(ipsec_strerror());
412 return -1;
413 }
414 }
415 | ALG_ENC key_string {
416 if ($1 < 0) {
417 yyerror("unsupported algorithm");
418 return -1;
419 }
420 p_alg_enc = $1;
421
422 p_key_enc_len = $2.len;
423 p_key_enc = $2.buf;
424 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
425 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
426 yyerror(ipsec_strerror());
427 return -1;
428 }
429 }
430 | ALG_ENC_OLD {
431 if ($1 < 0) {
432 yyerror("unsupported algorithm");
433 return -1;
434 }
435 yyerror("WARNING: obsolete algorithm");
436 p_alg_enc = $1;
437
438 p_key_enc_len = 0;
439 p_key_enc = "";
440 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
441 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
442 yyerror(ipsec_strerror());
443 return -1;
444 }
445 }
446 | ALG_ENC_DESDERIV key_string
447 {
448 if ($1 < 0) {
449 yyerror("unsupported algorithm");
450 return -1;
451 }
452 p_alg_enc = $1;
453 if (p_ext & SADB_X_EXT_OLD) {
454 yyerror("algorithm mismatched");
455 return -1;
456 }
457 p_ext |= SADB_X_EXT_DERIV;
458
459 p_key_enc_len = $2.len;
460 p_key_enc = $2.buf;
461 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
462 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
463 yyerror(ipsec_strerror());
464 return -1;
465 }
466 }
467 | ALG_ENC_DES32IV key_string
468 {
469 if ($1 < 0) {
470 yyerror("unsupported algorithm");
471 return -1;
472 }
473 p_alg_enc = $1;
474 if (!(p_ext & SADB_X_EXT_OLD)) {
475 yyerror("algorithm mismatched");
476 return -1;
477 }
478 p_ext |= SADB_X_EXT_IV4B;
479
480 p_key_enc_len = $2.len;
481 p_key_enc = $2.buf;
482 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
483 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
484 yyerror(ipsec_strerror());
485 return -1;
486 }
487 }
488 ;
489
490 auth_alg
491 : ALG_AUTH key_string {
492 if ($1 < 0) {
493 yyerror("unsupported algorithm");
494 return -1;
495 }
496 p_alg_auth = $1;
497
498 p_key_auth_len = $2.len;
499 p_key_auth = $2.buf;
500 #ifdef SADB_X_AALG_TCP_MD5
501 if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
502 if ((p_key_auth_len < 1) ||
503 (p_key_auth_len > 80))
504 return -1;
505 } else
506 #endif
507 {
508 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
509 p_alg_auth,
510 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
511 yyerror(ipsec_strerror());
512 return -1;
513 }
514 }
515 }
516 | ALG_AUTH_NOKEY {
517 if ($1 < 0) {
518 yyerror("unsupported algorithm");
519 return -1;
520 }
521 p_alg_auth = $1;
522
523 p_key_auth_len = 0;
524 p_key_auth = "";
525 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
526 p_alg_auth,
527 PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
528 yyerror(ipsec_strerror());
529 return -1;
530 }
531 }
532 ;
533
534 key_string
535 : QUOTEDSTRING
536 {
537 $$ = $1;
538 }
539 | HEXSTRING
540 {
541 caddr_t pp_key;
542 caddr_t bp;
543 caddr_t yp = $1.buf;
544 int l;
545
546 l = strlen(yp) % 2 + strlen(yp) / 2;
547 if ((pp_key = malloc(l)) == 0) {
548 yyerror("not enough core");
549 return -1;
550 }
551 memset(pp_key, 0, l);
552
553 bp = pp_key;
554 if (strlen(yp) % 2) {
555 *bp = ATOX(yp[0]);
556 yp++, bp++;
557 }
558 while (*yp) {
559 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
560 yp += 2, bp++;
561 }
562
563 $$.len = l;
564 $$.buf = pp_key;
565 }
566 ;
567
568 extension_spec
569 : /*NOTHING*/
570 | extension_spec extension
571 ;
572
573 extension
574 : F_EXT EXTENSION { p_ext |= $2; }
575 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
576 | F_MODE MODE { p_mode = $2; }
577 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
578 | F_REQID DECSTRING { p_reqid = $2; }
579 | F_ESPFRAG DECSTRING
580 {
581 if (p_natt_type == 0) {
582 yyerror("esp fragment size only valid for NAT-T");
583 return -1;
584 }
585 p_esp_frag = $2;
586 }
587 | F_REPLAY DECSTRING
588 {
589 if ((p_ext & SADB_X_EXT_OLD) != 0) {
590 yyerror("replay prevention cannot be used with "
591 "ah/esp-old");
592 return -1;
593 }
594 p_replay = $2;
595 }
596 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
597 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
598 | F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
599 | F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
600 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
601 sec_ctx.doi = $2;
602 sec_ctx.alg = $3;
603 sec_ctx.len = $4.len+1;
604 sec_ctx.buf = $4.buf;
605 }
606 ;
607
608 /* definition about command for SPD management */
609 /* spdadd */
610 spdadd_command
611 /* XXX merge with spdupdate ??? */
612 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
613 {
614 int status;
615 struct addrinfo *src, *dst;
616
617 #ifdef HAVE_PFKEY_POLICY_PRIORITY
618 last_msg_type = SADB_X_SPDADD;
619 #endif
620
621 /* fixed port fields if ulp is icmp */
622 if (fix_portstr($9, &$10, &$5, &$8))
623 return -1;
624
625 src = parse_addr($3.buf, $5.buf);
626 dst = parse_addr($6.buf, $8.buf);
627 if (!src || !dst) {
628 /* yyerror is already called */
629 return -1;
630 }
631 if (src->ai_next || dst->ai_next) {
632 yyerror("multiple address specified");
633 freeaddrinfo(src);
634 freeaddrinfo(dst);
635 return -1;
636 }
637
638 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
639 src, $4, dst, $7);
640 freeaddrinfo(src);
641 freeaddrinfo(dst);
642 if (status < 0)
643 return -1;
644 }
645 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT
646 {
647 int status;
648
649 status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
650 $3.buf, &$4);
651 if (status < 0)
652 return -1;
653 }
654 ;
655
656 spdupdate_command
657 /* XXX merge with spdadd ??? */
658 : SPDUPDATE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
659 {
660 int status;
661 struct addrinfo *src, *dst;
662
663 #ifdef HAVE_PFKEY_POLICY_PRIORITY
664 last_msg_type = SADB_X_SPDUPDATE;
665 #endif
666
667 /* fixed port fields if ulp is icmp */
668 if (fix_portstr($9, &$10, &$5, &$8))
669 return -1;
670
671 src = parse_addr($3.buf, $5.buf);
672 dst = parse_addr($6.buf, $8.buf);
673 if (!src || !dst) {
674 /* yyerror is already called */
675 return -1;
676 }
677 if (src->ai_next || dst->ai_next) {
678 yyerror("multiple address specified");
679 freeaddrinfo(src);
680 freeaddrinfo(dst);
681 return -1;
682 }
683
684 status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, $9, &$12,
685 src, $4, dst, $7);
686 freeaddrinfo(src);
687 freeaddrinfo(dst);
688 if (status < 0)
689 return -1;
690 }
691 | SPDUPDATE TAGGED QUOTEDSTRING policy_spec EOT
692 {
693 int status;
694
695 status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE,
696 $3.buf, &$4);
697 if (status < 0)
698 return -1;
699 }
700 ;
701
702 spddelete_command
703 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
704 {
705 int status;
706 struct addrinfo *src, *dst;
707
708 /* fixed port fields if ulp is icmp */
709 if (fix_portstr($9, &$10, &$5, &$8))
710 return -1;
711
712 src = parse_addr($3.buf, $5.buf);
713 dst = parse_addr($6.buf, $8.buf);
714 if (!src || !dst) {
715 /* yyerror is already called */
716 return -1;
717 }
718 if (src->ai_next || dst->ai_next) {
719 yyerror("multiple address specified");
720 freeaddrinfo(src);
721 freeaddrinfo(dst);
722 return -1;
723 }
724
725 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
726 src, $4, dst, $7);
727 freeaddrinfo(src);
728 freeaddrinfo(dst);
729 if (status < 0)
730 return -1;
731 }
732 ;
733
734 spddump_command:
735 SPDDUMP EOT
736 {
737 struct sadb_msg msg;
738 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
739 sizeof(msg));
740 sendkeymsg((char *)&msg, sizeof(msg));
741 }
742 ;
743
744 spdflush_command
745 :
746 SPDFLUSH EOT
747 {
748 struct sadb_msg msg;
749 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
750 sizeof(msg));
751 sendkeymsg((char *)&msg, sizeof(msg));
752 }
753 ;
754
755 ipaddropts
756 : /* nothing */
757 | ipaddropts ipaddropt
758 ;
759
760 ipaddropt
761 : F_AIFLAGS
762 {
763 char *p;
764
765 for (p = $1.buf + 1; *p; p++)
766 switch (*p) {
767 case '4':
768 p_aifamily = AF_INET;
769 break;
770 #ifdef INET6
771 case '6':
772 p_aifamily = AF_INET6;
773 break;
774 #endif
775 case 'n':
776 p_aiflags = AI_NUMERICHOST;
777 break;
778 default:
779 yyerror("invalid flag");
780 return -1;
781 }
782 }
783 ;
784
785 ipaddr
786 : STRING
787 {
788 $$ = parse_addr($1.buf, NULL);
789 if ($$ == NULL) {
790 /* yyerror already called by parse_addr */
791 return -1;
792 }
793 }
794 ;
795
796 ipandport
797 : STRING
798 {
799 $$ = parse_addr($1.buf, NULL);
800 if ($$ == NULL) {
801 /* yyerror already called by parse_addr */
802 return -1;
803 }
804 }
805 | STRING portstr_notempty
806 {
807 $$ = parse_addr($1.buf, $2.buf);
808 if ($$ == NULL) {
809 /* yyerror already called by parse_addr */
810 return -1;
811 }
812 }
813 ;
814
815 prefix
816 : /*NOTHING*/ { $$ = -1; }
817 | SLASH DECSTRING { $$ = $2; }
818 ;
819
820 portstr
821 : /*NOTHING*/
822 {
823 $$.buf = strdup("0");
824 if (!$$.buf) {
825 yyerror("insufficient memory");
826 return -1;
827 }
828 $$.len = strlen($$.buf);
829 }
830 | portstr_notempty
831 ;
832
833 portstr_notempty
834 : BLCL ANY ELCL
835 {
836 $$.buf = strdup("0");
837 if (!$$.buf) {
838 yyerror("insufficient memory");
839 return -1;
840 }
841 $$.len = strlen($$.buf);
842 }
843 | BLCL DECSTRING ELCL
844 {
845 char buf[20];
846 snprintf(buf, sizeof(buf), "%lu", $2);
847 $$.buf = strdup(buf);
848 if (!$$.buf) {
849 yyerror("insufficient memory");
850 return -1;
851 }
852 $$.len = strlen($$.buf);
853 }
854 | BLCL STRING ELCL
855 {
856 $$ = $2;
857 }
858 ;
859
860 upper_spec
861 : DECSTRING { $$ = $1; }
862 | ANY { $$ = IPSEC_ULPROTO_ANY; }
863 | PR_TCP {
864 $$ = IPPROTO_TCP;
865 }
866 | STRING
867 {
868 struct protoent *ent;
869
870 ent = getprotobyname($1.buf);
871 if (ent)
872 $$ = ent->p_proto;
873 else {
874 if (strcmp("icmp6", $1.buf) == 0) {
875 $$ = IPPROTO_ICMPV6;
876 } else if(strcmp("ip4", $1.buf) == 0) {
877 $$ = IPPROTO_IPV4;
878 } else {
879 yyerror("invalid upper layer protocol");
880 return -1;
881 }
882 }
883 endprotoent();
884 }
885 ;
886
887 upper_misc_spec
888 : /*NOTHING*/
889 {
890 $$.buf = NULL;
891 $$.len = 0;
892 }
893 | STRING
894 {
895 $$.buf = strdup($1.buf);
896 if (!$$.buf) {
897 yyerror("insufficient memory");
898 return -1;
899 }
900 $$.len = strlen($$.buf);
901 }
902 ;
903
904 context_spec
905 : /* NOTHING */
906 | SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
907 sec_ctx.doi = $2;
908 sec_ctx.alg = $3;
909 sec_ctx.len = $4.len+1;
910 sec_ctx.buf = $4.buf;
911 }
912 ;
913
914 policy_spec
915 : F_POLICY policy_requests
916 {
917 char *policy;
918 #ifdef HAVE_PFKEY_POLICY_PRIORITY
919 struct sadb_x_policy *xpl;
920 #endif
921
922 policy = ipsec_set_policy($2.buf, $2.len);
923 if (policy == NULL) {
924 yyerror(ipsec_strerror());
925 return -1;
926 }
927
928 $$.buf = policy;
929 $$.len = ipsec_get_policylen(policy);
930
931 #ifdef HAVE_PFKEY_POLICY_PRIORITY
932 xpl = (struct sadb_x_policy *) $$.buf;
933 last_priority = xpl->sadb_x_policy_priority;
934 #endif
935 }
936 ;
937
938 policy_requests
939 : PL_REQUESTS { $$ = $1; }
940 ;
941
942 /* exit */
943 exit_command
944 : EXIT EOT
945 {
946 exit_now = 1;
947 YYACCEPT;
948 }
949 ;
950 %%
951
952 int
953 setkeymsg0(struct sadb_msg *msg, unsigned int type, unsigned int satype,
954 size_t l)
955 {
956
957 msg->sadb_msg_version = PF_KEY_V2;
958 msg->sadb_msg_type = type;
959 msg->sadb_msg_errno = 0;
960 msg->sadb_msg_satype = satype;
961 msg->sadb_msg_reserved = 0;
962 msg->sadb_msg_seq = 0;
963 msg->sadb_msg_pid = getpid();
964 msg->sadb_msg_len = PFKEY_UNIT64(l);
965 return 0;
966 }
967
968 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
969 static int
setkeymsg_spdaddr(unsigned int type,unsigned int upper,vchar_t * policy,struct addrinfo * srcs,int splen,struct addrinfo * dsts,int dplen)970 setkeymsg_spdaddr(unsigned int type, unsigned int upper, vchar_t *policy,
971 struct addrinfo *srcs, int splen, struct addrinfo *dsts, int dplen)
972 {
973 struct sadb_msg *msg;
974 char buf[BUFSIZ];
975 int l, l0;
976 struct sadb_address m_addr;
977 struct addrinfo *s, *d;
978 int n;
979 int plen;
980 struct sockaddr *sa;
981 int salen;
982 #ifdef HAVE_POLICY_FWD
983 struct sadb_x_ipsecrequest *ps = NULL;
984 int saved_level, saved_id = 0;
985 #endif
986
987 msg = (struct sadb_msg *)buf;
988
989 if (!srcs || !dsts)
990 return -1;
991
992 /* fix up length afterwards */
993 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
994 l = sizeof(struct sadb_msg);
995
996 memcpy(buf + l, policy->buf, policy->len);
997 l += policy->len;
998
999 l0 = l;
1000 n = 0;
1001
1002 /* do it for all src/dst pairs */
1003 for (s = srcs; s; s = s->ai_next) {
1004 for (d = dsts; d; d = d->ai_next) {
1005 /* rewind pointer */
1006 l = l0;
1007
1008 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1009 continue;
1010 switch (s->ai_addr->sa_family) {
1011 case AF_INET:
1012 plen = sizeof(struct in_addr) << 3;
1013 break;
1014 #ifdef INET6
1015 case AF_INET6:
1016 plen = sizeof(struct in6_addr) << 3;
1017 break;
1018 #endif
1019 default:
1020 continue;
1021 }
1022
1023 /* set src */
1024 sa = s->ai_addr;
1025 salen = sysdep_sa_len(s->ai_addr);
1026 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1027 PFKEY_ALIGN8(salen));
1028 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1029 m_addr.sadb_address_proto = upper;
1030 m_addr.sadb_address_prefixlen =
1031 (splen >= 0 ? splen : plen);
1032 m_addr.sadb_address_reserved = 0;
1033
1034 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1035 sizeof(m_addr), (caddr_t)sa, salen);
1036
1037 /* set dst */
1038 sa = d->ai_addr;
1039 salen = sysdep_sa_len(d->ai_addr);
1040 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1041 PFKEY_ALIGN8(salen));
1042 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1043 m_addr.sadb_address_proto = upper;
1044 m_addr.sadb_address_prefixlen =
1045 (dplen >= 0 ? dplen : plen);
1046 m_addr.sadb_address_reserved = 0;
1047
1048 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1049 sizeof(m_addr), sa, salen);
1050 #ifdef SADB_X_EXT_SEC_CTX
1051 /* Add security context label */
1052 if (sec_ctx.doi) {
1053 struct sadb_x_sec_ctx m_sec_ctx;
1054 u_int slen = sizeof(struct sadb_x_sec_ctx);
1055
1056 memset(&m_sec_ctx, 0, slen);
1057
1058 m_sec_ctx.sadb_x_sec_len =
1059 PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
1060
1061 m_sec_ctx.sadb_x_sec_exttype =
1062 SADB_X_EXT_SEC_CTX;
1063 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
1064 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1065 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1066 setvarbuf(buf, &l,
1067 (struct sadb_ext *)&m_sec_ctx, slen,
1068 (caddr_t)sec_ctx.buf, sec_ctx.len);
1069 }
1070 #endif
1071 msg->sadb_msg_len = PFKEY_UNIT64(l);
1072
1073 sendkeymsg(buf, l);
1074
1075 #ifdef HAVE_POLICY_FWD
1076 /* create extra call for FWD policy */
1077 if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
1078 sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
1079 ps = (struct sadb_x_ipsecrequest*) (sp+1);
1080
1081 /* if request level is unique, change it to
1082 * require for fwd policy */
1083 /* XXX: currently, only first policy is updated
1084 * only. Update following too... */
1085 saved_level = ps->sadb_x_ipsecrequest_level;
1086 if (saved_level == IPSEC_LEVEL_UNIQUE) {
1087 saved_id = ps->sadb_x_ipsecrequest_reqid;
1088 ps->sadb_x_ipsecrequest_reqid=0;
1089 ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
1090 }
1091
1092 sendkeymsg(buf, l);
1093 /* restoring for next message */
1094 sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
1095 if (saved_level == IPSEC_LEVEL_UNIQUE) {
1096 ps->sadb_x_ipsecrequest_reqid = saved_id;
1097 ps->sadb_x_ipsecrequest_level = saved_level;
1098 }
1099 }
1100 #endif
1101
1102 n++;
1103 }
1104 }
1105
1106 if (n == 0)
1107 return -1;
1108 else
1109 return 0;
1110 }
1111
1112 static int
setkeymsg_spdaddr_tag(unsigned int type,char * tag,vchar_t * policy)1113 setkeymsg_spdaddr_tag(unsigned int type, char *tag, vchar_t *policy)
1114 {
1115 struct sadb_msg *msg;
1116 char buf[BUFSIZ];
1117 int l;
1118 #ifdef SADB_X_EXT_TAG
1119 struct sadb_x_tag m_tag;
1120 #endif
1121
1122 msg = (struct sadb_msg *)buf;
1123
1124 /* fix up length afterwards */
1125 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
1126 l = sizeof(struct sadb_msg);
1127
1128 memcpy(buf + l, policy->buf, policy->len);
1129 l += policy->len;
1130
1131 #ifdef SADB_X_EXT_TAG
1132 memset(&m_tag, 0, sizeof(m_tag));
1133 m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
1134 m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
1135 if (strlcpy(m_tag.sadb_x_tag_name, tag,
1136 sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
1137 return -1;
1138 memcpy(buf + l, &m_tag, sizeof(m_tag));
1139 l += sizeof(m_tag);
1140 #endif
1141
1142 msg->sadb_msg_len = PFKEY_UNIT64(l);
1143
1144 sendkeymsg(buf, l);
1145
1146 return 0;
1147 }
1148
1149 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1150 static int
setkeymsg_addr(unsigned int type,unsigned int satype,struct addrinfo * srcs,struct addrinfo * dsts,int no_spi)1151 setkeymsg_addr(unsigned int type, unsigned int satype, struct addrinfo *srcs,
1152 struct addrinfo *dsts, int no_spi)
1153 {
1154 struct sadb_msg *msg;
1155 char buf[BUFSIZ];
1156 int l, l0, len;
1157 struct sadb_sa m_sa;
1158 struct sadb_x_sa2 m_sa2;
1159 struct sadb_address m_addr;
1160 struct addrinfo *s, *d;
1161 int n;
1162 int plen;
1163 struct sockaddr *sa;
1164 int salen;
1165
1166 msg = (struct sadb_msg *)buf;
1167
1168 if (!srcs || !dsts)
1169 return -1;
1170
1171 /* fix up length afterwards */
1172 setkeymsg0(msg, type, satype, 0);
1173 l = sizeof(struct sadb_msg);
1174
1175 if (!no_spi) {
1176 len = sizeof(struct sadb_sa);
1177 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1178 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1179 m_sa.sadb_sa_spi = htonl(p_spi);
1180 m_sa.sadb_sa_replay = p_replay;
1181 m_sa.sadb_sa_state = 0;
1182 m_sa.sadb_sa_auth = p_alg_auth;
1183 m_sa.sadb_sa_encrypt = p_alg_enc;
1184 m_sa.sadb_sa_flags = p_ext;
1185
1186 memcpy(buf + l, &m_sa, len);
1187 l += len;
1188
1189 len = sizeof(struct sadb_x_sa2);
1190 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1191 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1192 m_sa2.sadb_x_sa2_mode = p_mode;
1193 m_sa2.sadb_x_sa2_reqid = p_reqid;
1194
1195 memcpy(buf + l, &m_sa2, len);
1196 l += len;
1197 }
1198
1199 l0 = l;
1200 n = 0;
1201
1202 /* do it for all src/dst pairs */
1203 for (s = srcs; s; s = s->ai_next) {
1204 for (d = dsts; d; d = d->ai_next) {
1205 /* rewind pointer */
1206 l = l0;
1207
1208 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1209 continue;
1210 switch (s->ai_addr->sa_family) {
1211 case AF_INET:
1212 plen = sizeof(struct in_addr) << 3;
1213 break;
1214 #ifdef INET6
1215 case AF_INET6:
1216 plen = sizeof(struct in6_addr) << 3;
1217 break;
1218 #endif
1219 default:
1220 continue;
1221 }
1222
1223 /* set src */
1224 sa = s->ai_addr;
1225 salen = sysdep_sa_len(s->ai_addr);
1226 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1227 PFKEY_ALIGN8(salen));
1228 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1229 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1230 m_addr.sadb_address_prefixlen = plen;
1231 m_addr.sadb_address_reserved = 0;
1232
1233 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1234 sizeof(m_addr), sa, salen);
1235
1236 /* set dst */
1237 sa = d->ai_addr;
1238 salen = sysdep_sa_len(d->ai_addr);
1239 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1240 PFKEY_ALIGN8(salen));
1241 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1242 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1243 m_addr.sadb_address_prefixlen = plen;
1244 m_addr.sadb_address_reserved = 0;
1245
1246 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1247 sizeof(m_addr), sa, salen);
1248
1249 msg->sadb_msg_len = PFKEY_UNIT64(l);
1250
1251 sendkeymsg(buf, l);
1252
1253 n++;
1254 }
1255 }
1256
1257 if (n == 0)
1258 return -1;
1259 else
1260 return 0;
1261 }
1262
1263 #ifdef SADB_X_EXT_NAT_T_TYPE
get_port(struct addrinfo * addr)1264 static u_int16_t get_port (struct addrinfo *addr)
1265 {
1266 struct sockaddr *s = addr->ai_addr;
1267 u_int16_t port = 0;
1268
1269 switch (s->sa_family) {
1270 case AF_INET:
1271 {
1272 struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
1273 port = ntohs(sin4->sin_port);
1274 break;
1275 }
1276 case AF_INET6:
1277 {
1278 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
1279 port = ntohs(sin6->sin6_port);
1280 break;
1281 }
1282 }
1283
1284 if (port == 0)
1285 port = DEFAULT_NATT_PORT;
1286
1287 return port;
1288 }
1289 #endif
1290
1291 /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
1292 static int
setkeymsg_add(unsigned int type,unsigned int satype,struct addrinfo * srcs,struct addrinfo * dsts)1293 setkeymsg_add(unsigned int type, unsigned int satype, struct addrinfo *srcs,
1294 struct addrinfo *dsts)
1295 {
1296 struct sadb_msg *msg;
1297 char buf[BUFSIZ];
1298 int l, l0, len;
1299 struct sadb_sa m_sa;
1300 struct sadb_x_sa2 m_sa2;
1301 struct sadb_address m_addr;
1302 struct addrinfo *s, *d;
1303 int n;
1304 int plen;
1305 struct sockaddr *sa;
1306 int salen;
1307
1308 msg = (struct sadb_msg *)buf;
1309
1310 if (!srcs || !dsts)
1311 return -1;
1312
1313 /* fix up length afterwards */
1314 setkeymsg0(msg, type, satype, 0);
1315 l = sizeof(struct sadb_msg);
1316
1317 /* set encryption algorithm, if present. */
1318 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
1319 union {
1320 struct sadb_key key;
1321 struct sadb_ext ext;
1322 } m;
1323
1324 m.key.sadb_key_len =
1325 PFKEY_UNIT64(sizeof(m.key)
1326 + PFKEY_ALIGN8(p_key_enc_len));
1327 m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
1328 m.key.sadb_key_bits = p_key_enc_len * 8;
1329 m.key.sadb_key_reserved = 0;
1330
1331 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1332 p_key_enc, p_key_enc_len);
1333 }
1334
1335 /* set authentication algorithm, if present. */
1336 if (p_key_auth) {
1337 union {
1338 struct sadb_key key;
1339 struct sadb_ext ext;
1340 } m;
1341
1342 m.key.sadb_key_len =
1343 PFKEY_UNIT64(sizeof(m.key)
1344 + PFKEY_ALIGN8(p_key_auth_len));
1345 m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
1346 m.key.sadb_key_bits = p_key_auth_len * 8;
1347 m.key.sadb_key_reserved = 0;
1348
1349 setvarbuf(buf, &l, &m.ext, sizeof(m.key),
1350 p_key_auth, p_key_auth_len);
1351 }
1352
1353 /* set lifetime for HARD */
1354 if (p_lt_hard != 0 || p_lb_hard != 0) {
1355 struct sadb_lifetime m_lt;
1356 u_int slen = sizeof(struct sadb_lifetime);
1357
1358 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1359 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
1360 m_lt.sadb_lifetime_allocations = 0;
1361 m_lt.sadb_lifetime_bytes = p_lb_hard;
1362 m_lt.sadb_lifetime_addtime = p_lt_hard;
1363 m_lt.sadb_lifetime_usetime = 0;
1364
1365 memcpy(buf + l, &m_lt, slen);
1366 l += slen;
1367 }
1368
1369 /* set lifetime for SOFT */
1370 if (p_lt_soft != 0 || p_lb_soft != 0) {
1371 struct sadb_lifetime m_lt;
1372 u_int slen = sizeof(struct sadb_lifetime);
1373
1374 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
1375 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
1376 m_lt.sadb_lifetime_allocations = 0;
1377 m_lt.sadb_lifetime_bytes = p_lb_soft;
1378 m_lt.sadb_lifetime_addtime = p_lt_soft;
1379 m_lt.sadb_lifetime_usetime = 0;
1380
1381 memcpy(buf + l, &m_lt, slen);
1382 l += slen;
1383 }
1384
1385 #ifdef SADB_X_EXT_SEC_CTX
1386 /* Add security context label */
1387 if (sec_ctx.doi) {
1388 struct sadb_x_sec_ctx m_sec_ctx;
1389 u_int slen = sizeof(struct sadb_x_sec_ctx);
1390
1391 memset(&m_sec_ctx, 0, slen);
1392
1393 m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
1394 PFKEY_ALIGN8(sec_ctx.len));
1395 m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
1396 m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
1397 m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
1398 m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
1399 setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
1400 (caddr_t)sec_ctx.buf, sec_ctx.len);
1401 }
1402 #endif
1403
1404 /* SPI == 0 allows the kernel to pick a random SPI */
1405 if (type == SADB_GETSPI && p_spi != 0) {
1406 struct sadb_spirange spirange;
1407 u_int slen = sizeof(struct sadb_spirange);
1408
1409 memset(&spirange, 0, sizeof(spirange));
1410 spirange.sadb_spirange_len = PFKEY_UNIT64(slen);
1411 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
1412 spirange.sadb_spirange_min = p_spi;
1413 spirange.sadb_spirange_max = p_spi;
1414
1415 memcpy(buf + l, &spirange, slen);
1416 l += slen;
1417 }
1418
1419 len = sizeof(struct sadb_sa);
1420 m_sa.sadb_sa_len = PFKEY_UNIT64(len);
1421 m_sa.sadb_sa_exttype = SADB_EXT_SA;
1422 m_sa.sadb_sa_spi = htonl(p_spi);
1423 m_sa.sadb_sa_replay = p_replay;
1424 m_sa.sadb_sa_state = 0;
1425 m_sa.sadb_sa_auth = p_alg_auth;
1426 m_sa.sadb_sa_encrypt = p_alg_enc;
1427 m_sa.sadb_sa_flags = p_ext;
1428
1429 memcpy(buf + l, &m_sa, len);
1430 l += len;
1431
1432 len = sizeof(struct sadb_x_sa2);
1433 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
1434 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1435 m_sa2.sadb_x_sa2_mode = p_mode;
1436 m_sa2.sadb_x_sa2_reqid = p_reqid;
1437
1438 memcpy(buf + l, &m_sa2, len);
1439 l += len;
1440
1441 #ifdef SADB_X_EXT_NAT_T_TYPE
1442 if (p_natt_type) {
1443 struct sadb_x_nat_t_type natt_type;
1444
1445 len = sizeof(struct sadb_x_nat_t_type);
1446 memset(&natt_type, 0, len);
1447 natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
1448 natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
1449 natt_type.sadb_x_nat_t_type_type = p_natt_type;
1450
1451 memcpy(buf + l, &natt_type, len);
1452 l += len;
1453
1454 if (p_natt_oa) {
1455 sa = p_natt_oa->ai_addr;
1456 switch (sa->sa_family) {
1457 case AF_INET:
1458 plen = sizeof(struct in_addr) << 3;
1459 break;
1460 #ifdef INET6
1461 case AF_INET6:
1462 plen = sizeof(struct in6_addr) << 3;
1463 break;
1464 #endif
1465 default:
1466 return -1;
1467 }
1468 salen = sysdep_sa_len(sa);
1469 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1470 PFKEY_ALIGN8(salen));
1471 m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
1472 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1473 m_addr.sadb_address_prefixlen = plen;
1474 m_addr.sadb_address_reserved = 0;
1475
1476 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1477 sizeof(m_addr), sa, salen);
1478 }
1479 }
1480 #endif
1481
1482 l0 = l;
1483 n = 0;
1484
1485 /* do it for all src/dst pairs */
1486 for (s = srcs; s; s = s->ai_next) {
1487 for (d = dsts; d; d = d->ai_next) {
1488 /* rewind pointer */
1489 l = l0;
1490
1491 if (s->ai_addr->sa_family != d->ai_addr->sa_family)
1492 continue;
1493 switch (s->ai_addr->sa_family) {
1494 case AF_INET:
1495 plen = sizeof(struct in_addr) << 3;
1496 break;
1497 #ifdef INET6
1498 case AF_INET6:
1499 plen = sizeof(struct in6_addr) << 3;
1500 break;
1501 #endif
1502 default:
1503 continue;
1504 }
1505
1506 /* set src */
1507 sa = s->ai_addr;
1508 salen = sysdep_sa_len(s->ai_addr);
1509 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1510 PFKEY_ALIGN8(salen));
1511 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
1512 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1513 m_addr.sadb_address_prefixlen = plen;
1514 m_addr.sadb_address_reserved = 0;
1515
1516 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1517 sizeof(m_addr), sa, salen);
1518
1519 /* set dst */
1520 sa = d->ai_addr;
1521 salen = sysdep_sa_len(d->ai_addr);
1522 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
1523 PFKEY_ALIGN8(salen));
1524 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
1525 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
1526 m_addr.sadb_address_prefixlen = plen;
1527 m_addr.sadb_address_reserved = 0;
1528
1529 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
1530 sizeof(m_addr), sa, salen);
1531
1532 #ifdef SADB_X_EXT_NAT_T_TYPE
1533 if (p_natt_type) {
1534 struct sadb_x_nat_t_port natt_port;
1535
1536 /* NATT_SPORT */
1537 len = sizeof(struct sadb_x_nat_t_port);
1538 memset(&natt_port, 0, len);
1539 natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
1540 natt_port.sadb_x_nat_t_port_exttype =
1541 SADB_X_EXT_NAT_T_SPORT;
1542 natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
1543
1544 memcpy(buf + l, &natt_port, len);
1545 l += len;
1546
1547 /* NATT_DPORT */
1548 natt_port.sadb_x_nat_t_port_exttype =
1549 SADB_X_EXT_NAT_T_DPORT;
1550 natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
1551
1552 memcpy(buf + l, &natt_port, len);
1553 l += len;
1554 #ifdef SADB_X_EXT_NAT_T_FRAG
1555 if (p_esp_frag) {
1556 struct sadb_x_nat_t_frag esp_frag;
1557
1558 /* NATT_FRAG */
1559 len = sizeof(struct sadb_x_nat_t_frag);
1560 memset(&esp_frag, 0, len);
1561 esp_frag.sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
1562 esp_frag.sadb_x_nat_t_frag_exttype =
1563 SADB_X_EXT_NAT_T_FRAG;
1564 esp_frag.sadb_x_nat_t_frag_fraglen = p_esp_frag;
1565
1566 memcpy(buf + l, &esp_frag, len);
1567 l += len;
1568 }
1569 #endif
1570 }
1571 #endif
1572 msg->sadb_msg_len = PFKEY_UNIT64(l);
1573
1574 sendkeymsg(buf, l);
1575
1576 n++;
1577 }
1578 }
1579
1580 if (n == 0)
1581 return -1;
1582 else
1583 return 0;
1584 }
1585
1586 static struct addrinfo *
parse_addr(char * host,char * port)1587 parse_addr(char *host, char *port)
1588 {
1589 struct addrinfo hints, *res = NULL;
1590 int error;
1591
1592 memset(&hints, 0, sizeof(hints));
1593 hints.ai_family = p_aifamily;
1594 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
1595 hints.ai_protocol = IPPROTO_UDP; /*dummy*/
1596 hints.ai_flags = p_aiflags;
1597 error = getaddrinfo(host, port, &hints, &res);
1598 if (error != 0) {
1599 yyerror(gai_strerror(error));
1600 return NULL;
1601 }
1602 return res;
1603 }
1604
1605 static int
fix_portstr(int ulproto,vchar_t * spec,vchar_t * sport,vchar_t * dport)1606 fix_portstr(int ulproto, vchar_t *spec, vchar_t *sport, vchar_t *dport)
1607 {
1608 char sp[16], dp[16];
1609 int a, b, c, d;
1610 unsigned long u;
1611
1612 if (spec->buf == NULL)
1613 return 0;
1614
1615 switch (ulproto) {
1616 case IPPROTO_ICMP:
1617 case IPPROTO_ICMPV6:
1618 case IPPROTO_MH:
1619 if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) {
1620 sprintf(sp, "%d", a);
1621 sprintf(dp, "%d", b);
1622 } else if (sscanf(spec->buf, "%d", &a) == 1) {
1623 sprintf(sp, "%d", a);
1624 } else {
1625 yyerror("invalid an upper layer protocol spec");
1626 return -1;
1627 }
1628 break;
1629 case IPPROTO_GRE:
1630 if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) {
1631 sprintf(sp, "%d", (a << 8) + b);
1632 sprintf(dp, "%d", (c << 8) + d);
1633 } else if (sscanf(spec->buf, "%lu", &u) == 1) {
1634 sprintf(sp, "%d", (int) (u >> 16));
1635 sprintf(dp, "%d", (int) (u & 0xffff));
1636 } else {
1637 yyerror("invalid an upper layer protocol spec");
1638 return -1;
1639 }
1640 break;
1641 }
1642
1643 free(sport->buf);
1644 sport->buf = strdup(sp);
1645 if (!sport->buf) {
1646 yyerror("insufficient memory");
1647 return -1;
1648 }
1649 sport->len = strlen(sport->buf);
1650
1651 free(dport->buf);
1652 dport->buf = strdup(dp);
1653 if (!dport->buf) {
1654 yyerror("insufficient memory");
1655 return -1;
1656 }
1657 dport->len = strlen(dport->buf);
1658
1659 return 0;
1660 }
1661
1662 static int
setvarbuf(char * buf,int * off,struct sadb_ext * ebuf,int elen,const void * vbuf,int vlen)1663 setvarbuf(char *buf, int *off, struct sadb_ext *ebuf, int elen,
1664 const void *vbuf, int vlen)
1665 {
1666 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
1667 memcpy(buf + *off, (caddr_t)ebuf, elen);
1668 memcpy(buf + *off + elen, vbuf, vlen);
1669 (*off) += PFKEY_ALIGN8(elen + vlen);
1670
1671 return 0;
1672 }
1673
1674 void
parse_init(void)1675 parse_init(void)
1676 {
1677 p_spi = 0;
1678
1679 p_ext = SADB_X_EXT_CYCSEQ;
1680 p_alg_enc = SADB_EALG_NONE;
1681 p_alg_auth = SADB_AALG_NONE;
1682 p_mode = IPSEC_MODE_ANY;
1683 p_reqid = 0;
1684 p_replay = 0;
1685 p_key_enc_len = p_key_auth_len = 0;
1686 p_key_enc = p_key_auth = 0;
1687 p_lt_hard = p_lt_soft = 0;
1688 p_lb_hard = p_lb_soft = 0;
1689
1690 memset(&sec_ctx, 0, sizeof(struct security_ctx));
1691
1692 p_aiflags = 0;
1693 p_aifamily = PF_UNSPEC;
1694
1695 /* Clear out any natt OA information */
1696 if (p_natt_oa)
1697 freeaddrinfo (p_natt_oa);
1698 p_natt_oa = NULL;
1699 p_natt_type = 0;
1700 p_esp_frag = 0;
1701
1702 return;
1703 }
1704
1705 void
free_buffer(void)1706 free_buffer(void)
1707 {
1708 /* we got tons of memory leaks in the parser anyways, leave them */
1709
1710 return;
1711 }
1712