jcs's openbsd hax
openbsd
1/* $OpenBSD: parse.y,v 1.184 2025/04/30 03:54:09 tb Exp $ */
2
3/*
4 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
5 * Copyright (c) 2001 Markus Friedl. All rights reserved.
6 * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
7 * Copyright (c) 2001 Theo de Raadt. All rights reserved.
8 * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
9 *
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23%{
24#include <sys/types.h>
25#include <sys/ioctl.h>
26#include <sys/queue.h>
27#include <sys/socket.h>
28#include <sys/stat.h>
29#include <net/if.h>
30#include <netinet/in.h>
31#include <netinet/ip_ipsp.h>
32#include <arpa/inet.h>
33
34#include <ctype.h>
35#include <err.h>
36#include <errno.h>
37#include <fcntl.h>
38#include <ifaddrs.h>
39#include <limits.h>
40#include <netdb.h>
41#include <stdarg.h>
42#include <stdio.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
46
47#include "ipsecctl.h"
48
49TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
50static struct file {
51 TAILQ_ENTRY(file) entry;
52 FILE *stream;
53 char *name;
54 int lineno;
55 int errors;
56} *file, *topfile;
57struct file *pushfile(const char *, int);
58int popfile(void);
59int check_file_secrecy(int, const char *);
60int yyparse(void);
61int yylex(void);
62int yyerror(const char *, ...)
63 __attribute__((__format__ (printf, 1, 2)))
64 __attribute__((__nonnull__ (1)));
65int yywarn(const char *, ...)
66 __attribute__((__format__ (printf, 1, 2)))
67 __attribute__((__nonnull__ (1)));
68int kw_cmp(const void *, const void *);
69int lookup(char *);
70int lgetc(int);
71int lungetc(int);
72int findeol(void);
73
74TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
75struct sym {
76 TAILQ_ENTRY(sym) entry;
77 int used;
78 int persist;
79 char *nam;
80 char *val;
81};
82int symset(const char *, const char *, int);
83char *symget(const char *);
84int cmdline_symset(char *);
85
86#define KEYSIZE_LIMIT 1024
87
88static struct ipsecctl *ipsec = NULL;
89static int debug = 0;
90
91const struct ipsec_xf authxfs[] = {
92 { "unknown", AUTHXF_UNKNOWN, 0, 0 },
93 { "none", AUTHXF_NONE, 0, 0 },
94 { "hmac-md5", AUTHXF_HMAC_MD5, 16, 0 },
95 { "hmac-ripemd160", AUTHXF_HMAC_RIPEMD160, 20, 0 },
96 { "hmac-sha1", AUTHXF_HMAC_SHA1, 20, 0 },
97 { "hmac-sha2-256", AUTHXF_HMAC_SHA2_256, 32, 0 },
98 { "hmac-sha2-384", AUTHXF_HMAC_SHA2_384, 48, 0 },
99 { "hmac-sha2-512", AUTHXF_HMAC_SHA2_512, 64, 0 },
100 { NULL, 0, 0, 0 },
101};
102
103const struct ipsec_xf encxfs[] = {
104 { "unknown", ENCXF_UNKNOWN, 0, 0, 0, 0 },
105 { "none", ENCXF_NONE, 0, 0, 0, 0 },
106 { "3des-cbc", ENCXF_3DES_CBC, 24, 24, 0, 0 },
107 { "aes", ENCXF_AES, 16, 32, 0, 0 },
108 { "aes-128", ENCXF_AES_128, 16, 16, 0, 0 },
109 { "aes-192", ENCXF_AES_192, 24, 24, 0, 0 },
110 { "aes-256", ENCXF_AES_256, 32, 32, 0, 0 },
111 { "aesctr", ENCXF_AESCTR, 16+4, 32+4, 0, 1 },
112 { "aes-128-ctr", ENCXF_AES_128_CTR, 16+4, 16+4, 0, 1 },
113 { "aes-192-ctr", ENCXF_AES_192_CTR, 24+4, 24+4, 0, 1 },
114 { "aes-256-ctr", ENCXF_AES_256_CTR, 32+4, 32+4, 0, 1 },
115 { "aes-128-gcm", ENCXF_AES_128_GCM, 16+4, 16+4, 1, 1 },
116 { "aes-192-gcm", ENCXF_AES_192_GCM, 24+4, 24+4, 1, 1 },
117 { "aes-256-gcm", ENCXF_AES_256_GCM, 32+4, 32+4, 1, 1 },
118 { "aes-128-gmac", ENCXF_AES_128_GMAC, 16+4, 16+4, 1, 1 },
119 { "aes-192-gmac", ENCXF_AES_192_GMAC, 24+4, 24+4, 1, 1 },
120 { "aes-256-gmac", ENCXF_AES_256_GMAC, 32+4, 32+4, 1, 1 },
121 { "blowfish", ENCXF_BLOWFISH, 5, 56, 0, 0 },
122 { "cast128", ENCXF_CAST128, 5, 16, 0, 0 },
123 { "chacha20-poly1305", ENCXF_CHACHA20_POLY1305, 32+4, 32+4, 1, 1 },
124 { "null", ENCXF_NULL, 0, 0, 0, 0 },
125 { NULL, 0, 0, 0, 0, 0 },
126};
127
128const struct ipsec_xf compxfs[] = {
129 { "unknown", COMPXF_UNKNOWN, 0, 0 },
130 { "deflate", COMPXF_DEFLATE, 0, 0 },
131 { NULL, 0, 0, 0 },
132};
133
134const struct ipsec_xf groupxfs[] = {
135 { "unknown", GROUPXF_UNKNOWN, 0, 0 },
136 { "none", GROUPXF_NONE, 0, 0 },
137 { "modp768", GROUPXF_1, 768, 0 },
138 { "grp1", GROUPXF_1, 768, 0 },
139 { "modp1024", GROUPXF_2, 1024, 0 },
140 { "grp2", GROUPXF_2, 1024, 0 },
141 { "modp1536", GROUPXF_5, 1536, 0 },
142 { "grp5", GROUPXF_5, 1536, 0 },
143 { "modp2048", GROUPXF_14, 2048, 0 },
144 { "grp14", GROUPXF_14, 2048, 0 },
145 { "modp3072", GROUPXF_15, 3072, 0 },
146 { "grp15", GROUPXF_15, 3072, 0 },
147 { "modp4096", GROUPXF_16, 4096, 0 },
148 { "grp16", GROUPXF_16, 4096, 0 },
149 { "modp6144", GROUPXF_17, 6144, 0 },
150 { "grp17", GROUPXF_17, 6144, 0 },
151 { "modp8192", GROUPXF_18, 8192, 0 },
152 { "grp18", GROUPXF_18, 8192, 0 },
153 { "ecp256", GROUPXF_19, 256, 0 },
154 { "grp19", GROUPXF_19, 256, 0 },
155 { "ecp384", GROUPXF_20, 384, 0 },
156 { "grp20", GROUPXF_20, 384, 0 },
157 { "ecp521", GROUPXF_21, 521, 0 },
158 { "grp21", GROUPXF_21, 521, 0 },
159 { "ecp224", GROUPXF_26, 224, 0 },
160 { "grp26", GROUPXF_26, 224, 0 },
161 { "bp224", GROUPXF_27, 224, 0 },
162 { "grp27", GROUPXF_27, 224, 0 },
163 { "bp256", GROUPXF_28, 256, 0 },
164 { "grp28", GROUPXF_28, 256, 0 },
165 { "bp384", GROUPXF_29, 384, 0 },
166 { "grp29", GROUPXF_29, 384, 0 },
167 { "bp512", GROUPXF_30, 512, 0 },
168 { "grp30", GROUPXF_30, 512, 0 },
169 { NULL, 0, 0, 0 },
170};
171
172int atoul(char *, u_long *);
173int atospi(char *, u_int32_t *);
174u_int8_t x2i(unsigned char *);
175struct ipsec_key *parsekey(unsigned char *, size_t);
176struct ipsec_key *parsekeyfile(char *);
177struct ipsec_addr_wrap *host(const char *);
178struct ipsec_addr_wrap *host_v6(const char *, int);
179struct ipsec_addr_wrap *host_v4(const char *, int);
180struct ipsec_addr_wrap *host_dns(const char *, int);
181struct ipsec_addr_wrap *host_if(const char *, int);
182struct ipsec_addr_wrap *host_any(void);
183void ifa_load(void);
184int ifa_exists(const char *);
185struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name);
186struct ipsec_addr_wrap *ifa_grouplookup(const char *);
187void set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
188const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *);
189struct ipsec_lifetime *parse_life(const char *);
190struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
191struct ipsec_lifetime *copylife(const struct ipsec_lifetime *);
192struct ipsec_auth *copyipsecauth(const struct ipsec_auth *);
193struct ike_auth *copyikeauth(const struct ike_auth *);
194struct ipsec_key *copykey(struct ipsec_key *);
195struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *);
196char *copytag(const char *);
197struct ipsec_rule *copyrule(struct ipsec_rule *);
198int validate_af(struct ipsec_addr_wrap *,
199 struct ipsec_addr_wrap *);
200int validate_sa(u_int32_t, u_int8_t,
201 struct ipsec_transforms *, struct ipsec_key *,
202 struct ipsec_key *, u_int8_t);
203struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *,
204 u_int32_t, u_int8_t, u_int16_t,
205 struct ipsec_transforms *,
206 struct ipsec_key *, struct ipsec_key *);
207struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t,
208 struct ipsec_key *, struct ipsec_key *);
209struct ipsec_rule *create_sabundle(struct ipsec_addr_wrap *, u_int8_t,
210 u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
211 u_int32_t);
212struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
213 u_int8_t, char *, char *, u_int8_t);
214int set_rule_peers(struct ipsec_rule *r,
215 struct ipsec_hosts *peers);
216void expand_any(struct ipsec_addr_wrap *);
217int expand_rule(struct ipsec_rule *, struct ipsec_hosts *,
218 u_int8_t, u_int32_t, struct ipsec_key *,
219 struct ipsec_key *, char *);
220struct ipsec_rule *reverse_rule(struct ipsec_rule *);
221struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *,
222 struct ike_mode *, struct ike_mode *, u_int8_t,
223 u_int8_t, u_int8_t, char *, char *,
224 struct ike_auth *, char *);
225int add_sabundle(struct ipsec_rule *, char *);
226int get_id_type(char *);
227
228struct ipsec_transforms *ipsec_transforms;
229
230typedef struct {
231 union {
232 int64_t number;
233 uint32_t unit;
234 u_int8_t ikemode;
235 u_int8_t dir;
236 u_int8_t satype; /* encapsulating prococol */
237 u_int8_t proto; /* encapsulated protocol */
238 u_int8_t tmode;
239 char *string;
240 u_int16_t port;
241 struct ipsec_hosts hosts;
242 struct ipsec_hosts peers;
243 struct ipsec_addr_wrap *anyhost;
244 struct ipsec_addr_wrap *singlehost;
245 struct ipsec_addr_wrap *host;
246 struct {
247 char *srcid;
248 char *dstid;
249 } ids;
250 char *id;
251 u_int8_t type;
252 struct ike_auth ikeauth;
253 struct {
254 u_int32_t spiout;
255 u_int32_t spiin;
256 } spis;
257 struct {
258 u_int8_t encap;
259 u_int16_t port;
260 } udpencap;
261 struct {
262 struct ipsec_key *keyout;
263 struct ipsec_key *keyin;
264 } authkeys;
265 struct {
266 struct ipsec_key *keyout;
267 struct ipsec_key *keyin;
268 } enckeys;
269 struct {
270 struct ipsec_key *keyout;
271 struct ipsec_key *keyin;
272 } keys;
273 struct ipsec_transforms *transforms;
274 struct ipsec_lifetime *life;
275 struct ike_mode *mode;
276 } v;
277 int lineno;
278} YYSTYPE;
279
280%}
281
282%token FLOW FROM ESP AH IN PEER ON OUT TO SRCID DSTID RSA PSK TCPMD5 SPI
283%token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE
284%token PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFETIME
285%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG
286%token INCLUDE BUNDLE UDPENCAP INTERFACE
287%token <v.string> STRING
288%token <v.number> NUMBER
289%type <v.unit> iface
290%type <v.string> string
291%type <v.dir> dir
292%type <v.satype> satype
293%type <v.proto> proto
294%type <v.number> protoval
295%type <v.tmode> tmode
296%type <v.hosts> hosts
297%type <v.port> port
298%type <v.number> portval
299%type <v.peers> peers
300%type <v.anyhost> anyhost
301%type <v.singlehost> singlehost
302%type <v.host> host host_list host_spec
303%type <v.ids> ids
304%type <v.id> id
305%type <v.spis> spispec
306%type <v.udpencap> udpencap
307%type <v.authkeys> authkeyspec
308%type <v.enckeys> enckeyspec
309%type <v.string> bundlestring
310%type <v.keys> keyspec
311%type <v.transforms> transforms
312%type <v.ikemode> ikemode
313%type <v.ikeauth> ikeauth
314%type <v.type> type
315%type <v.life> lifetime
316%type <v.mode> phase1mode phase2mode
317%type <v.string> tag
318%%
319
320grammar : /* empty */
321 | grammar include '\n'
322 | grammar '\n'
323 | grammar ikerule '\n'
324 | grammar flowrule '\n'
325 | grammar sarule '\n'
326 | grammar tcpmd5rule '\n'
327 | grammar varset '\n'
328 | grammar error '\n' { file->errors++; }
329 ;
330
331comma : ','
332 | /* empty */
333 ;
334
335include : INCLUDE STRING {
336 struct file *nfile;
337
338 if ((nfile = pushfile($2, 0)) == NULL) {
339 yyerror("failed to include file %s", $2);
340 free($2);
341 YYERROR;
342 }
343 free($2);
344
345 file = nfile;
346 lungetc('\n');
347 }
348 ;
349
350tcpmd5rule : TCPMD5 hosts spispec authkeyspec {
351 struct ipsec_rule *r;
352
353 r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2,
354 $3.spiout, 0, 0, NULL, $4.keyout, NULL);
355 if (r == NULL)
356 YYERROR;
357
358 if (expand_rule(r, NULL, 0, $3.spiin, $4.keyin, NULL,
359 NULL))
360 errx(1, "tcpmd5rule: expand_rule");
361 }
362 ;
363
364sarule : satype tmode hosts spispec udpencap transforms authkeyspec
365 enckeyspec bundlestring {
366 struct ipsec_rule *r;
367
368 r = create_sa($1, $2, &$3, $4.spiout, $5.encap, $5.port,
369 $6, $7.keyout, $8.keyout);
370 if (r == NULL)
371 YYERROR;
372
373 if (expand_rule(r, NULL, 0, $4.spiin, $7.keyin,
374 $8.keyin, $9))
375 errx(1, "sarule: expand_rule");
376 }
377 ;
378
379flowrule : FLOW satype dir proto hosts peers ids type {
380 struct ipsec_rule *r;
381
382 r = create_flow($3, $4, &$5, $2, $7.srcid,
383 $7.dstid, $8);
384 if (r == NULL)
385 YYERROR;
386
387 if (expand_rule(r, &$6, $3, 0, NULL, NULL, NULL))
388 errx(1, "flowrule: expand_rule");
389 }
390 ;
391
392ikerule : IKE ikemode satype tmode proto hosts peers
393 phase1mode phase2mode ids ikeauth tag {
394 struct ipsec_rule *r;
395
396 r = create_ike($5, &$6, $8, $9, $3, $4, $2,
397 $10.srcid, $10.dstid, &$11, $12);
398 if (r == NULL)
399 YYERROR;
400
401 if (expand_rule(r, &$7, 0, 0, NULL, NULL, NULL))
402 errx(1, "ikerule: expand_rule");
403 }
404
405 /* ike interface sec0 local $h_self peer $h_s2s1 ... */
406 | IKE ikemode iface peers
407 phase1mode phase2mode ids ikeauth {
408 uint8_t proto = 0; // IPPROTO_IPIP;
409 struct ipsec_hosts hosts;
410 struct ike_mode *phase1mode = $5;
411 struct ike_mode *phase2mode = $6;
412 uint8_t satype = IPSEC_ESP;
413 uint8_t tmode = IPSEC_TUNNEL;
414 uint8_t mode = $2;
415 struct ike_auth *authtype = &$8;
416 char *tag = NULL;
417
418 struct ipsec_rule *r;
419
420 hosts.src = host_v4("0.0.0.0/0", 1);
421 hosts.sport = htons(0);
422 hosts.dst = host_v4("0.0.0.0/0", 1);
423 hosts.dport = htons(0);
424
425 r = create_ike(proto, &hosts, phase1mode, phase2mode,
426 satype, tmode, mode, $7.srcid, $7.dstid,
427 authtype, tag);
428 if (r == NULL) {
429 YYERROR;
430 }
431
432 r->flags |= IPSEC_RULE_F_IFACE;
433 r->iface = $3;
434
435 if (expand_rule(r, &$4, 0, 0, NULL, NULL, NULL))
436 errx(1, "ikerule: expand interface rule");
437
438 }
439 ;
440
441satype : /* empty */ { $$ = IPSEC_ESP; }
442 | ESP { $$ = IPSEC_ESP; }
443 | AH { $$ = IPSEC_AH; }
444 | IPCOMP { $$ = IPSEC_IPCOMP; }
445 | IPIP { $$ = IPSEC_IPIP; }
446 ;
447
448proto : /* empty */ { $$ = 0; }
449 | PROTO protoval { $$ = $2; }
450 | PROTO ESP { $$ = IPPROTO_ESP; }
451 | PROTO AH { $$ = IPPROTO_AH; }
452 ;
453
454protoval : STRING {
455 struct protoent *p;
456
457 p = getprotobyname($1);
458 if (p == NULL) {
459 yyerror("unknown protocol: %s", $1);
460 YYERROR;
461 }
462 $$ = p->p_proto;
463 free($1);
464 }
465 | NUMBER {
466 if ($1 > 255 || $1 < 0) {
467 yyerror("protocol outside range");
468 YYERROR;
469 }
470 }
471 ;
472
473tmode : /* empty */ { $$ = IPSEC_TUNNEL; }
474 | TUNNEL { $$ = IPSEC_TUNNEL; }
475 | TRANSPORT { $$ = IPSEC_TRANSPORT; }
476 ;
477
478dir : /* empty */ { $$ = IPSEC_INOUT; }
479 | IN { $$ = IPSEC_IN; }
480 | OUT { $$ = IPSEC_OUT; }
481 ;
482
483hosts : FROM host port TO host port {
484 struct ipsec_addr_wrap *ipa;
485 for (ipa = $5; ipa; ipa = ipa->next) {
486 if (ipa->srcnat) {
487 yyerror("no flow NAT support for"
488 " destination network: %s", ipa->name);
489 YYERROR;
490 }
491 }
492 $$.src = $2;
493 $$.sport = $3;
494 $$.dst = $5;
495 $$.dport = $6;
496 }
497 | TO host port FROM host port {
498 struct ipsec_addr_wrap *ipa;
499 for (ipa = $2; ipa; ipa = ipa->next) {
500 if (ipa->srcnat) {
501 yyerror("no flow NAT support for"
502 " destination network: %s", ipa->name);
503 YYERROR;
504 }
505 }
506 $$.src = $5;
507 $$.sport = $6;
508 $$.dst = $2;
509 $$.dport = $3;
510 }
511 ;
512
513port : /* empty */ { $$ = 0; }
514 | PORT portval { $$ = $2; }
515 ;
516
517portval : STRING {
518 struct servent *s;
519
520 if ((s = getservbyname($1, "tcp")) != NULL ||
521 (s = getservbyname($1, "udp")) != NULL) {
522 $$ = s->s_port;
523 } else {
524 yyerror("unknown port: %s", $1);
525 YYERROR;
526 }
527 }
528 | NUMBER {
529 if ($1 > USHRT_MAX || $1 < 0) {
530 yyerror("port outside range");
531 YYERROR;
532 }
533 $$ = htons($1);
534 }
535 ;
536
537peers : /* empty */ {
538 $$.dst = NULL;
539 $$.src = NULL;
540 }
541 | PEER anyhost LOCAL singlehost {
542 $$.dst = $2;
543 $$.src = $4;
544 }
545 | LOCAL singlehost PEER anyhost {
546 $$.dst = $4;
547 $$.src = $2;
548 }
549 | PEER anyhost {
550 $$.dst = $2;
551 $$.src = NULL;
552 }
553 | LOCAL singlehost {
554 $$.dst = NULL;
555 $$.src = $2;
556 }
557 ;
558
559anyhost : singlehost { $$ = $1; }
560 | ANY {
561 $$ = host_any();
562 }
563
564singlehost : /* empty */ { $$ = NULL; }
565 | STRING {
566 if (($$ = host($1)) == NULL) {
567 free($1);
568 yyerror("could not parse host specification");
569 YYERROR;
570 }
571 free($1);
572 }
573 ;
574
575host_list : host { $$ = $1; }
576 | host_list comma host {
577 if ($3 == NULL)
578 $$ = $1;
579 else if ($1 == NULL)
580 $$ = $3;
581 else {
582 $1->tail->next = $3;
583 $1->tail = $3->tail;
584 $$ = $1;
585 }
586 }
587 ;
588
589host_spec : STRING {
590 if (($$ = host($1)) == NULL) {
591 free($1);
592 yyerror("could not parse host specification");
593 YYERROR;
594 }
595 free($1);
596 }
597 | STRING '/' NUMBER {
598 char *buf;
599
600 if (asprintf(&buf, "%s/%lld", $1, $3) == -1)
601 err(1, "host: asprintf");
602 free($1);
603 if (($$ = host(buf)) == NULL) {
604 free(buf);
605 yyerror("could not parse host specification");
606 YYERROR;
607 }
608 free(buf);
609 }
610 ;
611
612host : host_spec { $$ = $1; }
613 | host_spec '(' host_spec ')' {
614 if ($3->af != $1->af) {
615 yyerror("Flow NAT address family mismatch");
616 YYERROR;
617 }
618 $$ = $1;
619 $$->srcnat = $3;
620 }
621 | ANY {
622 $$ = host_any();
623 }
624 | '{' host_list '}' { $$ = $2; }
625 ;
626
627ids : /* empty */ {
628 $$.srcid = NULL;
629 $$.dstid = NULL;
630 }
631 | SRCID id DSTID id {
632 $$.srcid = $2;
633 $$.dstid = $4;
634 }
635 | SRCID id {
636 $$.srcid = $2;
637 $$.dstid = NULL;
638 }
639 | DSTID id {
640 $$.srcid = NULL;
641 $$.dstid = $2;
642 }
643 ;
644
645type : /* empty */ {
646 $$ = TYPE_UNKNOWN;
647 }
648 | TYPE USE {
649 $$ = TYPE_USE;
650 }
651 | TYPE ACQUIRE {
652 $$ = TYPE_ACQUIRE;
653 }
654 | TYPE REQUIRE {
655 $$ = TYPE_REQUIRE;
656 }
657 | TYPE DENY {
658 $$ = TYPE_DENY;
659 }
660 | TYPE BYPASS {
661 $$ = TYPE_BYPASS;
662 }
663 | TYPE DONTACQ {
664 $$ = TYPE_DONTACQ;
665 }
666 ;
667
668id : STRING { $$ = $1; }
669 ;
670
671spispec : SPI STRING {
672 u_int32_t spi;
673 char *p = strchr($2, ':');
674
675 if (p != NULL) {
676 *p++ = 0;
677
678 if (atospi(p, &spi) == -1) {
679 free($2);
680 YYERROR;
681 }
682 $$.spiin = spi;
683 } else
684 $$.spiin = 0;
685
686 if (atospi($2, &spi) == -1) {
687 free($2);
688 YYERROR;
689 }
690 $$.spiout = spi;
691
692
693 free($2);
694 }
695 | SPI NUMBER {
696 if ($2 > UINT_MAX || $2 < 0) {
697 yyerror("%lld not a valid spi", $2);
698 YYERROR;
699 }
700 if ($2 >= SPI_RESERVED_MIN && $2 <= SPI_RESERVED_MAX) {
701 yyerror("%lld within reserved spi range", $2);
702 YYERROR;
703 }
704
705 $$.spiin = 0;
706 $$.spiout = $2;
707 }
708 ;
709
710udpencap : /* empty */ {
711 $$.encap = 0;
712 }
713 | UDPENCAP {
714 $$.encap = 1;
715 $$.port = 0;
716 }
717 | UDPENCAP PORT NUMBER {
718 $$.encap = 1;
719 $$.port = $3;
720 }
721 ;
722
723transforms : {
724 if ((ipsec_transforms = calloc(1,
725 sizeof(struct ipsec_transforms))) == NULL)
726 err(1, "transforms: calloc");
727 }
728 transforms_l
729 { $$ = ipsec_transforms; }
730 | /* empty */ {
731 if (($$ = calloc(1,
732 sizeof(struct ipsec_transforms))) == NULL)
733 err(1, "transforms: calloc");
734 }
735 ;
736
737transforms_l : transforms_l transform
738 | transform
739 ;
740
741transform : AUTHXF STRING {
742 if (ipsec_transforms->authxf)
743 yyerror("auth already set");
744 else {
745 ipsec_transforms->authxf = parse_xf($2,
746 authxfs);
747 if (!ipsec_transforms->authxf)
748 yyerror("%s not a valid transform", $2);
749 }
750 }
751 | ENCXF STRING {
752 if (ipsec_transforms->encxf)
753 yyerror("enc already set");
754 else {
755 ipsec_transforms->encxf = parse_xf($2, encxfs);
756 if (!ipsec_transforms->encxf)
757 yyerror("%s not a valid transform", $2);
758 }
759 }
760 | COMPXF STRING {
761 if (ipsec_transforms->compxf)
762 yyerror("comp already set");
763 else {
764 ipsec_transforms->compxf = parse_xf($2,
765 compxfs);
766 if (!ipsec_transforms->compxf)
767 yyerror("%s not a valid transform", $2);
768 }
769 }
770 | GROUP STRING {
771 if (ipsec_transforms->groupxf)
772 yyerror("group already set");
773 else {
774 ipsec_transforms->groupxf = parse_xf($2,
775 groupxfs);
776 if (!ipsec_transforms->groupxf)
777 yyerror("%s not a valid transform", $2);
778 }
779 }
780 ;
781
782phase1mode : /* empty */ {
783 struct ike_mode *p1;
784
785 /* We create just an empty main mode */
786 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
787 err(1, "phase1mode: calloc");
788 p1->ike_exch = IKE_MM;
789 $$ = p1;
790 }
791 | MAIN transforms lifetime {
792 struct ike_mode *p1;
793
794 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
795 err(1, "phase1mode: calloc");
796 p1->xfs = $2;
797 p1->life = $3;
798 p1->ike_exch = IKE_MM;
799 $$ = p1;
800 }
801 | AGGRESSIVE transforms lifetime {
802 struct ike_mode *p1;
803
804 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL)
805 err(1, "phase1mode: calloc");
806 p1->xfs = $2;
807 p1->life = $3;
808 p1->ike_exch = IKE_AM;
809 $$ = p1;
810 }
811 ;
812
813phase2mode : /* empty */ {
814 struct ike_mode *p2;
815
816 /* We create just an empty quick mode */
817 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
818 err(1, "phase2mode: calloc");
819 p2->ike_exch = IKE_QM;
820 $$ = p2;
821 }
822 | QUICK transforms lifetime {
823 struct ike_mode *p2;
824
825 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL)
826 err(1, "phase2mode: calloc");
827 p2->xfs = $2;
828 p2->life = $3;
829 p2->ike_exch = IKE_QM;
830 $$ = p2;
831 }
832 ;
833
834lifetime : /* empty */ {
835 struct ipsec_lifetime *life;
836
837 /* We create just an empty transform */
838 if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
839 == NULL)
840 err(1, "life: calloc");
841 life->lt_seconds = -1;
842 life->lt_bytes = -1;
843 $$ = life;
844 }
845 | LIFETIME NUMBER {
846 struct ipsec_lifetime *life;
847
848 if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
849 == NULL)
850 err(1, "life: calloc");
851 life->lt_seconds = $2;
852 life->lt_bytes = -1;
853 $$ = life;
854 }
855 | LIFETIME STRING {
856 $$ = parse_life($2);
857 }
858 ;
859
860authkeyspec : /* empty */ {
861 $$.keyout = NULL;
862 $$.keyin = NULL;
863 }
864 | AUTHKEY keyspec {
865 $$.keyout = $2.keyout;
866 $$.keyin = $2.keyin;
867 }
868 ;
869
870enckeyspec : /* empty */ {
871 $$.keyout = NULL;
872 $$.keyin = NULL;
873 }
874 | ENCKEY keyspec {
875 $$.keyout = $2.keyout;
876 $$.keyin = $2.keyin;
877 }
878 ;
879
880bundlestring : /* empty */ { $$ = NULL; }
881 | BUNDLE STRING { $$ = $2; }
882 ;
883
884keyspec : STRING {
885 unsigned char *hex;
886 unsigned char *p = strchr($1, ':');
887
888 if (p != NULL ) {
889 *p++ = 0;
890
891 if (!strncmp(p, "0x", 2))
892 p += 2;
893 $$.keyin = parsekey(p, strlen(p));
894 } else
895 $$.keyin = NULL;
896
897 hex = $1;
898 if (!strncmp(hex, "0x", 2))
899 hex += 2;
900 $$.keyout = parsekey(hex, strlen(hex));
901
902 free($1);
903 }
904 | FILENAME STRING {
905 unsigned char *p = strchr($2, ':');
906
907 if (p != NULL) {
908 *p++ = 0;
909 $$.keyin = parsekeyfile(p);
910 }
911 $$.keyout = parsekeyfile($2);
912 free($2);
913 }
914 ;
915
916ikemode : /* empty */ { $$ = IKE_ACTIVE; }
917 | PASSIVE { $$ = IKE_PASSIVE; }
918 | DYNAMIC { $$ = IKE_DYNAMIC; }
919 | ACTIVE { $$ = IKE_ACTIVE; }
920 ;
921
922ikeauth : /* empty */ {
923 $$.type = IKE_AUTH_RSA;
924 $$.string = NULL;
925 }
926 | RSA {
927 $$.type = IKE_AUTH_RSA;
928 $$.string = NULL;
929 }
930 | PSK STRING {
931 $$.type = IKE_AUTH_PSK;
932 if (($$.string = strdup($2)) == NULL)
933 err(1, "ikeauth: strdup");
934 }
935 ;
936
937tag : /* empty */
938 {
939 $$ = NULL;
940 }
941 | TAG STRING
942 {
943 $$ = $2;
944 }
945 ;
946
947iface : INTERFACE STRING {
948 static const char prefix[] = "sec";
949 const char *errstr = NULL;
950 size_t len, plen;
951
952 plen = strlen(prefix);
953 len = strlen($2);
954
955 if (len <= plen || memcmp($2, prefix, plen) != 0) {
956 yyerror("invalid %s interface name", prefix);
957 free($2);
958 YYERROR;
959 }
960
961 $$ = strtonum($2 + plen, 0, UINT_MAX, &errstr);
962 free($2);
963 if (errstr != NULL) {
964 yyerror("invalid %s interface unit: %s",
965 prefix, errstr);
966 YYERROR;
967 }
968 }
969 ;
970
971string : string STRING
972 {
973 if (asprintf(&$$, "%s %s", $1, $2) == -1)
974 err(1, "string: asprintf");
975 free($1);
976 free($2);
977 }
978 | STRING
979 ;
980
981varset : STRING '=' string
982 {
983 char *s = $1;
984 if (ipsec->opts & IPSECCTL_OPT_VERBOSE)
985 printf("%s = \"%s\"\n", $1, $3);
986 while (*s++) {
987 if (isspace((unsigned char)*s)) {
988 yyerror("macro name cannot contain "
989 "whitespace");
990 free($1);
991 free($3);
992 YYERROR;
993 }
994 }
995 if (symset($1, $3, 0) == -1)
996 err(1, "cannot store variable");
997 free($1);
998 free($3);
999 }
1000 ;
1001
1002%%
1003
1004struct keywords {
1005 const char *k_name;
1006 int k_val;
1007};
1008
1009int
1010yyerror(const char *fmt, ...)
1011{
1012 va_list ap;
1013
1014 file->errors++;
1015 va_start(ap, fmt);
1016 fprintf(stderr, "%s: %d: ", file->name, yylval.lineno);
1017 vfprintf(stderr, fmt, ap);
1018 fprintf(stderr, "\n");
1019 va_end(ap);
1020 return (0);
1021}
1022
1023int
1024yywarn(const char *fmt, ...)
1025{
1026 va_list ap;
1027
1028 va_start(ap, fmt);
1029 fprintf(stderr, "%s: %d: ", file->name, yylval.lineno);
1030 vfprintf(stderr, fmt, ap);
1031 fprintf(stderr, "\n");
1032 va_end(ap);
1033 return (0);
1034}
1035
1036int
1037kw_cmp(const void *k, const void *e)
1038{
1039 return (strcmp(k, ((const struct keywords *)e)->k_name));
1040}
1041
1042int
1043lookup(char *s)
1044{
1045 /* this has to be sorted always */
1046 static const struct keywords keywords[] = {
1047 { "acquire", ACQUIRE },
1048 { "active", ACTIVE },
1049 { "aggressive", AGGRESSIVE },
1050 { "ah", AH },
1051 { "any", ANY },
1052 { "auth", AUTHXF },
1053 { "authkey", AUTHKEY },
1054 { "bundle", BUNDLE },
1055 { "bypass", BYPASS },
1056 { "comp", COMPXF },
1057 { "deny", DENY },
1058 { "dontacq", DONTACQ },
1059 { "dstid", DSTID },
1060 { "dynamic", DYNAMIC },
1061 { "enc", ENCXF },
1062 { "enckey", ENCKEY },
1063 { "esp", ESP },
1064 { "file", FILENAME },
1065 { "flow", FLOW },
1066 { "from", FROM },
1067 { "group", GROUP },
1068 { "ike", IKE },
1069 { "in", IN },
1070 { "include", INCLUDE },
1071 { "interface", INTERFACE },
1072 { "ipcomp", IPCOMP },
1073 { "ipip", IPIP },
1074 { "lifetime", LIFETIME },
1075 { "local", LOCAL },
1076 { "main", MAIN },
1077 { "out", OUT },
1078 { "passive", PASSIVE },
1079 { "peer", PEER },
1080 { "port", PORT },
1081 { "proto", PROTO },
1082 { "psk", PSK },
1083 { "quick", QUICK },
1084 { "require", REQUIRE },
1085 { "rsa", RSA },
1086 { "spi", SPI },
1087 { "srcid", SRCID },
1088 { "tag", TAG },
1089 { "tcpmd5", TCPMD5 },
1090 { "to", TO },
1091 { "transport", TRANSPORT },
1092 { "tunnel", TUNNEL },
1093 { "type", TYPE },
1094 { "udpencap", UDPENCAP },
1095 { "use", USE }
1096 };
1097 const struct keywords *p;
1098
1099 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
1100 sizeof(keywords[0]), kw_cmp);
1101
1102 if (p) {
1103 if (debug > 1)
1104 fprintf(stderr, "%s: %d\n", s, p->k_val);
1105 return (p->k_val);
1106 } else {
1107 if (debug > 1)
1108 fprintf(stderr, "string: %s\n", s);
1109 return (STRING);
1110 }
1111}
1112
1113#define MAXPUSHBACK 128
1114
1115char *parsebuf;
1116int parseindex;
1117char pushback_buffer[MAXPUSHBACK];
1118int pushback_index = 0;
1119
1120int
1121lgetc(int quotec)
1122{
1123 int c, next;
1124
1125 if (parsebuf) {
1126 /* Read character from the parsebuffer instead of input. */
1127 if (parseindex >= 0) {
1128 c = (unsigned char)parsebuf[parseindex++];
1129 if (c != '\0')
1130 return (c);
1131 parsebuf = NULL;
1132 } else
1133 parseindex++;
1134 }
1135
1136 if (pushback_index)
1137 return ((unsigned char)pushback_buffer[--pushback_index]);
1138
1139 if (quotec) {
1140 if ((c = getc(file->stream)) == EOF) {
1141 yyerror("reached end of file while parsing quoted string");
1142 if (file == topfile || popfile() == EOF)
1143 return (EOF);
1144 return (quotec);
1145 }
1146 return (c);
1147 }
1148
1149 while ((c = getc(file->stream)) == '\\') {
1150 next = getc(file->stream);
1151 if (next != '\n') {
1152 c = next;
1153 break;
1154 }
1155 yylval.lineno = file->lineno;
1156 file->lineno++;
1157 }
1158
1159 while (c == EOF) {
1160 if (file == topfile || popfile() == EOF)
1161 return (EOF);
1162 c = getc(file->stream);
1163 }
1164 return (c);
1165}
1166
1167int
1168lungetc(int c)
1169{
1170 if (c == EOF)
1171 return (EOF);
1172 if (parsebuf) {
1173 parseindex--;
1174 if (parseindex >= 0)
1175 return (c);
1176 }
1177 if (pushback_index + 1 >= MAXPUSHBACK)
1178 return (EOF);
1179 pushback_buffer[pushback_index++] = c;
1180 return (c);
1181}
1182
1183int
1184findeol(void)
1185{
1186 int c;
1187
1188 parsebuf = NULL;
1189
1190 /* skip to either EOF or the first real EOL */
1191 while (1) {
1192 if (pushback_index)
1193 c = (unsigned char)pushback_buffer[--pushback_index];
1194 else
1195 c = lgetc(0);
1196 if (c == '\n') {
1197 file->lineno++;
1198 break;
1199 }
1200 if (c == EOF)
1201 break;
1202 }
1203 return (ERROR);
1204}
1205
1206int
1207yylex(void)
1208{
1209 char buf[8096];
1210 char *p, *val;
1211 int quotec, next, c;
1212 int token;
1213
1214top:
1215 p = buf;
1216 while ((c = lgetc(0)) == ' ' || c == '\t')
1217 ; /* nothing */
1218
1219 yylval.lineno = file->lineno;
1220 if (c == '#')
1221 while ((c = lgetc(0)) != '\n' && c != EOF)
1222 ; /* nothing */
1223 if (c == '$' && parsebuf == NULL) {
1224 while (1) {
1225 if ((c = lgetc(0)) == EOF)
1226 return (0);
1227
1228 if (p + 1 >= buf + sizeof(buf) - 1) {
1229 yyerror("string too long");
1230 return (findeol());
1231 }
1232 if (isalnum(c) || c == '_') {
1233 *p++ = c;
1234 continue;
1235 }
1236 *p = '\0';
1237 lungetc(c);
1238 break;
1239 }
1240 val = symget(buf);
1241 if (val == NULL) {
1242 yyerror("macro '%s' not defined", buf);
1243 return (findeol());
1244 }
1245 parsebuf = val;
1246 parseindex = 0;
1247 goto top;
1248 }
1249
1250 switch (c) {
1251 case '\'':
1252 case '"':
1253 quotec = c;
1254 while (1) {
1255 if ((c = lgetc(quotec)) == EOF)
1256 return (0);
1257 if (c == '\n') {
1258 file->lineno++;
1259 continue;
1260 } else if (c == '\\') {
1261 if ((next = lgetc(quotec)) == EOF)
1262 return (0);
1263 if (next == quotec || next == ' ' ||
1264 next == '\t')
1265 c = next;
1266 else if (next == '\n') {
1267 file->lineno++;
1268 continue;
1269 } else
1270 lungetc(next);
1271 } else if (c == quotec) {
1272 *p = '\0';
1273 break;
1274 } else if (c == '\0') {
1275 yyerror("syntax error");
1276 return (findeol());
1277 }
1278 if (p + 1 >= buf + sizeof(buf) - 1) {
1279 yyerror("string too long");
1280 return (findeol());
1281 }
1282 *p++ = c;
1283 }
1284 yylval.v.string = strdup(buf);
1285 if (yylval.v.string == NULL)
1286 err(1, "%s", __func__);
1287 return (STRING);
1288 }
1289
1290#define allowed_to_end_number(x) \
1291 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1292
1293 if (c == '-' || isdigit(c)) {
1294 do {
1295 *p++ = c;
1296 if ((size_t)(p-buf) >= sizeof(buf)) {
1297 yyerror("string too long");
1298 return (findeol());
1299 }
1300 } while ((c = lgetc(0)) != EOF && isdigit(c));
1301 lungetc(c);
1302 if (p == buf + 1 && buf[0] == '-')
1303 goto nodigits;
1304 if (c == EOF || allowed_to_end_number(c)) {
1305 const char *errstr = NULL;
1306
1307 *p = '\0';
1308 yylval.v.number = strtonum(buf, LLONG_MIN,
1309 LLONG_MAX, &errstr);
1310 if (errstr) {
1311 yyerror("\"%s\" invalid number: %s",
1312 buf, errstr);
1313 return (findeol());
1314 }
1315 return (NUMBER);
1316 } else {
1317nodigits:
1318 while (p > buf + 1)
1319 lungetc((unsigned char)*--p);
1320 c = (unsigned char)*--p;
1321 if (c == '-')
1322 return (c);
1323 }
1324 }
1325
1326#define allowed_in_string(x) \
1327 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1328 x != '{' && x != '}' && x != '<' && x != '>' && \
1329 x != '!' && x != '=' && x != '/' && x != '#' && \
1330 x != ','))
1331
1332 if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1333 do {
1334 *p++ = c;
1335 if ((size_t)(p-buf) >= sizeof(buf)) {
1336 yyerror("string too long");
1337 return (findeol());
1338 }
1339 } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
1340 lungetc(c);
1341 *p = '\0';
1342 if ((token = lookup(buf)) == STRING)
1343 if ((yylval.v.string = strdup(buf)) == NULL)
1344 err(1, "%s", __func__);
1345 return (token);
1346 }
1347 if (c == '\n') {
1348 yylval.lineno = file->lineno;
1349 file->lineno++;
1350 }
1351 if (c == EOF)
1352 return (0);
1353 return (c);
1354}
1355
1356int
1357check_file_secrecy(int fd, const char *fname)
1358{
1359 struct stat st;
1360
1361 if (fstat(fd, &st)) {
1362 warn("cannot stat %s", fname);
1363 return (-1);
1364 }
1365 if (st.st_uid != 0 && st.st_uid != getuid()) {
1366 warnx("%s: owner not root or current user", fname);
1367 return (-1);
1368 }
1369 if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
1370 warnx("%s: group writable or world read/writable", fname);
1371 return (-1);
1372 }
1373 return (0);
1374}
1375
1376struct file *
1377pushfile(const char *name, int secret)
1378{
1379 struct file *nfile;
1380
1381 if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
1382 warn("%s", __func__);
1383 return (NULL);
1384 }
1385 if ((nfile->name = strdup(name)) == NULL) {
1386 warn("%s", __func__);
1387 free(nfile);
1388 return (NULL);
1389 }
1390 if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
1391 nfile->stream = stdin;
1392 free(nfile->name);
1393 if ((nfile->name = strdup("stdin")) == NULL) {
1394 warn("%s", __func__);
1395 free(nfile);
1396 return (NULL);
1397 }
1398 } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
1399 warn("%s: %s", __func__, nfile->name);
1400 free(nfile->name);
1401 free(nfile);
1402 return (NULL);
1403 } else if (secret &&
1404 check_file_secrecy(fileno(nfile->stream), nfile->name)) {
1405 fclose(nfile->stream);
1406 free(nfile->name);
1407 free(nfile);
1408 return (NULL);
1409 }
1410 nfile->lineno = 1;
1411 TAILQ_INSERT_TAIL(&files, nfile, entry);
1412 return (nfile);
1413}
1414
1415int
1416popfile(void)
1417{
1418 struct file *prev;
1419
1420 if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
1421 prev->errors += file->errors;
1422
1423 TAILQ_REMOVE(&files, file, entry);
1424 fclose(file->stream);
1425 free(file->name);
1426 free(file);
1427 file = prev;
1428
1429 return (file ? 0 : EOF);
1430}
1431
1432int
1433parse_rules(const char *filename, struct ipsecctl *ipsecx)
1434{
1435 struct sym *sym;
1436 int errors = 0;
1437
1438 ipsec = ipsecx;
1439
1440 if ((file = pushfile(filename, 1)) == NULL) {
1441 return (-1);
1442 }
1443 topfile = file;
1444
1445 yyparse();
1446 errors = file->errors;
1447 popfile();
1448
1449 /* Free macros and check which have not been used. */
1450 while ((sym = TAILQ_FIRST(&symhead))) {
1451 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE2) && !sym->used)
1452 fprintf(stderr, "warning: macro '%s' not "
1453 "used\n", sym->nam);
1454 free(sym->nam);
1455 free(sym->val);
1456 TAILQ_REMOVE(&symhead, sym, entry);
1457 free(sym);
1458 }
1459
1460 return (errors ? -1 : 0);
1461}
1462
1463int
1464symset(const char *nam, const char *val, int persist)
1465{
1466 struct sym *sym;
1467
1468 TAILQ_FOREACH(sym, &symhead, entry) {
1469 if (strcmp(nam, sym->nam) == 0)
1470 break;
1471 }
1472
1473 if (sym != NULL) {
1474 if (sym->persist == 1)
1475 return (0);
1476 else {
1477 free(sym->nam);
1478 free(sym->val);
1479 TAILQ_REMOVE(&symhead, sym, entry);
1480 free(sym);
1481 }
1482 }
1483 if ((sym = calloc(1, sizeof(*sym))) == NULL)
1484 return (-1);
1485
1486 sym->nam = strdup(nam);
1487 if (sym->nam == NULL) {
1488 free(sym);
1489 return (-1);
1490 }
1491 sym->val = strdup(val);
1492 if (sym->val == NULL) {
1493 free(sym->nam);
1494 free(sym);
1495 return (-1);
1496 }
1497 sym->used = 0;
1498 sym->persist = persist;
1499 TAILQ_INSERT_TAIL(&symhead, sym, entry);
1500 return (0);
1501}
1502
1503int
1504cmdline_symset(char *s)
1505{
1506 char *sym, *val;
1507 int ret;
1508
1509 if ((val = strrchr(s, '=')) == NULL)
1510 return (-1);
1511
1512 sym = strndup(s, val - s);
1513 if (sym == NULL)
1514 err(1, "%s", __func__);
1515 ret = symset(sym, val + 1, 1);
1516 free(sym);
1517
1518 return (ret);
1519}
1520
1521char *
1522symget(const char *nam)
1523{
1524 struct sym *sym;
1525
1526 TAILQ_FOREACH(sym, &symhead, entry) {
1527 if (strcmp(nam, sym->nam) == 0) {
1528 sym->used = 1;
1529 return (sym->val);
1530 }
1531 }
1532 return (NULL);
1533}
1534
1535int
1536atoul(char *s, u_long *ulvalp)
1537{
1538 u_long ulval;
1539 char *ep;
1540
1541 errno = 0;
1542 ulval = strtoul(s, &ep, 0);
1543 if (s[0] == '\0' || *ep != '\0')
1544 return (-1);
1545 if (errno == ERANGE && ulval == ULONG_MAX)
1546 return (-1);
1547 *ulvalp = ulval;
1548 return (0);
1549}
1550
1551int
1552atospi(char *s, u_int32_t *spivalp)
1553{
1554 unsigned long ulval;
1555
1556 if (atoul(s, &ulval) == -1)
1557 return (-1);
1558 if (ulval > UINT_MAX) {
1559 yyerror("%lu not a valid spi", ulval);
1560 return (-1);
1561 }
1562 if (ulval >= SPI_RESERVED_MIN && ulval <= SPI_RESERVED_MAX) {
1563 yyerror("%lu within reserved spi range", ulval);
1564 return (-1);
1565 }
1566 *spivalp = ulval;
1567 return (0);
1568}
1569
1570u_int8_t
1571x2i(unsigned char *s)
1572{
1573 char ss[3];
1574
1575 ss[0] = s[0];
1576 ss[1] = s[1];
1577 ss[2] = 0;
1578
1579 if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1580 yyerror("keys need to be specified in hex digits");
1581 return (-1);
1582 }
1583 return ((u_int8_t)strtoul(ss, NULL, 16));
1584}
1585
1586struct ipsec_key *
1587parsekey(unsigned char *hexkey, size_t len)
1588{
1589 struct ipsec_key *key;
1590 int i;
1591
1592 key = calloc(1, sizeof(struct ipsec_key));
1593 if (key == NULL)
1594 err(1, "%s", __func__);
1595
1596 key->len = len / 2;
1597 key->data = calloc(key->len, sizeof(u_int8_t));
1598 if (key->data == NULL)
1599 err(1, "%s", __func__);
1600
1601 for (i = 0; i < (int)key->len; i++)
1602 key->data[i] = x2i(hexkey + 2 * i);
1603
1604 return (key);
1605}
1606
1607struct ipsec_key *
1608parsekeyfile(char *filename)
1609{
1610 struct stat sb;
1611 int fd;
1612 unsigned char *hex;
1613
1614 if ((fd = open(filename, O_RDONLY)) < 0)
1615 err(1, "open %s", filename);
1616 if (fstat(fd, &sb) < 0)
1617 err(1, "parsekeyfile: stat %s", filename);
1618 if ((sb.st_size > KEYSIZE_LIMIT) || (sb.st_size == 0))
1619 errx(1, "%s: key too %s", filename, sb.st_size ? "large" :
1620 "small");
1621 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL)
1622 err(1, "%s", __func__);
1623 if (read(fd, hex, sb.st_size) < sb.st_size)
1624 err(1, "parsekeyfile: read");
1625 close(fd);
1626 return (parsekey(hex, sb.st_size));
1627}
1628
1629int
1630get_id_type(char *string)
1631{
1632 struct in6_addr ia;
1633
1634 if (string == NULL)
1635 return (ID_UNKNOWN);
1636
1637 if (inet_pton(AF_INET, string, &ia) == 1)
1638 return (ID_IPV4);
1639 else if (inet_pton(AF_INET6, string, &ia) == 1)
1640 return (ID_IPV6);
1641 else if (strchr(string, '@'))
1642 return (ID_UFQDN);
1643 else
1644 return (ID_FQDN);
1645}
1646
1647struct ipsec_addr_wrap *
1648host(const char *s)
1649{
1650 struct ipsec_addr_wrap *ipa = NULL;
1651 int mask, cont = 1;
1652 char *p, *q, *ps;
1653
1654 if ((p = strrchr(s, '/')) != NULL) {
1655 errno = 0;
1656 mask = strtol(p + 1, &q, 0);
1657 if (errno == ERANGE || !q || *q || mask > 128 || q == (p + 1))
1658 errx(1, "host: invalid netmask '%s'", p);
1659 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL)
1660 err(1, "%s", __func__);
1661 strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1662 } else {
1663 if ((ps = strdup(s)) == NULL)
1664 err(1, "%s", __func__);
1665 mask = -1;
1666 }
1667
1668 /* Does interface with this name exist? */
1669 if (cont && (ipa = host_if(ps, mask)) != NULL)
1670 cont = 0;
1671
1672 /* IPv4 address? */
1673 if (cont && (ipa = host_v4(s, mask == -1 ? 32 : mask)) != NULL)
1674 cont = 0;
1675
1676 /* IPv6 address? */
1677 if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL)
1678 cont = 0;
1679
1680 /* dns lookup */
1681 if (cont && mask == -1 && (ipa = host_dns(s, mask)) != NULL)
1682 cont = 0;
1683 free(ps);
1684
1685 if (ipa == NULL || cont == 1) {
1686 fprintf(stderr, "no IP address found for %s\n", s);
1687 return (NULL);
1688 }
1689 return (ipa);
1690}
1691
1692struct ipsec_addr_wrap *
1693host_v6(const char *s, int prefixlen)
1694{
1695 struct ipsec_addr_wrap *ipa = NULL;
1696 struct addrinfo hints, *res;
1697 char hbuf[NI_MAXHOST];
1698
1699 bzero(&hints, sizeof(struct addrinfo));
1700 hints.ai_family = AF_INET6;
1701 hints.ai_socktype = SOCK_STREAM;
1702 hints.ai_flags = AI_NUMERICHOST;
1703 if (getaddrinfo(s, NULL, &hints, &res))
1704 return (NULL);
1705 if (res->ai_next)
1706 err(1, "host_v6: numeric hostname expanded to multiple item");
1707
1708 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1709 if (ipa == NULL)
1710 err(1, "%s", __func__);
1711 ipa->af = res->ai_family;
1712 memcpy(&ipa->address.v6,
1713 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1714 sizeof(struct in6_addr));
1715 if (prefixlen > 128)
1716 prefixlen = 128;
1717 ipa->next = NULL;
1718 ipa->tail = ipa;
1719
1720 set_ipmask(ipa, prefixlen);
1721 if (getnameinfo(res->ai_addr, res->ai_addrlen,
1722 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST)) {
1723 errx(1, "could not get a numeric hostname");
1724 }
1725
1726 if (prefixlen != 128) {
1727 ipa->netaddress = 1;
1728 if (asprintf(&ipa->name, "%s/%d", hbuf, prefixlen) == -1)
1729 err(1, "%s", __func__);
1730 } else {
1731 if ((ipa->name = strdup(hbuf)) == NULL)
1732 err(1, "%s", __func__);
1733 }
1734
1735 freeaddrinfo(res);
1736
1737 return (ipa);
1738}
1739
1740struct ipsec_addr_wrap *
1741host_v4(const char *s, int mask)
1742{
1743 struct ipsec_addr_wrap *ipa = NULL;
1744 struct in_addr ina;
1745 int bits = 32;
1746
1747 bzero(&ina, sizeof(struct in_addr));
1748 if (strrchr(s, '/') != NULL) {
1749 if ((bits = inet_net_pton(AF_INET, s, &ina, sizeof(ina))) == -1)
1750 return (NULL);
1751 } else {
1752 if (inet_pton(AF_INET, s, &ina) != 1)
1753 return (NULL);
1754 }
1755
1756 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1757 if (ipa == NULL)
1758 err(1, "%s", __func__);
1759
1760 ipa->address.v4 = ina;
1761 ipa->name = strdup(s);
1762 if (ipa->name == NULL)
1763 err(1, "%s", __func__);
1764 ipa->af = AF_INET;
1765 ipa->next = NULL;
1766 ipa->tail = ipa;
1767
1768 set_ipmask(ipa, bits);
1769 if (strrchr(s, '/') != NULL)
1770 ipa->netaddress = 1;
1771
1772 return (ipa);
1773}
1774
1775struct ipsec_addr_wrap *
1776host_dns(const char *s, int mask)
1777{
1778 struct ipsec_addr_wrap *ipa = NULL, *head = NULL;
1779 struct addrinfo hints, *res0, *res;
1780 int error;
1781 char hbuf[NI_MAXHOST];
1782
1783 bzero(&hints, sizeof(struct addrinfo));
1784 hints.ai_family = PF_UNSPEC;
1785 hints.ai_socktype = SOCK_STREAM;
1786 error = getaddrinfo(s, NULL, &hints, &res0);
1787 if (error)
1788 return (NULL);
1789
1790 for (res = res0; res; res = res->ai_next) {
1791 if (res->ai_family != AF_INET && res->ai_family != AF_INET6)
1792 continue;
1793
1794 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1795 if (ipa == NULL)
1796 err(1, "%s", __func__);
1797 switch (res->ai_family) {
1798 case AF_INET:
1799 memcpy(&ipa->address.v4,
1800 &((struct sockaddr_in *)res->ai_addr)->sin_addr,
1801 sizeof(struct in_addr));
1802 break;
1803 case AF_INET6:
1804 /* XXX we do not support scoped IPv6 address yet */
1805 if (((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
1806 free(ipa);
1807 continue;
1808 }
1809 memcpy(&ipa->address.v6,
1810 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1811 sizeof(struct in6_addr));
1812 break;
1813 }
1814 error = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
1815 sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
1816 if (error)
1817 err(1, "host_dns: getnameinfo");
1818 ipa->name = strdup(hbuf);
1819 if (ipa->name == NULL)
1820 err(1, "%s", __func__);
1821 ipa->af = res->ai_family;
1822 ipa->next = NULL;
1823 ipa->tail = ipa;
1824 if (head == NULL)
1825 head = ipa;
1826 else {
1827 head->tail->next = ipa;
1828 head->tail = ipa;
1829 }
1830
1831 /*
1832 * XXX for now, no netmask support for IPv6.
1833 * but since there's no way to specify address family, once you
1834 * have IPv6 address on a host, you cannot use dns/netmask
1835 * syntax.
1836 */
1837 if (ipa->af == AF_INET)
1838 set_ipmask(ipa, mask == -1 ? 32 : mask);
1839 else
1840 if (mask != -1)
1841 err(1, "host_dns: cannot apply netmask "
1842 "on non-IPv4 address");
1843 }
1844 freeaddrinfo(res0);
1845
1846 return (head);
1847}
1848
1849struct ipsec_addr_wrap *
1850host_if(const char *s, int mask)
1851{
1852 struct ipsec_addr_wrap *ipa = NULL;
1853
1854 if (ifa_exists(s))
1855 ipa = ifa_lookup(s);
1856
1857 return (ipa);
1858}
1859
1860struct ipsec_addr_wrap *
1861host_any(void)
1862{
1863 struct ipsec_addr_wrap *ipa;
1864
1865 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1866 if (ipa == NULL)
1867 err(1, "%s", __func__);
1868 ipa->af = AF_UNSPEC;
1869 ipa->netaddress = 1;
1870 ipa->tail = ipa;
1871 return (ipa);
1872}
1873
1874/* interface lookup routintes */
1875
1876struct ipsec_addr_wrap *iftab;
1877
1878void
1879ifa_load(void)
1880{
1881 struct ifaddrs *ifap, *ifa;
1882 struct ipsec_addr_wrap *n = NULL, *h = NULL;
1883
1884 if (getifaddrs(&ifap) < 0)
1885 err(1, "ifa_load: getifaddrs");
1886
1887 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1888 if (ifa->ifa_addr == NULL ||
1889 !(ifa->ifa_addr->sa_family == AF_INET ||
1890 ifa->ifa_addr->sa_family == AF_INET6 ||
1891 ifa->ifa_addr->sa_family == AF_LINK))
1892 continue;
1893 n = calloc(1, sizeof(struct ipsec_addr_wrap));
1894 if (n == NULL)
1895 err(1, "%s", __func__);
1896 n->af = ifa->ifa_addr->sa_family;
1897 if ((n->name = strdup(ifa->ifa_name)) == NULL)
1898 err(1, "%s", __func__);
1899 if (n->af == AF_INET) {
1900 n->af = AF_INET;
1901 memcpy(&n->address.v4, &((struct sockaddr_in *)
1902 ifa->ifa_addr)->sin_addr,
1903 sizeof(struct in_addr));
1904 memcpy(&n->mask.v4, &((struct sockaddr_in *)
1905 ifa->ifa_netmask)->sin_addr,
1906 sizeof(struct in_addr));
1907 } else if (n->af == AF_INET6) {
1908 n->af = AF_INET6;
1909 memcpy(&n->address.v6, &((struct sockaddr_in6 *)
1910 ifa->ifa_addr)->sin6_addr,
1911 sizeof(struct in6_addr));
1912 memcpy(&n->mask.v6, &((struct sockaddr_in6 *)
1913 ifa->ifa_netmask)->sin6_addr,
1914 sizeof(struct in6_addr));
1915 }
1916 n->next = NULL;
1917 n->tail = n;
1918 if (h == NULL)
1919 h = n;
1920 else {
1921 h->tail->next = n;
1922 h->tail = n;
1923 }
1924 }
1925
1926 iftab = h;
1927 freeifaddrs(ifap);
1928}
1929
1930int
1931ifa_exists(const char *ifa_name)
1932{
1933 struct ipsec_addr_wrap *n;
1934 struct ifgroupreq ifgr;
1935 int s;
1936
1937 if (iftab == NULL)
1938 ifa_load();
1939
1940 /* check whether this is a group */
1941 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1942 err(1, "ifa_exists: socket");
1943 bzero(&ifgr, sizeof(ifgr));
1944 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1945 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
1946 close(s);
1947 return (1);
1948 }
1949 close(s);
1950
1951 for (n = iftab; n; n = n->next) {
1952 if (n->af == AF_LINK && !strncmp(n->name, ifa_name,
1953 IFNAMSIZ))
1954 return (1);
1955 }
1956
1957 return (0);
1958}
1959
1960struct ipsec_addr_wrap *
1961ifa_grouplookup(const char *ifa_name)
1962{
1963 struct ifg_req *ifg;
1964 struct ifgroupreq ifgr;
1965 int s;
1966 size_t len;
1967 struct ipsec_addr_wrap *n, *h = NULL, *hn;
1968
1969 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
1970 err(1, "socket");
1971 bzero(&ifgr, sizeof(ifgr));
1972 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1973 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
1974 close(s);
1975 return (NULL);
1976 }
1977
1978 len = ifgr.ifgr_len;
1979 if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
1980 err(1, "%s", __func__);
1981 if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
1982 err(1, "ioctl");
1983
1984 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
1985 ifg++) {
1986 len -= sizeof(struct ifg_req);
1987 if ((n = ifa_lookup(ifg->ifgrq_member)) == NULL)
1988 continue;
1989 if (h == NULL)
1990 h = n;
1991 else {
1992 for (hn = h; hn->next != NULL; hn = hn->next)
1993 ; /* nothing */
1994 hn->next = n;
1995 n->tail = hn;
1996 }
1997 }
1998 free(ifgr.ifgr_groups);
1999 close(s);
2000
2001 return (h);
2002}
2003
2004struct ipsec_addr_wrap *
2005ifa_lookup(const char *ifa_name)
2006{
2007 struct ipsec_addr_wrap *p = NULL, *h = NULL, *n = NULL;
2008
2009 if (iftab == NULL)
2010 ifa_load();
2011
2012 if ((n = ifa_grouplookup(ifa_name)) != NULL)
2013 return (n);
2014
2015 for (p = iftab; p; p = p->next) {
2016 if (p->af != AF_INET && p->af != AF_INET6)
2017 continue;
2018 if (strncmp(p->name, ifa_name, IFNAMSIZ))
2019 continue;
2020 n = calloc(1, sizeof(struct ipsec_addr_wrap));
2021 if (n == NULL)
2022 err(1, "%s", __func__);
2023 memcpy(n, p, sizeof(struct ipsec_addr_wrap));
2024 if ((n->name = strdup(p->name)) == NULL)
2025 err(1, "%s", __func__);
2026 switch (n->af) {
2027 case AF_INET:
2028 set_ipmask(n, 32);
2029 break;
2030 case AF_INET6:
2031 /* route/show.c and bgpd/util.c give KAME credit */
2032 if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6)) {
2033 u_int16_t tmp16;
2034 /* for now we can not handle link local,
2035 * therefore bail for now
2036 */
2037 free(n);
2038 continue;
2039
2040 memcpy(&tmp16, &n->address.v6.s6_addr[2],
2041 sizeof(tmp16));
2042 /* use this when we support link-local
2043 * n->??.scopeid = ntohs(tmp16);
2044 */
2045 n->address.v6.s6_addr[2] = 0;
2046 n->address.v6.s6_addr[3] = 0;
2047 }
2048 set_ipmask(n, 128);
2049 break;
2050 }
2051
2052 n->next = NULL;
2053 n->tail = n;
2054 if (h == NULL)
2055 h = n;
2056 else {
2057 h->tail->next = n;
2058 h->tail = n;
2059 }
2060 }
2061
2062 return (h);
2063}
2064
2065void
2066set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
2067{
2068 struct ipsec_addr *ipa;
2069 int i, j = 0;
2070
2071 ipa = &address->mask;
2072 bzero(ipa, sizeof(struct ipsec_addr));
2073
2074 while (b >= 32) {
2075 ipa->addr32[j++] = 0xffffffff;
2076 b -= 32;
2077 }
2078 for (i = 31; i > 31 - b; --i)
2079 ipa->addr32[j] |= (1 << i);
2080 if (b)
2081 ipa->addr32[j] = htonl(ipa->addr32[j]);
2082}
2083
2084const struct ipsec_xf *
2085parse_xf(const char *name, const struct ipsec_xf xfs[])
2086{
2087 int i;
2088
2089 for (i = 0; xfs[i].name != NULL; i++) {
2090 if (strncmp(name, xfs[i].name, strlen(name)))
2091 continue;
2092 return &xfs[i];
2093 }
2094 return (NULL);
2095}
2096
2097struct ipsec_lifetime *
2098parse_life(const char *value)
2099{
2100 struct ipsec_lifetime *life;
2101 int ret;
2102 int seconds = 0;
2103 char unit = 0;
2104
2105 ret = sscanf(value, "%d%c", &seconds, &unit);
2106 if (ret == 2) {
2107 switch (tolower((unsigned char)unit)) {
2108 case 'm':
2109 seconds *= 60;
2110 break;
2111 case 'h':
2112 seconds *= 60 * 60;
2113 break;
2114 default:
2115 err(1, "invalid time unit");
2116 }
2117 } else if (ret != 1)
2118 err(1, "invalid time specification: %s", value);
2119
2120 life = calloc(1, sizeof(struct ipsec_lifetime));
2121 if (life == NULL)
2122 err(1, "%s", __func__);
2123
2124 life->lt_seconds = seconds;
2125 life->lt_bytes = -1;
2126
2127 return (life);
2128}
2129
2130struct ipsec_transforms *
2131copytransforms(const struct ipsec_transforms *xfs)
2132{
2133 struct ipsec_transforms *newxfs;
2134
2135 if (xfs == NULL)
2136 return (NULL);
2137
2138 newxfs = calloc(1, sizeof(struct ipsec_transforms));
2139 if (newxfs == NULL)
2140 err(1, "%s", __func__);
2141
2142 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
2143 return (newxfs);
2144}
2145
2146struct ipsec_lifetime *
2147copylife(const struct ipsec_lifetime *life)
2148{
2149 struct ipsec_lifetime *newlife;
2150
2151 if (life == NULL)
2152 return (NULL);
2153
2154 newlife = calloc(1, sizeof(struct ipsec_lifetime));
2155 if (newlife == NULL)
2156 err(1, "%s", __func__);
2157
2158 memcpy(newlife, life, sizeof(struct ipsec_lifetime));
2159 return (newlife);
2160}
2161
2162struct ipsec_auth *
2163copyipsecauth(const struct ipsec_auth *auth)
2164{
2165 struct ipsec_auth *newauth;
2166
2167 if (auth == NULL)
2168 return (NULL);
2169
2170 if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL)
2171 err(1, "%s", __func__);
2172 if (auth->srcid &&
2173 asprintf(&newauth->srcid, "%s", auth->srcid) == -1)
2174 err(1, "%s", __func__);
2175 if (auth->dstid &&
2176 asprintf(&newauth->dstid, "%s", auth->dstid) == -1)
2177 err(1, "%s", __func__);
2178
2179 newauth->srcid_type = auth->srcid_type;
2180 newauth->dstid_type = auth->dstid_type;
2181 newauth->type = auth->type;
2182
2183 return (newauth);
2184}
2185
2186struct ike_auth *
2187copyikeauth(const struct ike_auth *auth)
2188{
2189 struct ike_auth *newauth;
2190
2191 if (auth == NULL)
2192 return (NULL);
2193
2194 if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL)
2195 err(1, "%s", __func__);
2196 if (auth->string &&
2197 asprintf(&newauth->string, "%s", auth->string) == -1)
2198 err(1, "%s", __func__);
2199
2200 newauth->type = auth->type;
2201
2202 return (newauth);
2203}
2204
2205struct ipsec_key *
2206copykey(struct ipsec_key *key)
2207{
2208 struct ipsec_key *newkey;
2209
2210 if (key == NULL)
2211 return (NULL);
2212
2213 if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL)
2214 err(1, "%s", __func__);
2215 if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL)
2216 err(1, "%s", __func__);
2217 memcpy(newkey->data, key->data, key->len);
2218 newkey->len = key->len;
2219
2220 return (newkey);
2221}
2222
2223struct ipsec_addr_wrap *
2224copyhost(const struct ipsec_addr_wrap *src)
2225{
2226 struct ipsec_addr_wrap *dst;
2227
2228 if (src == NULL)
2229 return (NULL);
2230
2231 dst = calloc(1, sizeof(struct ipsec_addr_wrap));
2232 if (dst == NULL)
2233 err(1, "%s", __func__);
2234
2235 memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
2236
2237 if (src->name != NULL && (dst->name = strdup(src->name)) == NULL)
2238 err(1, "%s", __func__);
2239
2240 return dst;
2241}
2242
2243char *
2244copytag(const char *src)
2245{
2246 char *tag;
2247
2248 if (src == NULL)
2249 return (NULL);
2250 if ((tag = strdup(src)) == NULL)
2251 err(1, "%s", __func__);
2252
2253 return (tag);
2254}
2255
2256struct ipsec_rule *
2257copyrule(struct ipsec_rule *rule)
2258{
2259 struct ipsec_rule *r;
2260
2261 if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL)
2262 err(1, "%s", __func__);
2263
2264 r->src = copyhost(rule->src);
2265 r->dst = copyhost(rule->dst);
2266 r->local = copyhost(rule->local);
2267 r->peer = copyhost(rule->peer);
2268 r->auth = copyipsecauth(rule->auth);
2269 r->ikeauth = copyikeauth(rule->ikeauth);
2270 r->xfs = copytransforms(rule->xfs);
2271 r->p1xfs = copytransforms(rule->p1xfs);
2272 r->p2xfs = copytransforms(rule->p2xfs);
2273 r->p1life = copylife(rule->p1life);
2274 r->p2life = copylife(rule->p2life);
2275 r->authkey = copykey(rule->authkey);
2276 r->enckey = copykey(rule->enckey);
2277 r->tag = copytag(rule->tag);
2278
2279 r->flags = rule->flags;
2280 r->p1ie = rule->p1ie;
2281 r->p2ie = rule->p2ie;
2282 r->type = rule->type;
2283 r->satype = rule->satype;
2284 r->proto = rule->proto;
2285 r->tmode = rule->tmode;
2286 r->direction = rule->direction;
2287 r->flowtype = rule->flowtype;
2288 r->sport = rule->sport;
2289 r->dport = rule->dport;
2290 r->ikemode = rule->ikemode;
2291 r->spi = rule->spi;
2292 r->udpencap = rule->udpencap;
2293 r->udpdport = rule->udpdport;
2294 r->nr = rule->nr;
2295 r->iface = rule->iface;
2296
2297 return (r);
2298}
2299
2300int
2301validate_af(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst)
2302{
2303 struct ipsec_addr_wrap *ta;
2304 u_int8_t src_v4 = 0;
2305 u_int8_t dst_v4 = 0;
2306 u_int8_t src_v6 = 0;
2307 u_int8_t dst_v6 = 0;
2308
2309 for (ta = src; ta; ta = ta->next) {
2310 if (ta->af == AF_INET)
2311 src_v4 = 1;
2312 if (ta->af == AF_INET6)
2313 src_v6 = 1;
2314 if (ta->af == AF_UNSPEC)
2315 return 0;
2316 if (src_v4 && src_v6)
2317 break;
2318 }
2319 for (ta = dst; ta; ta = ta->next) {
2320 if (ta->af == AF_INET)
2321 dst_v4 = 1;
2322 if (ta->af == AF_INET6)
2323 dst_v6 = 1;
2324 if (ta->af == AF_UNSPEC)
2325 return 0;
2326 if (dst_v4 && dst_v6)
2327 break;
2328 }
2329 if (src_v4 != dst_v4 && src_v6 != dst_v6)
2330 return (1);
2331
2332 return (0);
2333}
2334
2335
2336int
2337validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs,
2338 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
2339{
2340 /* Sanity checks */
2341 if (spi == 0) {
2342 yyerror("no SPI specified");
2343 return (0);
2344 }
2345 if (satype == IPSEC_AH) {
2346 if (!xfs) {
2347 yyerror("no transforms specified");
2348 return (0);
2349 }
2350 if (!xfs->authxf)
2351 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2352 if (xfs->encxf) {
2353 yyerror("ah does not provide encryption");
2354 return (0);
2355 }
2356 if (xfs->compxf) {
2357 yyerror("ah does not provide compression");
2358 return (0);
2359 }
2360 }
2361 if (satype == IPSEC_ESP) {
2362 if (!xfs) {
2363 yyerror("no transforms specified");
2364 return (0);
2365 }
2366 if (xfs->compxf) {
2367 yyerror("esp does not provide compression");
2368 return (0);
2369 }
2370 if (!xfs->encxf)
2371 xfs->encxf = &encxfs[ENCXF_AES];
2372 if (xfs->encxf->nostatic) {
2373 yyerror("%s is disallowed with static keys",
2374 xfs->encxf->name);
2375 return 0;
2376 }
2377 if (xfs->encxf->noauth && xfs->authxf) {
2378 yyerror("authentication is implicit for %s",
2379 xfs->encxf->name);
2380 return (0);
2381 } else if (!xfs->encxf->noauth && !xfs->authxf)
2382 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2383 }
2384 if (satype == IPSEC_IPCOMP) {
2385 if (!xfs) {
2386 yyerror("no transform specified");
2387 return (0);
2388 }
2389 if (xfs->authxf || xfs->encxf) {
2390 yyerror("no encryption or authentication with ipcomp");
2391 return (0);
2392 }
2393 if (!xfs->compxf)
2394 xfs->compxf = &compxfs[COMPXF_DEFLATE];
2395 }
2396 if (satype == IPSEC_IPIP) {
2397 if (!xfs) {
2398 yyerror("no transform specified");
2399 return (0);
2400 }
2401 if (xfs->authxf || xfs->encxf || xfs->compxf) {
2402 yyerror("no encryption, authentication or compression"
2403 " with ipip");
2404 return (0);
2405 }
2406 }
2407 if (satype == IPSEC_TCPMD5 && authkey == NULL && tmode !=
2408 IPSEC_TRANSPORT) {
2409 yyerror("authentication key needed for tcpmd5");
2410 return (0);
2411 }
2412 if (xfs && xfs->authxf) {
2413 if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
2414 yyerror("no authentication key specified");
2415 return (0);
2416 }
2417 if (authkey && authkey->len != xfs->authxf->keymin) {
2418 yyerror("wrong authentication key length, needs to be "
2419 "%zu bits", xfs->authxf->keymin * 8);
2420 return (0);
2421 }
2422 }
2423 if (xfs && xfs->encxf) {
2424 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
2425 yyerror("no encryption key specified");
2426 return (0);
2427 }
2428 if (enckey) {
2429 if (enckey->len < xfs->encxf->keymin) {
2430 yyerror("encryption key too short (%zu bits), "
2431 "minimum %zu bits", enckey->len * 8,
2432 xfs->encxf->keymin * 8);
2433 return (0);
2434 }
2435 if (xfs->encxf->keymax < enckey->len) {
2436 yyerror("encryption key too long (%zu bits), "
2437 "maximum %zu bits", enckey->len * 8,
2438 xfs->encxf->keymax * 8);
2439 return (0);
2440 }
2441 }
2442 }
2443
2444 return 1;
2445}
2446
2447int
2448add_sabundle(struct ipsec_rule *r, char *bundle)
2449{
2450 struct ipsec_rule *rp, *last, *sabundle;
2451 int found = 0;
2452
2453 TAILQ_FOREACH(rp, &ipsec->bundle_queue, bundle_entry) {
2454 if ((strcmp(rp->src->name, r->src->name) == 0) &&
2455 (strcmp(rp->dst->name, r->dst->name) == 0) &&
2456 (strcmp(rp->bundle, bundle) == 0)) {
2457 found = 1;
2458 break;
2459 }
2460 }
2461 if (found) {
2462 last = TAILQ_LAST(&rp->dst_bundle_queue, dst_bundle_queue);
2463 TAILQ_INSERT_TAIL(&rp->dst_bundle_queue, r, dst_bundle_entry);
2464
2465 sabundle = create_sabundle(last->dst, last->satype, last->spi,
2466 r->dst, r->satype, r->spi);
2467 if (sabundle == NULL)
2468 return (1);
2469 sabundle->nr = ipsec->rule_nr++;
2470 if (ipsecctl_add_rule(ipsec, sabundle))
2471 return (1);
2472 } else {
2473 TAILQ_INSERT_TAIL(&ipsec->bundle_queue, r, bundle_entry);
2474 TAILQ_INIT(&r->dst_bundle_queue);
2475 TAILQ_INSERT_TAIL(&r->dst_bundle_queue, r, dst_bundle_entry);
2476 r->bundle = bundle;
2477 }
2478
2479 return (0);
2480}
2481
2482struct ipsec_rule *
2483create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts,
2484 u_int32_t spi, u_int8_t udpencap, u_int16_t udpdport,
2485 struct ipsec_transforms *xfs, struct ipsec_key *authkey, struct ipsec_key *enckey)
2486{
2487 struct ipsec_rule *r;
2488
2489 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0)
2490 return (NULL);
2491
2492 r = calloc(1, sizeof(struct ipsec_rule));
2493 if (r == NULL)
2494 err(1, "%s", __func__);
2495
2496 r->type |= RULE_SA;
2497 r->satype = satype;
2498 r->tmode = tmode;
2499 r->src = hosts->src;
2500 r->dst = hosts->dst;
2501 r->spi = spi;
2502 r->udpencap = udpencap;
2503 r->udpdport = udpdport;
2504 r->xfs = xfs;
2505 r->authkey = authkey;
2506 r->enckey = enckey;
2507
2508 return r;
2509}
2510
2511struct ipsec_rule *
2512reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
2513 struct ipsec_key *enckey)
2514{
2515 struct ipsec_rule *reverse;
2516
2517 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey,
2518 rule->tmode) == 0)
2519 return (NULL);
2520
2521 reverse = calloc(1, sizeof(struct ipsec_rule));
2522 if (reverse == NULL)
2523 err(1, "%s", __func__);
2524
2525 reverse->type |= RULE_SA;
2526 reverse->satype = rule->satype;
2527 reverse->tmode = rule->tmode;
2528 reverse->src = copyhost(rule->dst);
2529 reverse->dst = copyhost(rule->src);
2530 reverse->spi = spi;
2531 reverse->udpencap = rule->udpencap;
2532 reverse->udpdport = rule->udpdport;
2533 reverse->xfs = copytransforms(rule->xfs);
2534 reverse->authkey = authkey;
2535 reverse->enckey = enckey;
2536
2537 return (reverse);
2538}
2539
2540struct ipsec_rule *
2541create_sabundle(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
2542 struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2)
2543{
2544 struct ipsec_rule *r;
2545
2546 r = calloc(1, sizeof(struct ipsec_rule));
2547 if (r == NULL)
2548 err(1, "%s", __func__);
2549
2550 r->type |= RULE_BUNDLE;
2551
2552 r->dst = copyhost(dst);
2553 r->dst2 = copyhost(dst2);
2554 r->proto = proto;
2555 r->proto2 = proto2;
2556 r->spi = spi;
2557 r->spi2 = spi2;
2558 r->satype = proto;
2559
2560 return (r);
2561}
2562
2563struct ipsec_rule *
2564create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
2565 u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
2566{
2567 struct ipsec_rule *r;
2568
2569 r = calloc(1, sizeof(struct ipsec_rule));
2570 if (r == NULL)
2571 err(1, "%s", __func__);
2572
2573 r->type |= RULE_FLOW;
2574
2575 if (dir == IPSEC_INOUT)
2576 r->direction = IPSEC_OUT;
2577 else
2578 r->direction = dir;
2579
2580 r->satype = satype;
2581 r->proto = proto;
2582 r->src = hosts->src;
2583 r->sport = hosts->sport;
2584 r->dst = hosts->dst;
2585 r->dport = hosts->dport;
2586 if ((hosts->sport != 0 || hosts->dport != 0) &&
2587 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2588 yyerror("no protocol supplied with source/destination ports");
2589 goto errout;
2590 }
2591
2592 switch (satype) {
2593 case IPSEC_IPCOMP:
2594 case IPSEC_IPIP:
2595 if (type == TYPE_UNKNOWN)
2596 type = TYPE_USE;
2597 break;
2598 default:
2599 if (type == TYPE_UNKNOWN)
2600 type = TYPE_REQUIRE;
2601 break;
2602 }
2603
2604 r->flowtype = type;
2605 if (type == TYPE_DENY || type == TYPE_BYPASS)
2606 return (r);
2607
2608 r->auth = calloc(1, sizeof(struct ipsec_auth));
2609 if (r->auth == NULL)
2610 err(1, "%s", __func__);
2611 r->auth->srcid = srcid;
2612 r->auth->dstid = dstid;
2613 r->auth->srcid_type = get_id_type(srcid);
2614 r->auth->dstid_type = get_id_type(dstid);
2615 return r;
2616
2617errout:
2618 free(r);
2619 if (srcid)
2620 free(srcid);
2621 if (dstid)
2622 free(dstid);
2623 free(hosts->src);
2624 hosts->src = NULL;
2625 free(hosts->dst);
2626 hosts->dst = NULL;
2627
2628 return NULL;
2629}
2630
2631void
2632expand_any(struct ipsec_addr_wrap *ipa_in)
2633{
2634 struct ipsec_addr_wrap *oldnext, *ipa;
2635
2636 for (ipa = ipa_in; ipa; ipa = ipa->next) {
2637 if (ipa->af != AF_UNSPEC)
2638 continue;
2639 oldnext = ipa->next;
2640
2641 ipa->af = AF_INET;
2642 ipa->netaddress = 1;
2643 if ((ipa->name = strdup("0.0.0.0/0")) == NULL)
2644 err(1, "%s", __func__);
2645
2646 ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap));
2647 if (ipa->next == NULL)
2648 err(1, "%s", __func__);
2649 ipa->next->af = AF_INET6;
2650 ipa->next->netaddress = 1;
2651 if ((ipa->next->name = strdup("::/0")) == NULL)
2652 err(1, "%s", __func__);
2653
2654 ipa->next->next = oldnext;
2655 }
2656}
2657
2658int
2659set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers)
2660{
2661 if (r->type == RULE_FLOW &&
2662 (r->flowtype == TYPE_DENY || r->flowtype == TYPE_BYPASS))
2663 return (0);
2664
2665 r->local = copyhost(peers->src);
2666 r->peer = copyhost(peers->dst);
2667 if (r->peer == NULL) {
2668 /* Set peer to remote host. Must be a host address. */
2669 if (r->direction == IPSEC_IN) {
2670 if (!r->src->netaddress)
2671 r->peer = copyhost(r->src);
2672 } else {
2673 if (!r->dst->netaddress)
2674 r->peer = copyhost(r->dst);
2675 }
2676 }
2677 if (r->type == RULE_FLOW && r->peer == NULL) {
2678 yyerror("no peer specified for destination %s",
2679 r->dst->name);
2680 return (1);
2681 }
2682 if (r->peer != NULL && r->peer->af == AF_UNSPEC) {
2683 /* If peer has been specified as any, use the default peer. */
2684 free(r->peer);
2685 r->peer = NULL;
2686 }
2687 if (r->type == RULE_IKE && r->peer == NULL) {
2688 /*
2689 * Check if the default peer is consistent for all
2690 * rules. Only warn to avoid breaking existing configs.
2691 */
2692 static struct ipsec_rule *pdr = NULL;
2693
2694 if (pdr == NULL) {
2695 /* Remember first default peer rule for comparison. */
2696 pdr = r;
2697 } else {
2698 /* The new default peer must create the same config. */
2699 if ((pdr->local == NULL && r->local != NULL) ||
2700 (pdr->local != NULL && r->local == NULL) ||
2701 (pdr->local != NULL && r->local != NULL &&
2702 strcmp(pdr->local->name, r->local->name)))
2703 yywarn("default peer local mismatch");
2704 if (pdr->ikeauth->type != r->ikeauth->type)
2705 yywarn("default peer phase 1 auth mismatch");
2706 if (pdr->ikeauth->type == IKE_AUTH_PSK &&
2707 r->ikeauth->type == IKE_AUTH_PSK &&
2708 strcmp(pdr->ikeauth->string, r->ikeauth->string))
2709 yywarn("default peer psk mismatch");
2710 if (pdr->p1ie != r->p1ie)
2711 yywarn("default peer phase 1 mode mismatch");
2712 /*
2713 * Transforms have ADD insted of SET so they may be
2714 * different and are not checked here.
2715 */
2716 if ((pdr->auth->srcid == NULL &&
2717 r->auth->srcid != NULL) ||
2718 (pdr->auth->srcid != NULL &&
2719 r->auth->srcid == NULL) ||
2720 (pdr->auth->srcid != NULL &&
2721 r->auth->srcid != NULL &&
2722 strcmp(pdr->auth->srcid, r->auth->srcid)))
2723 yywarn("default peer srcid mismatch");
2724 if ((pdr->auth->dstid == NULL &&
2725 r->auth->dstid != NULL) ||
2726 (pdr->auth->dstid != NULL &&
2727 r->auth->dstid == NULL) ||
2728 (pdr->auth->dstid != NULL &&
2729 r->auth->dstid != NULL &&
2730 strcmp(pdr->auth->dstid, r->auth->dstid)))
2731 yywarn("default peer dstid mismatch");
2732 }
2733 }
2734 return (0);
2735}
2736
2737int
2738expand_rule(struct ipsec_rule *rule, struct ipsec_hosts *peers,
2739 u_int8_t direction, u_int32_t spi, struct ipsec_key *authkey,
2740 struct ipsec_key *enckey, char *bundle)
2741{
2742 struct ipsec_rule *r, *revr;
2743 struct ipsec_addr_wrap *src, *dst;
2744 int added = 0, ret = 1;
2745
2746 if (validate_af(rule->src, rule->dst)) {
2747 yyerror("source/destination address families do not match");
2748 goto errout;
2749 }
2750 expand_any(rule->src);
2751 expand_any(rule->dst);
2752 for (src = rule->src; src; src = src->next) {
2753 for (dst = rule->dst; dst; dst = dst->next) {
2754 if (src->af != dst->af)
2755 continue;
2756 r = copyrule(rule);
2757
2758 r->src = copyhost(src);
2759 r->dst = copyhost(dst);
2760
2761 if (peers && set_rule_peers(r, peers)) {
2762 ipsecctl_free_rule(r);
2763 goto errout;
2764 }
2765
2766 r->nr = ipsec->rule_nr++;
2767 if (ipsecctl_add_rule(ipsec, r))
2768 goto out;
2769 if (bundle && add_sabundle(r, bundle))
2770 goto out;
2771
2772 if (direction == IPSEC_INOUT) {
2773 /* Create and add reverse flow rule. */
2774 revr = reverse_rule(r);
2775 if (revr == NULL)
2776 goto out;
2777
2778 revr->nr = ipsec->rule_nr++;
2779 if (ipsecctl_add_rule(ipsec, revr))
2780 goto out;
2781 if (bundle && add_sabundle(revr, bundle))
2782 goto out;
2783 } else if (spi != 0 || authkey || enckey) {
2784 /* Create and add reverse sa rule. */
2785 revr = reverse_sa(r, spi, authkey, enckey);
2786 if (revr == NULL)
2787 goto out;
2788
2789 revr->nr = ipsec->rule_nr++;
2790 if (ipsecctl_add_rule(ipsec, revr))
2791 goto out;
2792 if (bundle && add_sabundle(revr, bundle))
2793 goto out;
2794 }
2795 added++;
2796 }
2797 }
2798 if (!added)
2799 yyerror("rule expands to no valid combination");
2800 errout:
2801 ret = 0;
2802 ipsecctl_free_rule(rule);
2803 out:
2804 if (peers) {
2805 if (peers->src)
2806 free(peers->src);
2807 if (peers->dst)
2808 free(peers->dst);
2809 }
2810 return (ret);
2811}
2812
2813struct ipsec_rule *
2814reverse_rule(struct ipsec_rule *rule)
2815{
2816 struct ipsec_rule *reverse;
2817
2818 reverse = calloc(1, sizeof(struct ipsec_rule));
2819 if (reverse == NULL)
2820 err(1, "%s", __func__);
2821
2822 reverse->type |= RULE_FLOW;
2823
2824 /* Reverse direction */
2825 if (rule->direction == (u_int8_t)IPSEC_OUT)
2826 reverse->direction = (u_int8_t)IPSEC_IN;
2827 else
2828 reverse->direction = (u_int8_t)IPSEC_OUT;
2829
2830 reverse->flowtype = rule->flowtype;
2831 reverse->src = copyhost(rule->dst);
2832 reverse->dst = copyhost(rule->src);
2833 reverse->sport = rule->dport;
2834 reverse->dport = rule->sport;
2835 if (rule->local)
2836 reverse->local = copyhost(rule->local);
2837 if (rule->peer)
2838 reverse->peer = copyhost(rule->peer);
2839 reverse->satype = rule->satype;
2840 reverse->proto = rule->proto;
2841
2842 if (rule->auth) {
2843 reverse->auth = calloc(1, sizeof(struct ipsec_auth));
2844 if (reverse->auth == NULL)
2845 err(1, "%s", __func__);
2846 if (rule->auth->dstid && (reverse->auth->dstid =
2847 strdup(rule->auth->dstid)) == NULL)
2848 err(1, "%s", __func__);
2849 if (rule->auth->srcid && (reverse->auth->srcid =
2850 strdup(rule->auth->srcid)) == NULL)
2851 err(1, "%s", __func__);
2852 reverse->auth->srcid_type = rule->auth->srcid_type;
2853 reverse->auth->dstid_type = rule->auth->dstid_type;
2854 reverse->auth->type = rule->auth->type;
2855 }
2856
2857 return reverse;
2858}
2859
2860struct ipsec_rule *
2861create_ike(u_int8_t proto, struct ipsec_hosts *hosts,
2862 struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype,
2863 u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid,
2864 struct ike_auth *authtype, char *tag)
2865{
2866 struct ipsec_rule *r;
2867
2868 r = calloc(1, sizeof(struct ipsec_rule));
2869 if (r == NULL)
2870 err(1, "%s", __func__);
2871
2872 r->type = RULE_IKE;
2873
2874 r->proto = proto;
2875 r->src = hosts->src;
2876 r->sport = hosts->sport;
2877 r->dst = hosts->dst;
2878 r->dport = hosts->dport;
2879 if ((hosts->sport != 0 || hosts->dport != 0) &&
2880 (proto != IPPROTO_TCP && proto != IPPROTO_UDP)) {
2881 yyerror("no protocol supplied with source/destination ports");
2882 goto errout;
2883 }
2884
2885 r->satype = satype;
2886 r->tmode = tmode;
2887 r->ikemode = mode;
2888 if (phase1mode) {
2889 r->p1xfs = phase1mode->xfs;
2890 r->p1life = phase1mode->life;
2891 r->p1ie = phase1mode->ike_exch;
2892 } else {
2893 r->p1ie = IKE_MM;
2894 }
2895 if (phase2mode) {
2896 if (phase2mode->xfs && phase2mode->xfs->encxf &&
2897 phase2mode->xfs->encxf->noauth &&
2898 phase2mode->xfs->authxf) {
2899 yyerror("authentication is implicit for %s",
2900 phase2mode->xfs->encxf->name);
2901 goto errout;
2902 }
2903 r->p2xfs = phase2mode->xfs;
2904 r->p2life = phase2mode->life;
2905 r->p2ie = phase2mode->ike_exch;
2906 } else {
2907 r->p2ie = IKE_QM;
2908 }
2909
2910 r->auth = calloc(1, sizeof(struct ipsec_auth));
2911 if (r->auth == NULL)
2912 err(1, "%s", __func__);
2913 r->auth->srcid = srcid;
2914 r->auth->dstid = dstid;
2915 r->auth->srcid_type = get_id_type(srcid);
2916 r->auth->dstid_type = get_id_type(dstid);
2917 r->ikeauth = calloc(1, sizeof(struct ike_auth));
2918 if (r->ikeauth == NULL)
2919 err(1, "%s", __func__);
2920 r->ikeauth->type = authtype->type;
2921 r->ikeauth->string = authtype->string;
2922 r->tag = tag;
2923
2924 return (r);
2925
2926errout:
2927 free(r);
2928 free(hosts->src);
2929 hosts->src = NULL;
2930 free(hosts->dst);
2931 hosts->dst = NULL;
2932 if (phase1mode) {
2933 free(phase1mode->xfs);
2934 phase1mode->xfs = NULL;
2935 free(phase1mode->life);
2936 phase1mode->life = NULL;
2937 }
2938 if (phase2mode) {
2939 free(phase2mode->xfs);
2940 phase2mode->xfs = NULL;
2941 free(phase2mode->life);
2942 phase2mode->life = NULL;
2943 }
2944 if (srcid)
2945 free(srcid);
2946 if (dstid)
2947 free(dstid);
2948 return NULL;
2949}