Bug Summary

File:src/sbin/ipsecctl/obj/parse.c
Warning:line 1174, column 49
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/ipsecctl/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sbin/ipsecctl -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/ipsecctl/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 24 "/usr/src/sbin/ipsecctl/parse.y"
13#include <sys/types.h>
14#include <sys/ioctl.h>
15#include <sys/queue.h>
16#include <sys/socket.h>
17#include <sys/stat.h>
18#include <net/if.h>
19#include <netinet/in.h>
20#include <netinet/ip_ipsp.h>
21#include <arpa/inet.h>
22
23#include <ctype.h>
24#include <err.h>
25#include <errno(*__errno()).h>
26#include <fcntl.h>
27#include <ifaddrs.h>
28#include <limits.h>
29#include <netdb.h>
30#include <stdarg.h>
31#include <stdio.h>
32#include <string.h>
33#include <syslog.h>
34#include <unistd.h>
35
36#include "ipsecctl.h"
37
38TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first };
39static struct file {
40 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
41 FILE *stream;
42 char *name;
43 int lineno;
44 int errors;
45} *file, *topfile;
46struct file *pushfile(const char *, int);
47int popfile(void);
48int check_file_secrecy(int, const char *);
49int yyparse(void);
50int yylex(void);
51int yyerror(const char *, ...)
52 __attribute__((__format__ (printf, 1, 2)))
53 __attribute__((__nonnull__ (1)));
54int yywarn(const char *, ...)
55 __attribute__((__format__ (printf, 1, 2)))
56 __attribute__((__nonnull__ (1)));
57int kw_cmp(const void *, const void *);
58int lookup(char *);
59int lgetc(int);
60int lungetc(int);
61int findeol(void);
62
63TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first };
64struct sym {
65 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
66 int used;
67 int persist;
68 char *nam;
69 char *val;
70};
71int symset(const char *, const char *, int);
72char *symget(const char *);
73int cmdline_symset(char *);
74
75#define KEYSIZE_LIMIT1024 1024
76
77static struct ipsecctl *ipsec = NULL((void *)0);
78static int debug = 0;
79
80const struct ipsec_xf authxfs[] = {
81 { "unknown", AUTHXF_UNKNOWN, 0, 0 },
82 { "none", AUTHXF_NONE, 0, 0 },
83 { "hmac-md5", AUTHXF_HMAC_MD5, 16, 0 },
84 { "hmac-ripemd160", AUTHXF_HMAC_RIPEMD160, 20, 0 },
85 { "hmac-sha1", AUTHXF_HMAC_SHA1, 20, 0 },
86 { "hmac-sha2-256", AUTHXF_HMAC_SHA2_256, 32, 0 },
87 { "hmac-sha2-384", AUTHXF_HMAC_SHA2_384, 48, 0 },
88 { "hmac-sha2-512", AUTHXF_HMAC_SHA2_512, 64, 0 },
89 { NULL((void *)0), 0, 0, 0 },
90};
91
92const struct ipsec_xf encxfs[] = {
93 { "unknown", ENCXF_UNKNOWN, 0, 0, 0, 0 },
94 { "none", ENCXF_NONE, 0, 0, 0, 0 },
95 { "3des-cbc", ENCXF_3DES_CBC, 24, 24, 0, 0 },
96 { "aes", ENCXF_AES, 16, 32, 0, 0 },
97 { "aes-128", ENCXF_AES_128, 16, 16, 0, 0 },
98 { "aes-192", ENCXF_AES_192, 24, 24, 0, 0 },
99 { "aes-256", ENCXF_AES_256, 32, 32, 0, 0 },
100 { "aesctr", ENCXF_AESCTR, 16+4, 32+4, 0, 1 },
101 { "aes-128-ctr", ENCXF_AES_128_CTR, 16+4, 16+4, 0, 1 },
102 { "aes-192-ctr", ENCXF_AES_192_CTR, 24+4, 24+4, 0, 1 },
103 { "aes-256-ctr", ENCXF_AES_256_CTR, 32+4, 32+4, 0, 1 },
104 { "aes-128-gcm", ENCXF_AES_128_GCM, 16+4, 16+4, 1, 1 },
105 { "aes-192-gcm", ENCXF_AES_192_GCM, 24+4, 24+4, 1, 1 },
106 { "aes-256-gcm", ENCXF_AES_256_GCM, 32+4, 32+4, 1, 1 },
107 { "aes-128-gmac", ENCXF_AES_128_GMAC, 16+4, 16+4, 1, 1 },
108 { "aes-192-gmac", ENCXF_AES_192_GMAC, 24+4, 24+4, 1, 1 },
109 { "aes-256-gmac", ENCXF_AES_256_GMAC, 32+4, 32+4, 1, 1 },
110 { "blowfish", ENCXF_BLOWFISH, 5, 56, 0, 0 },
111 { "cast128", ENCXF_CAST128, 5, 16, 0, 0 },
112 { "chacha20-poly1305", ENCXF_CHACHA20_POLY1305, 32+4, 32+4, 1, 1 },
113 { "null", ENCXF_NULL, 0, 0, 0, 0 },
114 { NULL((void *)0), 0, 0, 0, 0, 0 },
115};
116
117const struct ipsec_xf compxfs[] = {
118 { "unknown", COMPXF_UNKNOWN, 0, 0 },
119 { "deflate", COMPXF_DEFLATE, 0, 0 },
120 { NULL((void *)0), 0, 0, 0 },
121};
122
123const struct ipsec_xf groupxfs[] = {
124 { "unknown", GROUPXF_UNKNOWN, 0, 0 },
125 { "none", GROUPXF_NONE, 0, 0 },
126 { "modp768", GROUPXF_1, 768, 0 },
127 { "grp1", GROUPXF_1, 768, 0 },
128 { "modp1024", GROUPXF_2, 1024, 0 },
129 { "grp2", GROUPXF_2, 1024, 0 },
130 { "modp1536", GROUPXF_5, 1536, 0 },
131 { "grp5", GROUPXF_5, 1536, 0 },
132 { "modp2048", GROUPXF_14, 2048, 0 },
133 { "grp14", GROUPXF_14, 2048, 0 },
134 { "modp3072", GROUPXF_15, 3072, 0 },
135 { "grp15", GROUPXF_15, 3072, 0 },
136 { "modp4096", GROUPXF_16, 4096, 0 },
137 { "grp16", GROUPXF_16, 4096, 0 },
138 { "modp6144", GROUPXF_17, 6144, 0 },
139 { "grp17", GROUPXF_17, 6144, 0 },
140 { "modp8192", GROUPXF_18, 8192, 0 },
141 { "grp18", GROUPXF_18, 8192, 0 },
142 { "ecp256", GROUPXF_19, 256, 0 },
143 { "grp19", GROUPXF_19, 256, 0 },
144 { "ecp384", GROUPXF_20, 384, 0 },
145 { "grp20", GROUPXF_20, 384, 0 },
146 { "ecp521", GROUPXF_21, 521, 0 },
147 { "grp21", GROUPXF_21, 521, 0 },
148 { "ecp192", GROUPXF_25, 192, 0 },
149 { "grp25", GROUPXF_25, 192, 0 },
150 { "ecp224", GROUPXF_26, 224, 0 },
151 { "grp26", GROUPXF_26, 224, 0 },
152 { "bp224", GROUPXF_27, 224, 0 },
153 { "grp27", GROUPXF_27, 224, 0 },
154 { "bp256", GROUPXF_28, 256, 0 },
155 { "grp28", GROUPXF_28, 256, 0 },
156 { "bp384", GROUPXF_29, 384, 0 },
157 { "grp29", GROUPXF_29, 384, 0 },
158 { "bp512", GROUPXF_30, 512, 0 },
159 { "grp30", GROUPXF_30, 512, 0 },
160 { NULL((void *)0), 0, 0, 0 },
161};
162
163int atoul(char *, u_long *);
164int atospi(char *, u_int32_t *);
165u_int8_t x2i(unsigned char *);
166struct ipsec_key *parsekey(unsigned char *, size_t);
167struct ipsec_key *parsekeyfile(char *);
168struct ipsec_addr_wrap *host(const char *);
169struct ipsec_addr_wrap *host_v6(const char *, int);
170struct ipsec_addr_wrap *host_v4(const char *, int);
171struct ipsec_addr_wrap *host_dns(const char *, int);
172struct ipsec_addr_wrap *host_if(const char *, int);
173struct ipsec_addr_wrap *host_any(void);
174void ifa_load(void);
175int ifa_exists(const char *);
176struct ipsec_addr_wrap *ifa_lookup(const char *ifa_name);
177struct ipsec_addr_wrap *ifa_grouplookup(const char *);
178void set_ipmask(struct ipsec_addr_wrap *, u_int8_t);
179const struct ipsec_xf *parse_xf(const char *, const struct ipsec_xf *);
180struct ipsec_lifetime *parse_life(const char *);
181struct ipsec_transforms *copytransforms(const struct ipsec_transforms *);
182struct ipsec_lifetime *copylife(const struct ipsec_lifetime *);
183struct ipsec_auth *copyipsecauth(const struct ipsec_auth *);
184struct ike_auth *copyikeauth(const struct ike_auth *);
185struct ipsec_key *copykey(struct ipsec_key *);
186struct ipsec_addr_wrap *copyhost(const struct ipsec_addr_wrap *);
187char *copytag(const char *);
188struct ipsec_rule *copyrule(struct ipsec_rule *);
189int validate_af(struct ipsec_addr_wrap *,
190 struct ipsec_addr_wrap *);
191int validate_sa(u_int32_t, u_int8_t,
192 struct ipsec_transforms *, struct ipsec_key *,
193 struct ipsec_key *, u_int8_t);
194struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *,
195 u_int32_t, u_int8_t, u_int16_t,
196 struct ipsec_transforms *,
197 struct ipsec_key *, struct ipsec_key *);
198struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t,
199 struct ipsec_key *, struct ipsec_key *);
200struct ipsec_rule *create_sabundle(struct ipsec_addr_wrap *, u_int8_t,
201 u_int32_t, struct ipsec_addr_wrap *, u_int8_t,
202 u_int32_t);
203struct ipsec_rule *create_flow(u_int8_t, u_int8_t, struct ipsec_hosts *,
204 u_int8_t, char *, char *, u_int8_t);
205int set_rule_peers(struct ipsec_rule *r,
206 struct ipsec_hosts *peers);
207void expand_any(struct ipsec_addr_wrap *);
208int expand_rule(struct ipsec_rule *, struct ipsec_hosts *,
209 u_int8_t, u_int32_t, struct ipsec_key *,
210 struct ipsec_key *, char *);
211struct ipsec_rule *reverse_rule(struct ipsec_rule *);
212struct ipsec_rule *create_ike(u_int8_t, struct ipsec_hosts *,
213 struct ike_mode *, struct ike_mode *, u_int8_t,
214 u_int8_t, u_int8_t, char *, char *,
215 struct ike_auth *, char *);
216int add_sabundle(struct ipsec_rule *, char *);
217int get_id_type(char *);
218
219struct ipsec_transforms *ipsec_transforms;
220
221typedef struct {
222 union {
223 int64_t number;
224 uint32_t unit;
225 u_int8_t ikemode;
226 u_int8_t dir;
227 u_int8_t satype; /* encapsulating prococol */
228 u_int8_t proto; /* encapsulated protocol */
229 u_int8_t tmode;
230 char *string;
231 u_int16_t port;
232 struct ipsec_hosts hosts;
233 struct ipsec_hosts peers;
234 struct ipsec_addr_wrap *anyhost;
235 struct ipsec_addr_wrap *singlehost;
236 struct ipsec_addr_wrap *host;
237 struct {
238 char *srcid;
239 char *dstid;
240 } ids;
241 char *id;
242 u_int8_t type;
243 struct ike_auth ikeauth;
244 struct {
245 u_int32_t spiout;
246 u_int32_t spiin;
247 } spis;
248 struct {
249 u_int8_t encap;
250 u_int16_t port;
251 } udpencap;
252 struct {
253 struct ipsec_key *keyout;
254 struct ipsec_key *keyin;
255 } authkeys;
256 struct {
257 struct ipsec_key *keyout;
258 struct ipsec_key *keyin;
259 } enckeys;
260 struct {
261 struct ipsec_key *keyout;
262 struct ipsec_key *keyin;
263 } keys;
264 struct ipsec_transforms *transforms;
265 struct ipsec_lifetime *life;
266 struct ike_mode *mode;
267 } v;
268 int lineno;
269} YYSTYPE;
270
271#line 272 "parse.c"
272#define FLOW257 257
273#define FROM258 258
274#define ESP259 259
275#define AH260 260
276#define IN261 261
277#define PEER262 262
278#define ON263 263
279#define OUT264 264
280#define TO265 265
281#define SRCID266 266
282#define DSTID267 267
283#define RSA268 268
284#define PSK269 269
285#define TCPMD5270 270
286#define SPI271 271
287#define AUTHKEY272 272
288#define ENCKEY273 273
289#define FILENAME274 274
290#define AUTHXF275 275
291#define ENCXF276 276
292#define ERROR277 277
293#define IKE278 278
294#define MAIN279 279
295#define QUICK280 280
296#define AGGRESSIVE281 281
297#define PASSIVE282 282
298#define ACTIVE283 283
299#define ANY284 284
300#define IPIP285 285
301#define IPCOMP286 286
302#define COMPXF287 287
303#define TUNNEL288 288
304#define TRANSPORT289 289
305#define DYNAMIC290 290
306#define LIFETIME291 291
307#define TYPE292 292
308#define DENY293 293
309#define BYPASS294 294
310#define LOCAL295 295
311#define PROTO296 296
312#define USE297 297
313#define ACQUIRE298 298
314#define REQUIRE299 299
315#define DONTACQ300 300
316#define GROUP301 301
317#define PORT302 302
318#define TAG303 303
319#define INCLUDE304 304
320#define BUNDLE305 305
321#define UDPENCAP306 306
322#define INTERFACE307 307
323#define STRING308 308
324#define NUMBER309 309
325#define YYERRCODE256 256
326const short yylhs[] =
327 { -1,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,
329 39, 33, 37, 36, 35, 34, 34, 4, 4, 4,
330 4, 4, 5, 5, 5, 5, 6, 6, 7, 7,
331 7, 3, 3, 3, 8, 8, 9, 9, 10, 10,
332 11, 11, 11, 11, 11, 12, 12, 13, 13, 15,
333 15, 16, 16, 14, 14, 14, 14, 17, 17, 17,
334 17, 28, 28, 28, 28, 28, 28, 28, 18, 19,
335 19, 20, 20, 20, 41, 25, 25, 40, 40, 42,
336 42, 42, 42, 30, 30, 30, 31, 31, 29, 29,
337 29, 21, 21, 22, 22, 23, 23, 24, 24, 26,
338 26, 26, 26, 27, 27, 27, 32, 32, 1, 2,
339 2, 38,
340};
341const short yylen[] =
342 { 2,
343 0, 3, 2, 3, 3, 3, 3, 3, 3, 1,
344 0, 2, 4, 9, 8, 12, 8, 0, 1, 1,
345 1, 1, 0, 2, 2, 2, 1, 1, 0, 1,
346 1, 0, 1, 1, 6, 6, 0, 2, 1, 1,
347 0, 4, 4, 2, 2, 1, 1, 0, 1, 1,
348 3, 1, 3, 1, 4, 1, 3, 0, 4, 2,
349 2, 0, 2, 2, 2, 2, 2, 2, 1, 2,
350 2, 0, 1, 3, 0, 2, 0, 2, 1, 2,
351 2, 2, 2, 0, 3, 3, 0, 3, 0, 2,
352 2, 0, 2, 0, 2, 0, 2, 1, 2, 0,
353 1, 1, 1, 0, 1, 2, 0, 2, 2, 2,
354 1, 3,
355};
356const short yydefred[] =
357 { 1,
358 0, 0, 0, 19, 20, 0, 0, 22, 21, 0,
359 0, 3, 0, 0, 0, 0, 0, 0, 0, 9,
360 0, 0, 0, 0, 101, 103, 102, 0, 12, 0,
361 30, 31, 0, 2, 4, 5, 6, 7, 8, 33,
362 34, 0, 56, 0, 0, 0, 0, 0, 0, 0,
363 0, 0, 0, 111, 0, 0, 0, 0, 0, 50,
364 0, 0, 0, 0, 0, 70, 71, 0, 13, 109,
365 0, 0, 0, 0, 110, 0, 25, 26, 27, 28,
366 24, 0, 53, 10, 57, 0, 39, 40, 38, 0,
367 0, 0, 0, 98, 93, 47, 49, 0, 46, 0,
368 0, 0, 0, 0, 0, 0, 0, 51, 0, 55,
369 0, 99, 0, 0, 0, 0, 0, 0, 0, 0,
370 0, 0, 0, 0, 0, 35, 36, 42, 43, 0,
371 85, 0, 0, 0, 0, 0, 79, 86, 0, 0,
372 0, 74, 0, 69, 0, 61, 0, 15, 91, 90,
373 80, 81, 82, 83, 78, 88, 105, 0, 17, 0,
374 0, 0, 0, 66, 67, 63, 64, 65, 68, 106,
375 0, 95, 0, 14, 59, 0, 97, 0, 0, 16,
376 108,
377};
378const short yydgoto[] =
379 { 1,
380 52, 55, 42, 13, 58, 81, 33, 24, 63, 89,
381 73, 98, 99, 46, 61, 47, 125, 145, 50, 106,
382 69, 162, 174, 95, 115, 28, 159, 148, 131, 103,
383 119, 180, 14, 15, 16, 17, 18, 19, 86, 136,
384 116, 137,
385};
386const short yysindex[] =
387 { 0,
388 47, 14, -191, 0, 0, -172, -184, 0, 0, -261,
389 4, 0, -163, 91, 104, 110, 112, 120, 122, 0,
390 -140, -120, -120, -137, 0, 0, 0, -245, 0, -168,
391 0, 0, -172, 0, 0, 0, 0, 0, 0, 0,
392 0, -146, 0, 106, -120, -148, 115, -148, -180, -115,
393 -150, -252, -163, 0, -149, -137, -242, -172, -147, 0,
394 -36, -162, -104, -145, -98, 0, 0, -248, 0, 0,
395 -200, -143, -246, -146, 0, -139, 0, 0, 0, 0,
396 0, -252, 0, 0, 0, -120, 0, 0, 0, -120,
397 127, -120, -138, 0, 0, 0, 0, -126, 0, -91,
398 0, 0, -107, -172, -128, 0, -130, 0, -148, 0,
399 -148, 0, -143, -200, -116, -185, -116, 0, -130, -252,
400 -133, -115, -131, -131, -114, 0, 0, 0, 0, -160,
401 0, -129, -127, -125, -124, -185, 0, 0, -116, -117,
402 -246, 0, -93, 0, -85, 0, -155, 0, 0, 0,
403 0, 0, 0, 0, 0, 0, 0, -123, 0, -107,
404 -248, -119, -131, 0, 0, 0, 0, 0, 0, 0,
405 -130, 0, -113, 0, 0, -117, 0, -112, -111, 0,
406 0,};
407const short yyrindex[] =
408 { 0,
409 -178, 0, -219, 0, 0, 0, -237, 0, 0, 0,
410 0, 0, -161, 0, 0, 0, 0, 0, 0, 0,
411 -221, 0, 0, 0, 0, 0, 0, -233, 0, 0,
412 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
413 0, -153, 0, -10, 0, -76, 10, -66, 0, 183,
414 0, 291, -187, 0, 186, 0, 0, 0, 0, 0,
415 -118, 0, 0, 0, 0, 0, 0, 0, 0, 0,
416 146, 177, 62, -153, 0, 63, 0, 0, 0, 0,
417 0, 17, 0, 0, 0, 0, 0, 0, 0, 0,
418 0, 0, 0, 0, 0, 0, 0, 197, 0, 215,
419 131, 131, 162, 0, 71, 90, -6, 0, 113, 0,
420 113, 0, 224, 224, 121, 0, 121, 184, 19, 243,
421 0, -9, 0, 0, 188, 0, 0, 0, 0, 0,
422 0, 0, 0, 0, 0, 54, 0, 0, 270, 189,
423 263, 0, -8, 0, 117, 0, 0, 0, 0, 0,
424 0, 0, 0, 0, 0, 0, 0, 0, 0, 285,
425 0, 190, 0, 0, 0, 0, 0, 0, 0, 0,
426 -3, 0, 0, 0, 0, -4, 0, 191, 0, 0,
427 0,};
428const short yygindex[] =
429 { 0,
430 0, 0, 0, 89, 128, 0, 150, -22, -35, 0,
431 -32, 92, -60, -7, 0, 140, -110, -105, 149, 0,
432 86, 0, 0, 48, 1, 0, 34, 0, -21, 70,
433 52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
434 0, 77,
435};
436#define YYTABLESIZE588 588
437const short yytable[] =
438 { 52,
439 92, 94, 45, 58, 11, 104, 58, 84, 140, 71,
440 56, 100, 65, 4, 5, 48, 77, 78, 146, 54,
441 100, 100, 100, 20, 18, 93, 41, 100, 58, 52,
442 52, 18, 101, 52, 102, 82, 32, 60, 18, 8,
443 9, 18, 72, 32, 18, 18, 29, 100, 100, 107,
444 100, 100, 128, 54, 18, 18, 12, 175, 100, 94,
445 176, 51, 18, 76, 30, 79, 80, 4, 5, 100,
446 29, 84, 72, 126, 32, 127, 18, 29, 108, 18,
447 73, 120, 109, 96, 111, 22, 18, 141, 85, 132,
448 133, 21, 23, 8, 9, 138, 29, 25, 26, 77,
449 34, 134, 117, 29, 23, 27, 122, 97, 29, 18,
450 18, 23, 52, 35, 52, 135, 53, 156, 139, 36,
451 40, 37, 37, 41, 31, 32, 60, 66, 67, 38,
452 89, 39, 54, 49, 54, 123, 124, 164, 165, 54,
453 77, 166, 167, 168, 169, 87, 88, 149, 150, 57,
454 157, 158, 59, 62, 64, 48, 68, 70, 75, 92,
455 90, 83, 44, 43, 97, 11, 105, 110, 113, 112,
456 114, 87, 118, 121, 130, 142, 144, 147, 151, 161,
457 152, 163, 153, 154, 170, 173, 48, 44, 37, 11,
458 179, 37, 92, 77, 177, 112, 181, 62, 104, 96,
459 107, 104, 74, 91, 76, 129, 44, 143, 172, 178,
460 160, 171, 155, 0, 0, 0, 0, 0, 0, 0,
461 0, 0, 0, 0, 45, 0, 0, 0, 0, 0,
462 0, 0, 0, 48, 0, 0, 0, 0, 0, 0,
463 0, 0, 0, 0, 0, 0, 0, 52, 0, 0,
464 0, 52, 41, 0, 52, 52, 52, 52, 52, 0,
465 52, 0, 0, 92, 58, 58, 0, 54, 52, 52,
466 52, 54, 84, 52, 54, 54, 54, 54, 54, 89,
467 54, 52, 41, 41, 52, 58, 58, 58, 54, 54,
468 54, 52, 52, 54, 87, 92, 94, 52, 104, 58,
469 41, 54, 2, 3, 54, 4, 5, 0, 41, 0,
470 0, 54, 54, 0, 0, 0, 6, 54, 0, 76,
471 76, 76, 76, 0, 7, 76, 76, 84, 84, 84,
472 84, 8, 9, 76, 72, 72, 0, 72, 72, 0,
473 0, 84, 73, 73, 76, 73, 73, 0, 0, 72,
474 10, 0, 0, 0, 11, 0, 76, 73, 76, 0,
475 0, 77, 77, 72, 75, 75, 0, 72, 0, 0,
476 0, 73, 0, 0, 37, 73, 75, 0, 37, 37,
477 37, 37, 0, 37, 60, 60, 89, 89, 89, 89,
478 75, 37, 37, 37, 77, 0, 77, 77, 77, 77,
479 89, 0, 0, 0, 37, 75, 75, 37, 60, 0,
480 77, 48, 48, 48, 48, 37, 0, 75, 0, 60,
481 0, 77, 0, 89, 48, 48, 48, 87, 87, 87,
482 87, 75, 0, 77, 0, 0, 0, 48, 48, 0,
483 48, 0, 48, 48, 48, 48, 0, 0, 48, 77,
484 77, 77, 77, 0, 0, 48, 48, 48, 75, 75,
485 0, 0, 44, 44, 44, 44, 0, 0, 48, 0,
486 75, 0, 0, 0, 77, 44, 44, 44, 0, 48,
487 45, 45, 45, 45, 75, 0, 77, 0, 44, 48,
488 48, 48, 48, 45, 45, 45, 0, 0, 0, 44,
489 0, 0, 48, 48, 48, 0, 45, 0, 41, 41,
490 41, 41, 0, 0, 0, 48, 0, 45, 0, 0,
491 0, 41, 41, 41, 0, 0, 48, 0, 84, 84,
492 84, 84, 0, 0, 0, 89, 89, 89, 89, 0,
493 0, 0, 84, 0, 0, 41, 0, 0, 0, 0,
494 87, 87, 87, 87, 0, 0, 41, 41, 41, 41,
495 0, 0, 0, 0, 0, 84, 0, 0, 0, 41,
496 41, 41, 89, 0, 0, 0, 0, 0, 0, 0,
497 0, 0, 0, 0, 0, 0, 0, 87,
498};
499const short yycheck[] =
500 { 10,
501 10, 10, 123, 10, 123, 10, 10, 44, 119, 262,
502 33, 72, 48, 259, 260, 23, 259, 260, 124, 10,
503 258, 259, 260, 10, 258, 274, 10, 265, 10, 40,
504 41, 265, 279, 44, 281, 58, 258, 45, 258, 285,
505 286, 261, 295, 265, 264, 265, 308, 285, 286, 82,
506 288, 289, 113, 44, 288, 289, 10, 163, 296, 308,
507 171, 307, 296, 10, 61, 308, 309, 259, 260, 307,
508 258, 10, 10, 109, 296, 111, 296, 265, 86, 258,
509 10, 104, 90, 284, 92, 258, 265, 120, 125, 275,
510 276, 3, 265, 285, 286, 117, 258, 282, 283, 10,
511 10, 287, 102, 265, 258, 290, 106, 308, 296, 288,
512 289, 265, 123, 10, 125, 301, 28, 139, 118, 10,
513 261, 10, 10, 264, 288, 289, 10, 308, 309, 10,
514 10, 10, 123, 271, 125, 266, 267, 293, 294, 308,
515 10, 297, 298, 299, 300, 308, 309, 308, 309, 296,
516 268, 269, 47, 302, 40, 10, 272, 308, 308, 258,
517 265, 309, 308, 284, 308, 284, 306, 41, 295, 308,
518 262, 10, 280, 302, 291, 309, 308, 292, 308, 273,
519 308, 267, 308, 308, 308, 305, 10, 308, 265, 308,
520 303, 258, 10, 10, 308, 10, 308, 10, 10, 10,
521 10, 74, 53, 64, 56, 114, 10, 122, 161, 176,
522 141, 160, 136, -1, -1, -1, -1, -1, -1, -1,
523 -1, -1, -1, -1, 10, -1, -1, -1, -1, -1,
524 -1, -1, -1, 10, -1, -1, -1, -1, -1, -1,
525 -1, -1, -1, -1, -1, -1, -1, 258, -1, -1,
526 -1, 262, 10, -1, 265, 266, 267, 268, 269, -1,
527 271, -1, -1, 273, 268, 269, -1, 258, 279, 280,
528 281, 262, 10, 284, 265, 266, 267, 268, 269, 10,
529 271, 292, 266, 267, 295, 292, 268, 269, 279, 280,
530 281, 302, 303, 284, 10, 305, 305, 308, 303, 303,
531 10, 292, 256, 257, 295, 259, 260, -1, 292, -1,
532 -1, 302, 303, -1, -1, -1, 270, 308, -1, 266,
533 267, 268, 269, -1, 278, 272, 273, 266, 267, 268,
534 269, 285, 286, 280, 272, 273, -1, 275, 276, -1,
535 -1, 280, 272, 273, 291, 275, 276, -1, -1, 287,
536 304, -1, -1, -1, 308, -1, 303, 287, 305, -1,
537 -1, 272, 273, 301, 275, 276, -1, 305, -1, -1,
538 -1, 301, -1, -1, 262, 305, 287, -1, 266, 267,
539 268, 269, -1, 271, 268, 269, 266, 267, 268, 269,
540 301, 279, 280, 281, 305, -1, 266, 267, 268, 269,
541 280, -1, -1, -1, 292, 275, 276, 295, 292, -1,
542 280, 266, 267, 268, 269, 303, -1, 287, -1, 303,
543 -1, 291, -1, 303, 279, 280, 281, 266, 267, 268,
544 269, 301, -1, 303, -1, -1, -1, 292, 262, -1,
545 295, -1, 266, 267, 268, 269, -1, -1, 303, 266,
546 267, 268, 269, -1, -1, 279, 280, 281, 275, 276,
547 -1, -1, 266, 267, 268, 269, -1, -1, 292, -1,
548 287, -1, -1, -1, 291, 279, 280, 281, -1, 303,
549 266, 267, 268, 269, 301, -1, 303, -1, 292, 266,
550 267, 268, 269, 279, 280, 281, -1, -1, -1, 303,
551 -1, -1, 279, 280, 281, -1, 292, -1, 266, 267,
552 268, 269, -1, -1, -1, 292, -1, 303, -1, -1,
553 -1, 279, 280, 281, -1, -1, 303, -1, 266, 267,
554 268, 269, -1, -1, -1, 266, 267, 268, 269, -1,
555 -1, -1, 280, -1, -1, 303, -1, -1, -1, -1,
556 266, 267, 268, 269, -1, -1, 266, 267, 268, 269,
557 -1, -1, -1, -1, -1, 303, -1, -1, -1, 279,
558 280, 281, 303, -1, -1, -1, -1, -1, -1, -1,
559 -1, -1, -1, -1, -1, -1, -1, 303,
560};
561#define YYFINAL1 1
562#ifndef YYDEBUG0
563#define YYDEBUG0 0
564#endif
565#define YYMAXTOKEN309 309
566#if YYDEBUG0
567const char * const yyname[] =
568 {
569"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5700,0,0,0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,0,
571"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,
5730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5760,0,"FLOW","FROM","ESP","AH","IN","PEER","ON","OUT","TO","SRCID","DSTID","RSA",
577"PSK","TCPMD5","SPI","AUTHKEY","ENCKEY","FILENAME","AUTHXF","ENCXF","ERROR",
578"IKE","MAIN","QUICK","AGGRESSIVE","PASSIVE","ACTIVE","ANY","IPIP","IPCOMP",
579"COMPXF","TUNNEL","TRANSPORT","DYNAMIC","LIFETIME","TYPE","DENY","BYPASS",
580"LOCAL","PROTO","USE","ACQUIRE","REQUIRE","DONTACQ","GROUP","PORT","TAG",
581"INCLUDE","BUNDLE","UDPENCAP","INTERFACE","STRING","NUMBER",
582};
583const char * const yyrule[] =
584 {"$accept : grammar",
585"grammar :",
586"grammar : grammar include '\\n'",
587"grammar : grammar '\\n'",
588"grammar : grammar ikerule '\\n'",
589"grammar : grammar flowrule '\\n'",
590"grammar : grammar sarule '\\n'",
591"grammar : grammar tcpmd5rule '\\n'",
592"grammar : grammar varset '\\n'",
593"grammar : grammar error '\\n'",
594"comma : ','",
595"comma :",
596"include : INCLUDE STRING",
597"tcpmd5rule : TCPMD5 hosts spispec authkeyspec",
598"sarule : satype tmode hosts spispec udpencap transforms authkeyspec enckeyspec bundlestring",
599"flowrule : FLOW satype dir proto hosts peers ids type",
600"ikerule : IKE ikemode satype tmode proto hosts peers phase1mode phase2mode ids ikeauth tag",
601"ikerule : IKE ikemode iface peers phase1mode phase2mode ids ikeauth",
602"satype :",
603"satype : ESP",
604"satype : AH",
605"satype : IPCOMP",
606"satype : IPIP",
607"proto :",
608"proto : PROTO protoval",
609"proto : PROTO ESP",
610"proto : PROTO AH",
611"protoval : STRING",
612"protoval : NUMBER",
613"tmode :",
614"tmode : TUNNEL",
615"tmode : TRANSPORT",
616"dir :",
617"dir : IN",
618"dir : OUT",
619"hosts : FROM host port TO host port",
620"hosts : TO host port FROM host port",
621"port :",
622"port : PORT portval",
623"portval : STRING",
624"portval : NUMBER",
625"peers :",
626"peers : PEER anyhost LOCAL singlehost",
627"peers : LOCAL singlehost PEER anyhost",
628"peers : PEER anyhost",
629"peers : LOCAL singlehost",
630"anyhost : singlehost",
631"anyhost : ANY",
632"singlehost :",
633"singlehost : STRING",
634"host_list : host",
635"host_list : host_list comma host",
636"host_spec : STRING",
637"host_spec : STRING '/' NUMBER",
638"host : host_spec",
639"host : host_spec '(' host_spec ')'",
640"host : ANY",
641"host : '{' host_list '}'",
642"ids :",
643"ids : SRCID id DSTID id",
644"ids : SRCID id",
645"ids : DSTID id",
646"type :",
647"type : TYPE USE",
648"type : TYPE ACQUIRE",
649"type : TYPE REQUIRE",
650"type : TYPE DENY",
651"type : TYPE BYPASS",
652"type : TYPE DONTACQ",
653"id : STRING",
654"spispec : SPI STRING",
655"spispec : SPI NUMBER",
656"udpencap :",
657"udpencap : UDPENCAP",
658"udpencap : UDPENCAP PORT NUMBER",
659"$$1 :",
660"transforms : $$1 transforms_l",
661"transforms :",
662"transforms_l : transforms_l transform",
663"transforms_l : transform",
664"transform : AUTHXF STRING",
665"transform : ENCXF STRING",
666"transform : COMPXF STRING",
667"transform : GROUP STRING",
668"phase1mode :",
669"phase1mode : MAIN transforms lifetime",
670"phase1mode : AGGRESSIVE transforms lifetime",
671"phase2mode :",
672"phase2mode : QUICK transforms lifetime",
673"lifetime :",
674"lifetime : LIFETIME NUMBER",
675"lifetime : LIFETIME STRING",
676"authkeyspec :",
677"authkeyspec : AUTHKEY keyspec",
678"enckeyspec :",
679"enckeyspec : ENCKEY keyspec",
680"bundlestring :",
681"bundlestring : BUNDLE STRING",
682"keyspec : STRING",
683"keyspec : FILENAME STRING",
684"ikemode :",
685"ikemode : PASSIVE",
686"ikemode : DYNAMIC",
687"ikemode : ACTIVE",
688"ikeauth :",
689"ikeauth : RSA",
690"ikeauth : PSK STRING",
691"tag :",
692"tag : TAG STRING",
693"iface : INTERFACE STRING",
694"string : string STRING",
695"string : STRING",
696"varset : STRING '=' string",
697};
698#endif
699#ifdef YYSTACKSIZE10000
700#undef YYMAXDEPTH10000
701#define YYMAXDEPTH10000 YYSTACKSIZE10000
702#else
703#ifdef YYMAXDEPTH10000
704#define YYSTACKSIZE10000 YYMAXDEPTH10000
705#else
706#define YYSTACKSIZE10000 10000
707#define YYMAXDEPTH10000 10000
708#endif
709#endif
710#define YYINITSTACKSIZE200 200
711/* LINTUSED */
712int yydebug;
713int yynerrs;
714int yyerrflag;
715int yychar;
716short *yyssp;
717YYSTYPE *yyvsp;
718YYSTYPE yyval;
719YYSTYPE yylval;
720short *yyss;
721short *yysslim;
722YYSTYPE *yyvs;
723unsigned int yystacksize;
724int yyparse(void);
725#line 1005 "/usr/src/sbin/ipsecctl/parse.y"
726
727struct keywords {
728 const char *k_name;
729 int k_val;
730};
731
732int
733yyerror(const char *fmt, ...)
734{
735 va_list ap;
736
737 file->errors++;
738 va_start(ap, fmt)__builtin_va_start((ap), fmt);
739 fprintf(stderr(&__sF[2]), "%s: %d: ", file->name, yylval.lineno);
740 vfprintf(stderr(&__sF[2]), fmt, ap);
741 fprintf(stderr(&__sF[2]), "\n");
742 va_end(ap)__builtin_va_end((ap));
743 return (0);
744}
745
746int
747yywarn(const char *fmt, ...)
748{
749 va_list ap;
750
751 va_start(ap, fmt)__builtin_va_start((ap), fmt);
752 fprintf(stderr(&__sF[2]), "%s: %d: ", file->name, yylval.lineno);
753 vfprintf(stderr(&__sF[2]), fmt, ap);
754 fprintf(stderr(&__sF[2]), "\n");
755 va_end(ap)__builtin_va_end((ap));
756 return (0);
757}
758
759int
760kw_cmp(const void *k, const void *e)
761{
762 return (strcmp(k, ((const struct keywords *)e)->k_name));
763}
764
765int
766lookup(char *s)
767{
768 /* this has to be sorted always */
769 static const struct keywords keywords[] = {
770 { "acquire", ACQUIRE298 },
771 { "active", ACTIVE283 },
772 { "aggressive", AGGRESSIVE281 },
773 { "ah", AH260 },
774 { "any", ANY284 },
775 { "auth", AUTHXF275 },
776 { "authkey", AUTHKEY272 },
777 { "bundle", BUNDLE305 },
778 { "bypass", BYPASS294 },
779 { "comp", COMPXF287 },
780 { "deny", DENY293 },
781 { "dontacq", DONTACQ300 },
782 { "dstid", DSTID267 },
783 { "dynamic", DYNAMIC290 },
784 { "enc", ENCXF276 },
785 { "enckey", ENCKEY273 },
786 { "esp", ESP259 },
787 { "file", FILENAME274 },
788 { "flow", FLOW257 },
789 { "from", FROM258 },
790 { "group", GROUP301 },
791 { "ike", IKE278 },
792 { "in", IN261 },
793 { "include", INCLUDE304 },
794 { "interface", INTERFACE307 },
795 { "ipcomp", IPCOMP286 },
796 { "ipip", IPIP285 },
797 { "lifetime", LIFETIME291 },
798 { "local", LOCAL295 },
799 { "main", MAIN279 },
800 { "out", OUT264 },
801 { "passive", PASSIVE282 },
802 { "peer", PEER262 },
803 { "port", PORT302 },
804 { "proto", PROTO296 },
805 { "psk", PSK269 },
806 { "quick", QUICK280 },
807 { "require", REQUIRE299 },
808 { "rsa", RSA268 },
809 { "spi", SPI271 },
810 { "srcid", SRCID266 },
811 { "tag", TAG303 },
812 { "tcpmd5", TCPMD5270 },
813 { "to", TO265 },
814 { "transport", TRANSPORT289 },
815 { "tunnel", TUNNEL288 },
816 { "type", TYPE292 },
817 { "udpencap", UDPENCAP306 },
818 { "use", USE297 }
819 };
820 const struct keywords *p;
821
822 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
823 sizeof(keywords[0]), kw_cmp);
824
825 if (p) {
826 if (debug > 1)
827 fprintf(stderr(&__sF[2]), "%s: %d\n", s, p->k_val);
828 return (p->k_val);
829 } else {
830 if (debug > 1)
831 fprintf(stderr(&__sF[2]), "string: %s\n", s);
832 return (STRING308);
833 }
834}
835
836#define MAXPUSHBACK128 128
837
838char *parsebuf;
839int parseindex;
840char pushback_buffer[MAXPUSHBACK128];
841int pushback_index = 0;
842
843int
844lgetc(int quotec)
845{
846 int c, next;
847
848 if (parsebuf) {
849 /* Read character from the parsebuffer instead of input. */
850 if (parseindex >= 0) {
851 c = (unsigned char)parsebuf[parseindex++];
852 if (c != '\0')
853 return (c);
854 parsebuf = NULL((void *)0);
855 } else
856 parseindex++;
857 }
858
859 if (pushback_index)
860 return ((unsigned char)pushback_buffer[--pushback_index]);
861
862 if (quotec) {
863 if ((c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
) == EOF(-1)) {
864 yyerror("reached end of file while parsing quoted string");
865 if (file == topfile || popfile() == EOF(-1))
866 return (EOF(-1));
867 return (quotec);
868 }
869 return (c);
870 }
871
872 while ((c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
) == '\\') {
873 next = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
874 if (next != '\n') {
875 c = next;
876 break;
877 }
878 yylval.lineno = file->lineno;
879 file->lineno++;
880 }
881
882 while (c == EOF(-1)) {
883 if (file == topfile || popfile() == EOF(-1))
884 return (EOF(-1));
885 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
886 }
887 return (c);
888}
889
890int
891lungetc(int c)
892{
893 if (c == EOF(-1))
894 return (EOF(-1));
895 if (parsebuf) {
896 parseindex--;
897 if (parseindex >= 0)
898 return (c);
899 }
900 if (pushback_index + 1 >= MAXPUSHBACK128)
901 return (EOF(-1));
902 pushback_buffer[pushback_index++] = c;
903 return (c);
904}
905
906int
907findeol(void)
908{
909 int c;
910
911 parsebuf = NULL((void *)0);
912
913 /* skip to either EOF or the first real EOL */
914 while (1) {
915 if (pushback_index)
916 c = (unsigned char)pushback_buffer[--pushback_index];
917 else
918 c = lgetc(0);
919 if (c == '\n') {
920 file->lineno++;
921 break;
922 }
923 if (c == EOF(-1))
924 break;
925 }
926 return (ERROR277);
927}
928
929int
930yylex(void)
931{
932 char buf[8096];
933 char *p, *val;
934 int quotec, next, c;
935 int token;
936
937top:
938 p = buf;
939 while ((c = lgetc(0)) == ' ' || c == '\t')
940 ; /* nothing */
941
942 yylval.lineno = file->lineno;
943 if (c == '#')
944 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
945 ; /* nothing */
946 if (c == '$' && parsebuf == NULL((void *)0)) {
947 while (1) {
948 if ((c = lgetc(0)) == EOF(-1))
949 return (0);
950
951 if (p + 1 >= buf + sizeof(buf) - 1) {
952 yyerror("string too long");
953 return (findeol());
954 }
955 if (isalnum(c) || c == '_') {
956 *p++ = c;
957 continue;
958 }
959 *p = '\0';
960 lungetc(c);
961 break;
962 }
963 val = symget(buf);
964 if (val == NULL((void *)0)) {
965 yyerror("macro '%s' not defined", buf);
966 return (findeol());
967 }
968 parsebuf = val;
969 parseindex = 0;
970 goto top;
971 }
972
973 switch (c) {
974 case '\'':
975 case '"':
976 quotec = c;
977 while (1) {
978 if ((c = lgetc(quotec)) == EOF(-1))
979 return (0);
980 if (c == '\n') {
981 file->lineno++;
982 continue;
983 } else if (c == '\\') {
984 if ((next = lgetc(quotec)) == EOF(-1))
985 return (0);
986 if (next == quotec || next == ' ' ||
987 next == '\t')
988 c = next;
989 else if (next == '\n') {
990 file->lineno++;
991 continue;
992 } else
993 lungetc(next);
994 } else if (c == quotec) {
995 *p = '\0';
996 break;
997 } else if (c == '\0') {
998 yyerror("syntax error");
999 return (findeol());
1000 }
1001 if (p + 1 >= buf + sizeof(buf) - 1) {
1002 yyerror("string too long");
1003 return (findeol());
1004 }
1005 *p++ = c;
1006 }
1007 yylval.v.string = strdup(buf);
1008 if (yylval.v.string == NULL((void *)0))
1009 err(1, "%s", __func__);
1010 return (STRING308);
1011 }
1012
1013#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
1014 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
1015
1016 if (c == '-' || isdigit(c)) {
1017 do {
1018 *p++ = c;
1019 if ((size_t)(p-buf) >= sizeof(buf)) {
1020 yyerror("string too long");
1021 return (findeol());
1022 }
1023 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
1024 lungetc(c);
1025 if (p == buf + 1 && buf[0] == '-')
1026 goto nodigits;
1027 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
1028 const char *errstr = NULL((void *)0);
1029
1030 *p = '\0';
1031 yylval.v.number = strtonum(buf, LLONG_MIN(-0x7fffffffffffffffLL-1),
1032 LLONG_MAX0x7fffffffffffffffLL, &errstr);
1033 if (errstr) {
1034 yyerror("\"%s\" invalid number: %s",
1035 buf, errstr);
1036 return (findeol());
1037 }
1038 return (NUMBER309);
1039 } else {
1040nodigits:
1041 while (p > buf + 1)
1042 lungetc((unsigned char)*--p);
1043 c = (unsigned char)*--p;
1044 if (c == '-')
1045 return (c);
1046 }
1047 }
1048
1049#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '<'
&& x != '>' && x != '!' && x != '='
&& x != '/' && x != '#' && x != ',')
)
\
1050 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
1051 x != '{' && x != '}' && x != '<' && x != '>' && \
1052 x != '!' && x != '=' && x != '/' && x != '#' && \
1053 x != ','))
1054
1055 if (isalnum(c) || c == ':' || c == '_' || c == '*') {
1056 do {
1057 *p++ = c;
1058 if ((size_t)(p-buf) >= sizeof(buf)) {
1059 yyerror("string too long");
1060 return (findeol());
1061 }
1062 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '<'
&& c != '>' && c != '!' && c != '='
&& c != '/' && c != '#' && c != ',')
)
));
1063 lungetc(c);
1064 *p = '\0';
1065 if ((token = lookup(buf)) == STRING308)
1066 if ((yylval.v.string = strdup(buf)) == NULL((void *)0))
1067 err(1, "%s", __func__);
1068 return (token);
1069 }
1070 if (c == '\n') {
1071 yylval.lineno = file->lineno;
1072 file->lineno++;
1073 }
1074 if (c == EOF(-1))
1075 return (0);
1076 return (c);
1077}
1078
1079int
1080check_file_secrecy(int fd, const char *fname)
1081{
1082 struct stat st;
1083
1084 if (fstat(fd, &st)) {
1085 warn("cannot stat %s", fname);
1086 return (-1);
1087 }
1088 if (st.st_uid != 0 && st.st_uid != getuid()) {
1089 warnx("%s: owner not root or current user", fname);
1090 return (-1);
1091 }
1092 if (st.st_mode & (S_IWGRP0000020 | S_IXGRP0000010 | S_IRWXO0000007)) {
1093 warnx("%s: group writable or world read/writable", fname);
1094 return (-1);
1095 }
1096 return (0);
1097}
1098
1099struct file *
1100pushfile(const char *name, int secret)
1101{
1102 struct file *nfile;
1103
1104 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) {
1105 warn("%s", __func__);
1106 return (NULL((void *)0));
1107 }
1108 if ((nfile->name = strdup(name)) == NULL((void *)0)) {
1109 warn("%s", __func__);
1110 free(nfile);
1111 return (NULL((void *)0));
1112 }
1113 if (TAILQ_FIRST(&files)((&files)->tqh_first) == NULL((void *)0) && strcmp(nfile->name, "-") == 0) {
1114 nfile->stream = stdin(&__sF[0]);
1115 free(nfile->name);
1116 if ((nfile->name = strdup("stdin")) == NULL((void *)0)) {
1117 warn("%s", __func__);
1118 free(nfile);
1119 return (NULL((void *)0));
1120 }
1121 } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) {
1122 warn("%s: %s", __func__, nfile->name);
1123 free(nfile->name);
1124 free(nfile);
1125 return (NULL((void *)0));
1126 } else if (secret &&
1127 check_file_secrecy(fileno(nfile->stream)(!__isthreaded ? ((nfile->stream)->_file) : (fileno)(nfile
->stream))
, nfile->name)) {
1128 fclose(nfile->stream);
1129 free(nfile->name);
1130 free(nfile);
1131 return (NULL((void *)0));
1132 }
1133 nfile->lineno = 1;
1134 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
1135 return (nfile);
1136}
1137
1138int
1139popfile(void)
1140{
1141 struct file *prev;
1142
1143 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void *)0))
1144 prev->errors += file->errors;
1145
1146 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
1147 fclose(file->stream);
1148 free(file->name);
1149 free(file);
1150 file = prev;
1151
1152 return (file ? 0 : EOF(-1));
1153}
1154
1155int
1156parse_rules(const char *filename, struct ipsecctl *ipsecx)
1157{
1158 struct sym *sym;
1159 int errors = 0;
1160
1161 ipsec = ipsecx;
1162
1163 if ((file = pushfile(filename, 1)) == NULL((void *)0)) {
1
Taking false branch
1164 return (-1);
1165 }
1166 topfile = file;
1167
1168 yyparse();
1169 errors = file->errors;
1170 popfile();
1171
1172 /* Free macros and check which have not been used. */
1173 while ((sym = TAILQ_FIRST(&symhead)((&symhead)->tqh_first))) {
1174 if ((ipsec->opts & IPSECCTL_OPT_VERBOSE20x0020) && !sym->used)
2
Assuming the condition is true
3
Assuming field 'used' is not equal to 0
4
Taking false branch
9
Use of memory after it is freed
1175 fprintf(stderr(&__sF[2]), "warning: macro '%s' not "
1176 "used\n", sym->nam);
1177 free(sym->nam);
1178 free(sym->val);
1179 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
5
Assuming field 'tqe_next' is equal to null
6
Taking false branch
7
Loop condition is false. Exiting loop
1180 free(sym);
8
Memory is released
1181 }
1182
1183 return (errors ? -1 : 0);
1184}
1185
1186int
1187symset(const char *nam, const char *val, int persist)
1188{
1189 struct sym *sym;
1190
1191 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
1192 if (strcmp(nam, sym->nam) == 0)
1193 break;
1194 }
1195
1196 if (sym != NULL((void *)0)) {
1197 if (sym->persist == 1)
1198 return (0);
1199 else {
1200 free(sym->nam);
1201 free(sym->val);
1202 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
1203 free(sym);
1204 }
1205 }
1206 if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0))
1207 return (-1);
1208
1209 sym->nam = strdup(nam);
1210 if (sym->nam == NULL((void *)0)) {
1211 free(sym);
1212 return (-1);
1213 }
1214 sym->val = strdup(val);
1215 if (sym->val == NULL((void *)0)) {
1216 free(sym->nam);
1217 free(sym);
1218 return (-1);
1219 }
1220 sym->used = 0;
1221 sym->persist = persist;
1222 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry.
tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last
= (sym); (&symhead)->tqh_last = &(sym)->entry.
tqe_next; } while (0)
;
1223 return (0);
1224}
1225
1226int
1227cmdline_symset(char *s)
1228{
1229 char *sym, *val;
1230 int ret;
1231
1232 if ((val = strrchr(s, '=')) == NULL((void *)0))
1233 return (-1);
1234
1235 sym = strndup(s, val - s);
1236 if (sym == NULL((void *)0))
1237 err(1, "%s", __func__);
1238 ret = symset(sym, val + 1, 1);
1239 free(sym);
1240
1241 return (ret);
1242}
1243
1244char *
1245symget(const char *nam)
1246{
1247 struct sym *sym;
1248
1249 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
1250 if (strcmp(nam, sym->nam) == 0) {
1251 sym->used = 1;
1252 return (sym->val);
1253 }
1254 }
1255 return (NULL((void *)0));
1256}
1257
1258int
1259atoul(char *s, u_long *ulvalp)
1260{
1261 u_long ulval;
1262 char *ep;
1263
1264 errno(*__errno()) = 0;
1265 ulval = strtoul(s, &ep, 0);
1266 if (s[0] == '\0' || *ep != '\0')
1267 return (-1);
1268 if (errno(*__errno()) == ERANGE34 && ulval == ULONG_MAX0xffffffffffffffffUL)
1269 return (-1);
1270 *ulvalp = ulval;
1271 return (0);
1272}
1273
1274int
1275atospi(char *s, u_int32_t *spivalp)
1276{
1277 unsigned long ulval;
1278
1279 if (atoul(s, &ulval) == -1)
1280 return (-1);
1281 if (ulval > UINT_MAX0xffffffffU) {
1282 yyerror("%lu not a valid spi", ulval);
1283 return (-1);
1284 }
1285 if (ulval >= SPI_RESERVED_MIN1 && ulval <= SPI_RESERVED_MAX255) {
1286 yyerror("%lu within reserved spi range", ulval);
1287 return (-1);
1288 }
1289 *spivalp = ulval;
1290 return (0);
1291}
1292
1293u_int8_t
1294x2i(unsigned char *s)
1295{
1296 char ss[3];
1297
1298 ss[0] = s[0];
1299 ss[1] = s[1];
1300 ss[2] = 0;
1301
1302 if (!isxdigit(s[0]) || !isxdigit(s[1])) {
1303 yyerror("keys need to be specified in hex digits");
1304 return (-1);
1305 }
1306 return ((u_int8_t)strtoul(ss, NULL((void *)0), 16));
1307}
1308
1309struct ipsec_key *
1310parsekey(unsigned char *hexkey, size_t len)
1311{
1312 struct ipsec_key *key;
1313 int i;
1314
1315 key = calloc(1, sizeof(struct ipsec_key));
1316 if (key == NULL((void *)0))
1317 err(1, "%s", __func__);
1318
1319 key->len = len / 2;
1320 key->data = calloc(key->len, sizeof(u_int8_t));
1321 if (key->data == NULL((void *)0))
1322 err(1, "%s", __func__);
1323
1324 for (i = 0; i < (int)key->len; i++)
1325 key->data[i] = x2i(hexkey + 2 * i);
1326
1327 return (key);
1328}
1329
1330struct ipsec_key *
1331parsekeyfile(char *filename)
1332{
1333 struct stat sb;
1334 int fd;
1335 unsigned char *hex;
1336
1337 if ((fd = open(filename, O_RDONLY0x0000)) < 0)
1338 err(1, "open %s", filename);
1339 if (fstat(fd, &sb) < 0)
1340 err(1, "parsekeyfile: stat %s", filename);
1341 if ((sb.st_size > KEYSIZE_LIMIT1024) || (sb.st_size == 0))
1342 errx(1, "%s: key too %s", filename, sb.st_size ? "large" :
1343 "small");
1344 if ((hex = calloc(sb.st_size, sizeof(unsigned char))) == NULL((void *)0))
1345 err(1, "%s", __func__);
1346 if (read(fd, hex, sb.st_size) < sb.st_size)
1347 err(1, "parsekeyfile: read");
1348 close(fd);
1349 return (parsekey(hex, sb.st_size));
1350}
1351
1352int
1353get_id_type(char *string)
1354{
1355 struct in6_addr ia;
1356
1357 if (string == NULL((void *)0))
1358 return (ID_UNKNOWN);
1359
1360 if (inet_pton(AF_INET2, string, &ia) == 1)
1361 return (ID_IPV4);
1362 else if (inet_pton(AF_INET624, string, &ia) == 1)
1363 return (ID_IPV6);
1364 else if (strchr(string, '@'))
1365 return (ID_UFQDN);
1366 else
1367 return (ID_FQDN);
1368}
1369
1370struct ipsec_addr_wrap *
1371host(const char *s)
1372{
1373 struct ipsec_addr_wrap *ipa = NULL((void *)0);
1374 int mask, cont = 1;
1375 char *p, *q, *ps;
1376
1377 if ((p = strrchr(s, '/')) != NULL((void *)0)) {
1378 errno(*__errno()) = 0;
1379 mask = strtol(p + 1, &q, 0);
1380 if (errno(*__errno()) == ERANGE34 || !q || *q || mask > 128 || q == (p + 1))
1381 errx(1, "host: invalid netmask '%s'", p);
1382 if ((ps = malloc(strlen(s) - strlen(p) + 1)) == NULL((void *)0))
1383 err(1, "%s", __func__);
1384 strlcpy(ps, s, strlen(s) - strlen(p) + 1);
1385 } else {
1386 if ((ps = strdup(s)) == NULL((void *)0))
1387 err(1, "%s", __func__);
1388 mask = -1;
1389 }
1390
1391 /* Does interface with this name exist? */
1392 if (cont && (ipa = host_if(ps, mask)) != NULL((void *)0))
1393 cont = 0;
1394
1395 /* IPv4 address? */
1396 if (cont && (ipa = host_v4(s, mask == -1 ? 32 : mask)) != NULL((void *)0))
1397 cont = 0;
1398
1399 /* IPv6 address? */
1400 if (cont && (ipa = host_v6(ps, mask == -1 ? 128 : mask)) != NULL((void *)0))
1401 cont = 0;
1402
1403 /* dns lookup */
1404 if (cont && mask == -1 && (ipa = host_dns(s, mask)) != NULL((void *)0))
1405 cont = 0;
1406 free(ps);
1407
1408 if (ipa == NULL((void *)0) || cont == 1) {
1409 fprintf(stderr(&__sF[2]), "no IP address found for %s\n", s);
1410 return (NULL((void *)0));
1411 }
1412 return (ipa);
1413}
1414
1415struct ipsec_addr_wrap *
1416host_v6(const char *s, int prefixlen)
1417{
1418 struct ipsec_addr_wrap *ipa = NULL((void *)0);
1419 struct addrinfo hints, *res;
1420 char hbuf[NI_MAXHOST256];
1421
1422 bzero(&hints, sizeof(struct addrinfo));
1423 hints.ai_family = AF_INET624;
1424 hints.ai_socktype = SOCK_STREAM1;
1425 hints.ai_flags = AI_NUMERICHOST4;
1426 if (getaddrinfo(s, NULL((void *)0), &hints, &res))
1427 return (NULL((void *)0));
1428 if (res->ai_next)
1429 err(1, "host_v6: numeric hostname expanded to multiple item");
1430
1431 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1432 if (ipa == NULL((void *)0))
1433 err(1, "%s", __func__);
1434 ipa->af = res->ai_family;
1435 memcpy(&ipa->address.v6ipa.v6,
1436 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1437 sizeof(struct in6_addr));
1438 if (prefixlen > 128)
1439 prefixlen = 128;
1440 ipa->next = NULL((void *)0);
1441 ipa->tail = ipa;
1442
1443 set_ipmask(ipa, prefixlen);
1444 if (getnameinfo(res->ai_addr, res->ai_addrlen,
1445 hbuf, sizeof(hbuf), NULL((void *)0), 0, NI_NUMERICHOST1)) {
1446 errx(1, "could not get a numeric hostname");
1447 }
1448
1449 if (prefixlen != 128) {
1450 ipa->netaddress = 1;
1451 if (asprintf(&ipa->name, "%s/%d", hbuf, prefixlen) == -1)
1452 err(1, "%s", __func__);
1453 } else {
1454 if ((ipa->name = strdup(hbuf)) == NULL((void *)0))
1455 err(1, "%s", __func__);
1456 }
1457
1458 freeaddrinfo(res);
1459
1460 return (ipa);
1461}
1462
1463struct ipsec_addr_wrap *
1464host_v4(const char *s, int mask)
1465{
1466 struct ipsec_addr_wrap *ipa = NULL((void *)0);
1467 struct in_addr ina;
1468 int bits = 32;
1469
1470 bzero(&ina, sizeof(struct in_addr));
1471 if (strrchr(s, '/') != NULL((void *)0)) {
1472 if ((bits = inet_net_pton(AF_INET2, s, &ina, sizeof(ina))) == -1)
1473 return (NULL((void *)0));
1474 } else {
1475 if (inet_pton(AF_INET2, s, &ina) != 1)
1476 return (NULL((void *)0));
1477 }
1478
1479 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1480 if (ipa == NULL((void *)0))
1481 err(1, "%s", __func__);
1482
1483 ipa->address.v4ipa.v4 = ina;
1484 ipa->name = strdup(s);
1485 if (ipa->name == NULL((void *)0))
1486 err(1, "%s", __func__);
1487 ipa->af = AF_INET2;
1488 ipa->next = NULL((void *)0);
1489 ipa->tail = ipa;
1490
1491 set_ipmask(ipa, bits);
1492 if (strrchr(s, '/') != NULL((void *)0))
1493 ipa->netaddress = 1;
1494
1495 return (ipa);
1496}
1497
1498struct ipsec_addr_wrap *
1499host_dns(const char *s, int mask)
1500{
1501 struct ipsec_addr_wrap *ipa = NULL((void *)0), *head = NULL((void *)0);
1502 struct addrinfo hints, *res0, *res;
1503 int error;
1504 char hbuf[NI_MAXHOST256];
1505
1506 bzero(&hints, sizeof(struct addrinfo));
1507 hints.ai_family = PF_UNSPEC0;
1508 hints.ai_socktype = SOCK_STREAM1;
1509 error = getaddrinfo(s, NULL((void *)0), &hints, &res0);
1510 if (error)
1511 return (NULL((void *)0));
1512
1513 for (res = res0; res; res = res->ai_next) {
1514 if (res->ai_family != AF_INET2 && res->ai_family != AF_INET624)
1515 continue;
1516
1517 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1518 if (ipa == NULL((void *)0))
1519 err(1, "%s", __func__);
1520 switch (res->ai_family) {
1521 case AF_INET2:
1522 memcpy(&ipa->address.v4ipa.v4,
1523 &((struct sockaddr_in *)res->ai_addr)->sin_addr,
1524 sizeof(struct in_addr));
1525 break;
1526 case AF_INET624:
1527 /* XXX we do not support scoped IPv6 address yet */
1528 if (((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id) {
1529 free(ipa);
1530 continue;
1531 }
1532 memcpy(&ipa->address.v6ipa.v6,
1533 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
1534 sizeof(struct in6_addr));
1535 break;
1536 }
1537 error = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
1538 sizeof(hbuf), NULL((void *)0), 0, NI_NUMERICHOST1);
1539 if (error)
1540 err(1, "host_dns: getnameinfo");
1541 ipa->name = strdup(hbuf);
1542 if (ipa->name == NULL((void *)0))
1543 err(1, "%s", __func__);
1544 ipa->af = res->ai_family;
1545 ipa->next = NULL((void *)0);
1546 ipa->tail = ipa;
1547 if (head == NULL((void *)0))
1548 head = ipa;
1549 else {
1550 head->tail->next = ipa;
1551 head->tail = ipa;
1552 }
1553
1554 /*
1555 * XXX for now, no netmask support for IPv6.
1556 * but since there's no way to specify address family, once you
1557 * have IPv6 address on a host, you cannot use dns/netmask
1558 * syntax.
1559 */
1560 if (ipa->af == AF_INET2)
1561 set_ipmask(ipa, mask == -1 ? 32 : mask);
1562 else
1563 if (mask != -1)
1564 err(1, "host_dns: cannot apply netmask "
1565 "on non-IPv4 address");
1566 }
1567 freeaddrinfo(res0);
1568
1569 return (head);
1570}
1571
1572struct ipsec_addr_wrap *
1573host_if(const char *s, int mask)
1574{
1575 struct ipsec_addr_wrap *ipa = NULL((void *)0);
1576
1577 if (ifa_exists(s))
1578 ipa = ifa_lookup(s);
1579
1580 return (ipa);
1581}
1582
1583struct ipsec_addr_wrap *
1584host_any(void)
1585{
1586 struct ipsec_addr_wrap *ipa;
1587
1588 ipa = calloc(1, sizeof(struct ipsec_addr_wrap));
1589 if (ipa == NULL((void *)0))
1590 err(1, "%s", __func__);
1591 ipa->af = AF_UNSPEC0;
1592 ipa->netaddress = 1;
1593 ipa->tail = ipa;
1594 return (ipa);
1595}
1596
1597/* interface lookup routintes */
1598
1599struct ipsec_addr_wrap *iftab;
1600
1601void
1602ifa_load(void)
1603{
1604 struct ifaddrs *ifap, *ifa;
1605 struct ipsec_addr_wrap *n = NULL((void *)0), *h = NULL((void *)0);
1606
1607 if (getifaddrs(&ifap) < 0)
1608 err(1, "ifa_load: getifaddrs");
1609
1610 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
1611 if (ifa->ifa_addr == NULL((void *)0) ||
1612 !(ifa->ifa_addr->sa_family == AF_INET2 ||
1613 ifa->ifa_addr->sa_family == AF_INET624 ||
1614 ifa->ifa_addr->sa_family == AF_LINK18))
1615 continue;
1616 n = calloc(1, sizeof(struct ipsec_addr_wrap));
1617 if (n == NULL((void *)0))
1618 err(1, "%s", __func__);
1619 n->af = ifa->ifa_addr->sa_family;
1620 if ((n->name = strdup(ifa->ifa_name)) == NULL((void *)0))
1621 err(1, "%s", __func__);
1622 if (n->af == AF_INET2) {
1623 n->af = AF_INET2;
1624 memcpy(&n->address.v4ipa.v4, &((struct sockaddr_in *)
1625 ifa->ifa_addr)->sin_addr,
1626 sizeof(struct in_addr));
1627 memcpy(&n->mask.v4ipa.v4, &((struct sockaddr_in *)
1628 ifa->ifa_netmask)->sin_addr,
1629 sizeof(struct in_addr));
1630 } else if (n->af == AF_INET624) {
1631 n->af = AF_INET624;
1632 memcpy(&n->address.v6ipa.v6, &((struct sockaddr_in6 *)
1633 ifa->ifa_addr)->sin6_addr,
1634 sizeof(struct in6_addr));
1635 memcpy(&n->mask.v6ipa.v6, &((struct sockaddr_in6 *)
1636 ifa->ifa_netmask)->sin6_addr,
1637 sizeof(struct in6_addr));
1638 }
1639 n->next = NULL((void *)0);
1640 n->tail = n;
1641 if (h == NULL((void *)0))
1642 h = n;
1643 else {
1644 h->tail->next = n;
1645 h->tail = n;
1646 }
1647 }
1648
1649 iftab = h;
1650 freeifaddrs(ifap);
1651}
1652
1653int
1654ifa_exists(const char *ifa_name)
1655{
1656 struct ipsec_addr_wrap *n;
1657 struct ifgroupreq ifgr;
1658 int s;
1659
1660 if (iftab == NULL((void *)0))
1661 ifa_load();
1662
1663 /* check whether this is a group */
1664 if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1)
1665 err(1, "ifa_exists: socket");
1666 bzero(&ifgr, sizeof(ifgr));
1667 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1668 if (ioctl(s, SIOCGIFGMEMB(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((138)))
, (caddr_t)&ifgr) == 0) {
1669 close(s);
1670 return (1);
1671 }
1672 close(s);
1673
1674 for (n = iftab; n; n = n->next) {
1675 if (n->af == AF_LINK18 && !strncmp(n->name, ifa_name,
1676 IFNAMSIZ16))
1677 return (1);
1678 }
1679
1680 return (0);
1681}
1682
1683struct ipsec_addr_wrap *
1684ifa_grouplookup(const char *ifa_name)
1685{
1686 struct ifg_req *ifg;
1687 struct ifgroupreq ifgr;
1688 int s;
1689 size_t len;
1690 struct ipsec_addr_wrap *n, *h = NULL((void *)0), *hn;
1691
1692 if ((s = socket(AF_INET2, SOCK_DGRAM2, 0)) == -1)
1693 err(1, "socket");
1694 bzero(&ifgr, sizeof(ifgr));
1695 strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
1696 if (ioctl(s, SIOCGIFGMEMB(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((138)))
, (caddr_t)&ifgr) == -1) {
1697 close(s);
1698 return (NULL((void *)0));
1699 }
1700
1701 len = ifgr.ifgr_len;
1702 if ((ifgr.ifgr_groupsifgr_ifgru.ifgru_groups = calloc(1, len)) == NULL((void *)0))
1703 err(1, "%s", __func__);
1704 if (ioctl(s, SIOCGIFGMEMB(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct ifgroupreq) & 0x1fff) << 16) | ((('i')) <<
8) | ((138)))
, (caddr_t)&ifgr) == -1)
1705 err(1, "ioctl");
1706
1707 for (ifg = ifgr.ifgr_groupsifgr_ifgru.ifgru_groups; ifg && len >= sizeof(struct ifg_req);
1708 ifg++) {
1709 len -= sizeof(struct ifg_req);
1710 if ((n = ifa_lookup(ifg->ifgrq_memberifgrq_ifgrqu.ifgrqu_member)) == NULL((void *)0))
1711 continue;
1712 if (h == NULL((void *)0))
1713 h = n;
1714 else {
1715 for (hn = h; hn->next != NULL((void *)0); hn = hn->next)
1716 ; /* nothing */
1717 hn->next = n;
1718 n->tail = hn;
1719 }
1720 }
1721 free(ifgr.ifgr_groupsifgr_ifgru.ifgru_groups);
1722 close(s);
1723
1724 return (h);
1725}
1726
1727struct ipsec_addr_wrap *
1728ifa_lookup(const char *ifa_name)
1729{
1730 struct ipsec_addr_wrap *p = NULL((void *)0), *h = NULL((void *)0), *n = NULL((void *)0);
1731
1732 if (iftab == NULL((void *)0))
1733 ifa_load();
1734
1735 if ((n = ifa_grouplookup(ifa_name)) != NULL((void *)0))
1736 return (n);
1737
1738 for (p = iftab; p; p = p->next) {
1739 if (p->af != AF_INET2 && p->af != AF_INET624)
1740 continue;
1741 if (strncmp(p->name, ifa_name, IFNAMSIZ16))
1742 continue;
1743 n = calloc(1, sizeof(struct ipsec_addr_wrap));
1744 if (n == NULL((void *)0))
1745 err(1, "%s", __func__);
1746 memcpy(n, p, sizeof(struct ipsec_addr_wrap));
1747 if ((n->name = strdup(p->name)) == NULL((void *)0))
1748 err(1, "%s", __func__);
1749 switch (n->af) {
1750 case AF_INET2:
1751 set_ipmask(n, 32);
1752 break;
1753 case AF_INET624:
1754 /* route/show.c and bgpd/util.c give KAME credit */
1755 if (IN6_IS_ADDR_LINKLOCAL(&n->address.v6)(((&n->address.ipa.v6)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&n->address.ipa.v6)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))
) {
1756 u_int16_t tmp16;
1757 /* for now we can not handle link local,
1758 * therefore bail for now
1759 */
1760 free(n);
1761 continue;
1762
1763 memcpy(&tmp16, &n->address.v6ipa.v6.s6_addr__u6_addr.__u6_addr8[2],
1764 sizeof(tmp16));
1765 /* use this when we support link-local
1766 * n->??.scopeid = ntohs(tmp16);
1767 */
1768 n->address.v6ipa.v6.s6_addr__u6_addr.__u6_addr8[2] = 0;
1769 n->address.v6ipa.v6.s6_addr__u6_addr.__u6_addr8[3] = 0;
1770 }
1771 set_ipmask(n, 128);
1772 break;
1773 }
1774
1775 n->next = NULL((void *)0);
1776 n->tail = n;
1777 if (h == NULL((void *)0))
1778 h = n;
1779 else {
1780 h->tail->next = n;
1781 h->tail = n;
1782 }
1783 }
1784
1785 return (h);
1786}
1787
1788void
1789set_ipmask(struct ipsec_addr_wrap *address, u_int8_t b)
1790{
1791 struct ipsec_addr *ipa;
1792 int i, j = 0;
1793
1794 ipa = &address->mask;
1795 bzero(ipa, sizeof(struct ipsec_addr));
1796
1797 while (b >= 32) {
1798 ipa->addr32ipa.addr32[j++] = 0xffffffff;
1799 b -= 32;
1800 }
1801 for (i = 31; i > 31 - b; --i)
1802 ipa->addr32ipa.addr32[j] |= (1 << i);
1803 if (b)
1804 ipa->addr32ipa.addr32[j] = htonl(ipa->addr32[j])(__uint32_t)(__builtin_constant_p(ipa->ipa.addr32[j]) ? (__uint32_t
)(((__uint32_t)(ipa->ipa.addr32[j]) & 0xff) << 24
| ((__uint32_t)(ipa->ipa.addr32[j]) & 0xff00) <<
8 | ((__uint32_t)(ipa->ipa.addr32[j]) & 0xff0000) >>
8 | ((__uint32_t)(ipa->ipa.addr32[j]) & 0xff000000) >>
24) : __swap32md(ipa->ipa.addr32[j]))
;
1805}
1806
1807const struct ipsec_xf *
1808parse_xf(const char *name, const struct ipsec_xf xfs[])
1809{
1810 int i;
1811
1812 for (i = 0; xfs[i].name != NULL((void *)0); i++) {
1813 if (strncmp(name, xfs[i].name, strlen(name)))
1814 continue;
1815 return &xfs[i];
1816 }
1817 return (NULL((void *)0));
1818}
1819
1820struct ipsec_lifetime *
1821parse_life(const char *value)
1822{
1823 struct ipsec_lifetime *life;
1824 int ret;
1825 int seconds = 0;
1826 char unit = 0;
1827
1828 ret = sscanf(value, "%d%c", &seconds, &unit);
1829 if (ret == 2) {
1830 switch (tolower((unsigned char)unit)) {
1831 case 'm':
1832 seconds *= 60;
1833 break;
1834 case 'h':
1835 seconds *= 60 * 60;
1836 break;
1837 default:
1838 err(1, "invalid time unit");
1839 }
1840 } else if (ret != 1)
1841 err(1, "invalid time specification: %s", value);
1842
1843 life = calloc(1, sizeof(struct ipsec_lifetime));
1844 if (life == NULL((void *)0))
1845 err(1, "%s", __func__);
1846
1847 life->lt_seconds = seconds;
1848 life->lt_bytes = -1;
1849
1850 return (life);
1851}
1852
1853struct ipsec_transforms *
1854copytransforms(const struct ipsec_transforms *xfs)
1855{
1856 struct ipsec_transforms *newxfs;
1857
1858 if (xfs == NULL((void *)0))
1859 return (NULL((void *)0));
1860
1861 newxfs = calloc(1, sizeof(struct ipsec_transforms));
1862 if (newxfs == NULL((void *)0))
1863 err(1, "%s", __func__);
1864
1865 memcpy(newxfs, xfs, sizeof(struct ipsec_transforms));
1866 return (newxfs);
1867}
1868
1869struct ipsec_lifetime *
1870copylife(const struct ipsec_lifetime *life)
1871{
1872 struct ipsec_lifetime *newlife;
1873
1874 if (life == NULL((void *)0))
1875 return (NULL((void *)0));
1876
1877 newlife = calloc(1, sizeof(struct ipsec_lifetime));
1878 if (newlife == NULL((void *)0))
1879 err(1, "%s", __func__);
1880
1881 memcpy(newlife, life, sizeof(struct ipsec_lifetime));
1882 return (newlife);
1883}
1884
1885struct ipsec_auth *
1886copyipsecauth(const struct ipsec_auth *auth)
1887{
1888 struct ipsec_auth *newauth;
1889
1890 if (auth == NULL((void *)0))
1891 return (NULL((void *)0));
1892
1893 if ((newauth = calloc(1, sizeof(struct ipsec_auth))) == NULL((void *)0))
1894 err(1, "%s", __func__);
1895 if (auth->srcid &&
1896 asprintf(&newauth->srcid, "%s", auth->srcid) == -1)
1897 err(1, "%s", __func__);
1898 if (auth->dstid &&
1899 asprintf(&newauth->dstid, "%s", auth->dstid) == -1)
1900 err(1, "%s", __func__);
1901
1902 newauth->srcid_type = auth->srcid_type;
1903 newauth->dstid_type = auth->dstid_type;
1904 newauth->type = auth->type;
1905
1906 return (newauth);
1907}
1908
1909struct ike_auth *
1910copyikeauth(const struct ike_auth *auth)
1911{
1912 struct ike_auth *newauth;
1913
1914 if (auth == NULL((void *)0))
1915 return (NULL((void *)0));
1916
1917 if ((newauth = calloc(1, sizeof(struct ike_auth))) == NULL((void *)0))
1918 err(1, "%s", __func__);
1919 if (auth->string &&
1920 asprintf(&newauth->string, "%s", auth->string) == -1)
1921 err(1, "%s", __func__);
1922
1923 newauth->type = auth->type;
1924
1925 return (newauth);
1926}
1927
1928struct ipsec_key *
1929copykey(struct ipsec_key *key)
1930{
1931 struct ipsec_key *newkey;
1932
1933 if (key == NULL((void *)0))
1934 return (NULL((void *)0));
1935
1936 if ((newkey = calloc(1, sizeof(struct ipsec_key))) == NULL((void *)0))
1937 err(1, "%s", __func__);
1938 if ((newkey->data = calloc(key->len, sizeof(u_int8_t))) == NULL((void *)0))
1939 err(1, "%s", __func__);
1940 memcpy(newkey->data, key->data, key->len);
1941 newkey->len = key->len;
1942
1943 return (newkey);
1944}
1945
1946struct ipsec_addr_wrap *
1947copyhost(const struct ipsec_addr_wrap *src)
1948{
1949 struct ipsec_addr_wrap *dst;
1950
1951 if (src == NULL((void *)0))
1952 return (NULL((void *)0));
1953
1954 dst = calloc(1, sizeof(struct ipsec_addr_wrap));
1955 if (dst == NULL((void *)0))
1956 err(1, "%s", __func__);
1957
1958 memcpy(dst, src, sizeof(struct ipsec_addr_wrap));
1959
1960 if (src->name != NULL((void *)0) && (dst->name = strdup(src->name)) == NULL((void *)0))
1961 err(1, "%s", __func__);
1962
1963 return dst;
1964}
1965
1966char *
1967copytag(const char *src)
1968{
1969 char *tag;
1970
1971 if (src == NULL((void *)0))
1972 return (NULL((void *)0));
1973 if ((tag = strdup(src)) == NULL((void *)0))
1974 err(1, "%s", __func__);
1975
1976 return (tag);
1977}
1978
1979struct ipsec_rule *
1980copyrule(struct ipsec_rule *rule)
1981{
1982 struct ipsec_rule *r;
1983
1984 if ((r = calloc(1, sizeof(struct ipsec_rule))) == NULL((void *)0))
1985 err(1, "%s", __func__);
1986
1987 r->src = copyhost(rule->src);
1988 r->dst = copyhost(rule->dst);
1989 r->local = copyhost(rule->local);
1990 r->peer = copyhost(rule->peer);
1991 r->auth = copyipsecauth(rule->auth);
1992 r->ikeauth = copyikeauth(rule->ikeauth);
1993 r->xfs = copytransforms(rule->xfs);
1994 r->p1xfs = copytransforms(rule->p1xfs);
1995 r->p2xfs = copytransforms(rule->p2xfs);
1996 r->p1life = copylife(rule->p1life);
1997 r->p2life = copylife(rule->p2life);
1998 r->authkey = copykey(rule->authkey);
1999 r->enckey = copykey(rule->enckey);
2000 r->tag = copytag(rule->tag);
2001
2002 r->flags = rule->flags;
2003 r->p1ie = rule->p1ie;
2004 r->p2ie = rule->p2ie;
2005 r->type = rule->type;
2006 r->satype = rule->satype;
2007 r->proto = rule->proto;
2008 r->tmode = rule->tmode;
2009 r->direction = rule->direction;
2010 r->flowtype = rule->flowtype;
2011 r->sport = rule->sport;
2012 r->dport = rule->dport;
2013 r->ikemode = rule->ikemode;
2014 r->spi = rule->spi;
2015 r->udpencap = rule->udpencap;
2016 r->udpdport = rule->udpdport;
2017 r->nr = rule->nr;
2018 r->iface = rule->iface;
2019
2020 return (r);
2021}
2022
2023int
2024validate_af(struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst)
2025{
2026 struct ipsec_addr_wrap *ta;
2027 u_int8_t src_v4 = 0;
2028 u_int8_t dst_v4 = 0;
2029 u_int8_t src_v6 = 0;
2030 u_int8_t dst_v6 = 0;
2031
2032 for (ta = src; ta; ta = ta->next) {
2033 if (ta->af == AF_INET2)
2034 src_v4 = 1;
2035 if (ta->af == AF_INET624)
2036 src_v6 = 1;
2037 if (ta->af == AF_UNSPEC0)
2038 return 0;
2039 if (src_v4 && src_v6)
2040 break;
2041 }
2042 for (ta = dst; ta; ta = ta->next) {
2043 if (ta->af == AF_INET2)
2044 dst_v4 = 1;
2045 if (ta->af == AF_INET624)
2046 dst_v6 = 1;
2047 if (ta->af == AF_UNSPEC0)
2048 return 0;
2049 if (dst_v4 && dst_v6)
2050 break;
2051 }
2052 if (src_v4 != dst_v4 && src_v6 != dst_v6)
2053 return (1);
2054
2055 return (0);
2056}
2057
2058
2059int
2060validate_sa(u_int32_t spi, u_int8_t satype, struct ipsec_transforms *xfs,
2061 struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode)
2062{
2063 /* Sanity checks */
2064 if (spi == 0) {
2065 yyerror("no SPI specified");
2066 return (0);
2067 }
2068 if (satype == IPSEC_AH) {
2069 if (!xfs) {
2070 yyerror("no transforms specified");
2071 return (0);
2072 }
2073 if (!xfs->authxf)
2074 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2075 if (xfs->encxf) {
2076 yyerror("ah does not provide encryption");
2077 return (0);
2078 }
2079 if (xfs->compxf) {
2080 yyerror("ah does not provide compression");
2081 return (0);
2082 }
2083 }
2084 if (satype == IPSEC_ESP) {
2085 if (!xfs) {
2086 yyerror("no transforms specified");
2087 return (0);
2088 }
2089 if (xfs->compxf) {
2090 yyerror("esp does not provide compression");
2091 return (0);
2092 }
2093 if (!xfs->encxf)
2094 xfs->encxf = &encxfs[ENCXF_AES];
2095 if (xfs->encxf->nostatic) {
2096 yyerror("%s is disallowed with static keys",
2097 xfs->encxf->name);
2098 return 0;
2099 }
2100 if (xfs->encxf->noauth && xfs->authxf) {
2101 yyerror("authentication is implicit for %s",
2102 xfs->encxf->name);
2103 return (0);
2104 } else if (!xfs->encxf->noauth && !xfs->authxf)
2105 xfs->authxf = &authxfs[AUTHXF_HMAC_SHA2_256];
2106 }
2107 if (satype == IPSEC_IPCOMP) {
2108 if (!xfs) {
2109 yyerror("no transform specified");
2110 return (0);
2111 }
2112 if (xfs->authxf || xfs->encxf) {
2113 yyerror("no encryption or authentication with ipcomp");
2114 return (0);
2115 }
2116 if (!xfs->compxf)
2117 xfs->compxf = &compxfs[COMPXF_DEFLATE];
2118 }
2119 if (satype == IPSEC_IPIP) {
2120 if (!xfs) {
2121 yyerror("no transform specified");
2122 return (0);
2123 }
2124 if (xfs->authxf || xfs->encxf || xfs->compxf) {
2125 yyerror("no encryption, authentication or compression"
2126 " with ipip");
2127 return (0);
2128 }
2129 }
2130 if (satype == IPSEC_TCPMD5 && authkey == NULL((void *)0) && tmode !=
2131 IPSEC_TRANSPORT) {
2132 yyerror("authentication key needed for tcpmd5");
2133 return (0);
2134 }
2135 if (xfs && xfs->authxf) {
2136 if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
2137 yyerror("no authentication key specified");
2138 return (0);
2139 }
2140 if (authkey && authkey->len != xfs->authxf->keymin) {
2141 yyerror("wrong authentication key length, needs to be "
2142 "%zu bits", xfs->authxf->keymin * 8);
2143 return (0);
2144 }
2145 }
2146 if (xfs && xfs->encxf) {
2147 if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
2148 yyerror("no encryption key specified");
2149 return (0);
2150 }
2151 if (enckey) {
2152 if (enckey->len < xfs->encxf->keymin) {
2153 yyerror("encryption key too short (%zu bits), "
2154 "minimum %zu bits", enckey->len * 8,
2155 xfs->encxf->keymin * 8);
2156 return (0);
2157 }
2158 if (xfs->encxf->keymax < enckey->len) {
2159 yyerror("encryption key too long (%zu bits), "
2160 "maximum %zu bits", enckey->len * 8,
2161 xfs->encxf->keymax * 8);
2162 return (0);
2163 }
2164 }
2165 }
2166
2167 return 1;
2168}
2169
2170int
2171add_sabundle(struct ipsec_rule *r, char *bundle)
2172{
2173 struct ipsec_rule *rp, *last, *sabundle;
2174 int found = 0;
2175
2176 TAILQ_FOREACH(rp, &ipsec->bundle_queue, bundle_entry)for((rp) = ((&ipsec->bundle_queue)->tqh_first); (rp
) != ((void *)0); (rp) = ((rp)->bundle_entry.tqe_next))
{
2177 if ((strcmp(rp->src->name, r->src->name) == 0) &&
2178 (strcmp(rp->dst->name, r->dst->name) == 0) &&
2179 (strcmp(rp->bundle, bundle) == 0)) {
2180 found = 1;
2181 break;
2182 }
2183 }
2184 if (found) {
2185 last = TAILQ_LAST(&rp->dst_bundle_queue, dst_bundle_queue)(*(((struct dst_bundle_queue *)((&rp->dst_bundle_queue
)->tqh_last))->tqh_last))
;
2186 TAILQ_INSERT_TAIL(&rp->dst_bundle_queue, r, dst_bundle_entry)do { (r)->dst_bundle_entry.tqe_next = ((void *)0); (r)->
dst_bundle_entry.tqe_prev = (&rp->dst_bundle_queue)->
tqh_last; *(&rp->dst_bundle_queue)->tqh_last = (r);
(&rp->dst_bundle_queue)->tqh_last = &(r)->dst_bundle_entry
.tqe_next; } while (0)
;
2187
2188 sabundle = create_sabundle(last->dst, last->satype, last->spi,
2189 r->dst, r->satype, r->spi);
2190 if (sabundle == NULL((void *)0))
2191 return (1);
2192 sabundle->nr = ipsec->rule_nr++;
2193 if (ipsecctl_add_rule(ipsec, sabundle))
2194 return (1);
2195 } else {
2196 TAILQ_INSERT_TAIL(&ipsec->bundle_queue, r, bundle_entry)do { (r)->bundle_entry.tqe_next = ((void *)0); (r)->bundle_entry
.tqe_prev = (&ipsec->bundle_queue)->tqh_last; *(&
ipsec->bundle_queue)->tqh_last = (r); (&ipsec->bundle_queue
)->tqh_last = &(r)->bundle_entry.tqe_next; } while (
0)
;
2197 TAILQ_INIT(&r->dst_bundle_queue)do { (&r->dst_bundle_queue)->tqh_first = ((void *)0
); (&r->dst_bundle_queue)->tqh_last = &(&r->
dst_bundle_queue)->tqh_first; } while (0)
;
2198 TAILQ_INSERT_TAIL(&r->dst_bundle_queue, r, dst_bundle_entry)do { (r)->dst_bundle_entry.tqe_next = ((void *)0); (r)->
dst_bundle_entry.tqe_prev = (&r->dst_bundle_queue)->
tqh_last; *(&r->dst_bundle_queue)->tqh_last = (r); (
&r->dst_bundle_queue)->tqh_last = &(r)->dst_bundle_entry
.tqe_next; } while (0)
;
2199 r->bundle = bundle;
2200 }
2201
2202 return (0);
2203}
2204
2205struct ipsec_rule *
2206create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts,
2207 u_int32_t spi, u_int8_t udpencap, u_int16_t udpdport,
2208 struct ipsec_transforms *xfs, struct ipsec_key *authkey, struct ipsec_key *enckey)
2209{
2210 struct ipsec_rule *r;
2211
2212 if (validate_sa(spi, satype, xfs, authkey, enckey, tmode) == 0)
2213 return (NULL((void *)0));
2214
2215 r = calloc(1, sizeof(struct ipsec_rule));
2216 if (r == NULL((void *)0))
2217 err(1, "%s", __func__);
2218
2219 r->type |= RULE_SA0x02;
2220 r->satype = satype;
2221 r->tmode = tmode;
2222 r->src = hosts->src;
2223 r->dst = hosts->dst;
2224 r->spi = spi;
2225 r->udpencap = udpencap;
2226 r->udpdport = udpdport;
2227 r->xfs = xfs;
2228 r->authkey = authkey;
2229 r->enckey = enckey;
2230
2231 return r;
2232}
2233
2234struct ipsec_rule *
2235reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey,
2236 struct ipsec_key *enckey)
2237{
2238 struct ipsec_rule *reverse;
2239
2240 if (validate_sa(spi, rule->satype, rule->xfs, authkey, enckey,
2241 rule->tmode) == 0)
2242 return (NULL((void *)0));
2243
2244 reverse = calloc(1, sizeof(struct ipsec_rule));
2245 if (reverse == NULL((void *)0))
2246 err(1, "%s", __func__);
2247
2248 reverse->type |= RULE_SA0x02;
2249 reverse->satype = rule->satype;
2250 reverse->tmode = rule->tmode;
2251 reverse->src = copyhost(rule->dst);
2252 reverse->dst = copyhost(rule->src);
2253 reverse->spi = spi;
2254 reverse->udpencap = rule->udpencap;
2255 reverse->udpdport = rule->udpdport;
2256 reverse->xfs = copytransforms(rule->xfs);
2257 reverse->authkey = authkey;
2258 reverse->enckey = enckey;
2259
2260 return (reverse);
2261}
2262
2263struct ipsec_rule *
2264create_sabundle(struct ipsec_addr_wrap *dst, u_int8_t proto, u_int32_t spi,
2265 struct ipsec_addr_wrap *dst2, u_int8_t proto2, u_int32_t spi2)
2266{
2267 struct ipsec_rule *r;
2268
2269 r = calloc(1, sizeof(struct ipsec_rule));
2270 if (r == NULL((void *)0))
2271 err(1, "%s", __func__);
2272
2273 r->type |= RULE_BUNDLE0x08;
2274
2275 r->dst = copyhost(dst);
2276 r->dst2 = copyhost(dst2);
2277 r->proto = proto;
2278 r->proto2 = proto2;
2279 r->spi = spi;
2280 r->spi2 = spi2;
2281 r->satype = proto;
2282
2283 return (r);
2284}
2285
2286struct ipsec_rule *
2287create_flow(u_int8_t dir, u_int8_t proto, struct ipsec_hosts *hosts,
2288 u_int8_t satype, char *srcid, char *dstid, u_int8_t type)
2289{
2290 struct ipsec_rule *r;
2291
2292 r = calloc(1, sizeof(struct ipsec_rule));
2293 if (r == NULL((void *)0))
2294 err(1, "%s", __func__);
2295
2296 r->type |= RULE_FLOW0x01;
2297
2298 if (dir == IPSEC_INOUT)
2299 r->direction = IPSEC_OUT;
2300 else
2301 r->direction = dir;
2302
2303 r->satype = satype;
2304 r->proto = proto;
2305 r->src = hosts->src;
2306 r->sport = hosts->sport;
2307 r->dst = hosts->dst;
2308 r->dport = hosts->dport;
2309 if ((hosts->sport != 0 || hosts->dport != 0) &&
2310 (proto != IPPROTO_TCP6 && proto != IPPROTO_UDP17)) {
2311 yyerror("no protocol supplied with source/destination ports");
2312 goto errout;
2313 }
2314
2315 switch (satype) {
2316 case IPSEC_IPCOMP:
2317 case IPSEC_IPIP:
2318 if (type == TYPE_UNKNOWN)
2319 type = TYPE_USE;
2320 break;
2321 default:
2322 if (type == TYPE_UNKNOWN)
2323 type = TYPE_REQUIRE;
2324 break;
2325 }
2326
2327 r->flowtype = type;
2328 if (type == TYPE_DENY || type == TYPE_BYPASS)
2329 return (r);
2330
2331 r->auth = calloc(1, sizeof(struct ipsec_auth));
2332 if (r->auth == NULL((void *)0))
2333 err(1, "%s", __func__);
2334 r->auth->srcid = srcid;
2335 r->auth->dstid = dstid;
2336 r->auth->srcid_type = get_id_type(srcid);
2337 r->auth->dstid_type = get_id_type(dstid);
2338 return r;
2339
2340errout:
2341 free(r);
2342 if (srcid)
2343 free(srcid);
2344 if (dstid)
2345 free(dstid);
2346 free(hosts->src);
2347 hosts->src = NULL((void *)0);
2348 free(hosts->dst);
2349 hosts->dst = NULL((void *)0);
2350
2351 return NULL((void *)0);
2352}
2353
2354void
2355expand_any(struct ipsec_addr_wrap *ipa_in)
2356{
2357 struct ipsec_addr_wrap *oldnext, *ipa;
2358
2359 for (ipa = ipa_in; ipa; ipa = ipa->next) {
2360 if (ipa->af != AF_UNSPEC0)
2361 continue;
2362 oldnext = ipa->next;
2363
2364 ipa->af = AF_INET2;
2365 ipa->netaddress = 1;
2366 if ((ipa->name = strdup("0.0.0.0/0")) == NULL((void *)0))
2367 err(1, "%s", __func__);
2368
2369 ipa->next = calloc(1, sizeof(struct ipsec_addr_wrap));
2370 if (ipa->next == NULL((void *)0))
2371 err(1, "%s", __func__);
2372 ipa->next->af = AF_INET624;
2373 ipa->next->netaddress = 1;
2374 if ((ipa->next->name = strdup("::/0")) == NULL((void *)0))
2375 err(1, "%s", __func__);
2376
2377 ipa->next->next = oldnext;
2378 }
2379}
2380
2381int
2382set_rule_peers(struct ipsec_rule *r, struct ipsec_hosts *peers)
2383{
2384 if (r->type == RULE_FLOW0x01 &&
2385 (r->flowtype == TYPE_DENY || r->flowtype == TYPE_BYPASS))
2386 return (0);
2387
2388 r->local = copyhost(peers->src);
2389 r->peer = copyhost(peers->dst);
2390 if (r->peer == NULL((void *)0)) {
2391 /* Set peer to remote host. Must be a host address. */
2392 if (r->direction == IPSEC_IN) {
2393 if (!r->src->netaddress)
2394 r->peer = copyhost(r->src);
2395 } else {
2396 if (!r->dst->netaddress)
2397 r->peer = copyhost(r->dst);
2398 }
2399 }
2400 if (r->type == RULE_FLOW0x01 && r->peer == NULL((void *)0)) {
2401 yyerror("no peer specified for destination %s",
2402 r->dst->name);
2403 return (1);
2404 }
2405 if (r->peer != NULL((void *)0) && r->peer->af == AF_UNSPEC0) {
2406 /* If peer has been specified as any, use the default peer. */
2407 free(r->peer);
2408 r->peer = NULL((void *)0);
2409 }
2410 if (r->type == RULE_IKE0x04 && r->peer == NULL((void *)0)) {
2411 /*
2412 * Check if the default peer is consistent for all
2413 * rules. Only warn to avoid breaking existing configs.
2414 */
2415 static struct ipsec_rule *pdr = NULL((void *)0);
2416
2417 if (pdr == NULL((void *)0)) {
2418 /* Remember first default peer rule for comparison. */
2419 pdr = r;
2420 } else {
2421 /* The new default peer must create the same config. */
2422 if ((pdr->local == NULL((void *)0) && r->local != NULL((void *)0)) ||
2423 (pdr->local != NULL((void *)0) && r->local == NULL((void *)0)) ||
2424 (pdr->local != NULL((void *)0) && r->local != NULL((void *)0) &&
2425 strcmp(pdr->local->name, r->local->name)))
2426 yywarn("default peer local mismatch");
2427 if (pdr->ikeauth->type != r->ikeauth->type)
2428 yywarn("default peer phase 1 auth mismatch");
2429 if (pdr->ikeauth->type == IKE_AUTH_PSK &&
2430 r->ikeauth->type == IKE_AUTH_PSK &&
2431 strcmp(pdr->ikeauth->string, r->ikeauth->string))
2432 yywarn("default peer psk mismatch");
2433 if (pdr->p1ie != r->p1ie)
2434 yywarn("default peer phase 1 mode mismatch");
2435 /*
2436 * Transforms have ADD insted of SET so they may be
2437 * different and are not checked here.
2438 */
2439 if ((pdr->auth->srcid == NULL((void *)0) &&
2440 r->auth->srcid != NULL((void *)0)) ||
2441 (pdr->auth->srcid != NULL((void *)0) &&
2442 r->auth->srcid == NULL((void *)0)) ||
2443 (pdr->auth->srcid != NULL((void *)0) &&
2444 r->auth->srcid != NULL((void *)0) &&
2445 strcmp(pdr->auth->srcid, r->auth->srcid)))
2446 yywarn("default peer srcid mismatch");
2447 if ((pdr->auth->dstid == NULL((void *)0) &&
2448 r->auth->dstid != NULL((void *)0)) ||
2449 (pdr->auth->dstid != NULL((void *)0) &&
2450 r->auth->dstid == NULL((void *)0)) ||
2451 (pdr->auth->dstid != NULL((void *)0) &&
2452 r->auth->dstid != NULL((void *)0) &&
2453 strcmp(pdr->auth->dstid, r->auth->dstid)))
2454 yywarn("default peer dstid mismatch");
2455 }
2456 }
2457 return (0);
2458}
2459
2460int
2461expand_rule(struct ipsec_rule *rule, struct ipsec_hosts *peers,
2462 u_int8_t direction, u_int32_t spi, struct ipsec_key *authkey,
2463 struct ipsec_key *enckey, char *bundle)
2464{
2465 struct ipsec_rule *r, *revr;
2466 struct ipsec_addr_wrap *src, *dst;
2467 int added = 0, ret = 1;
2468
2469 if (validate_af(rule->src, rule->dst)) {
2470 yyerror("source/destination address families do not match");
2471 goto errout;
2472 }
2473 expand_any(rule->src);
2474 expand_any(rule->dst);
2475 for (src = rule->src; src; src = src->next) {
2476 for (dst = rule->dst; dst; dst = dst->next) {
2477 if (src->af != dst->af)
2478 continue;
2479 r = copyrule(rule);
2480
2481 r->src = copyhost(src);
2482 r->dst = copyhost(dst);
2483
2484 if (peers && set_rule_peers(r, peers)) {
2485 ipsecctl_free_rule(r);
2486 goto errout;
2487 }
2488
2489 r->nr = ipsec->rule_nr++;
2490 if (ipsecctl_add_rule(ipsec, r))
2491 goto out;
2492 if (bundle && add_sabundle(r, bundle))
2493 goto out;
2494
2495 if (direction == IPSEC_INOUT) {
2496 /* Create and add reverse flow rule. */
2497 revr = reverse_rule(r);
2498 if (revr == NULL((void *)0))
2499 goto out;
2500
2501 revr->nr = ipsec->rule_nr++;
2502 if (ipsecctl_add_rule(ipsec, revr))
2503 goto out;
2504 if (bundle && add_sabundle(revr, bundle))
2505 goto out;
2506 } else if (spi != 0 || authkey || enckey) {
2507 /* Create and add reverse sa rule. */
2508 revr = reverse_sa(r, spi, authkey, enckey);
2509 if (revr == NULL((void *)0))
2510 goto out;
2511
2512 revr->nr = ipsec->rule_nr++;
2513 if (ipsecctl_add_rule(ipsec, revr))
2514 goto out;
2515 if (bundle && add_sabundle(revr, bundle))
2516 goto out;
2517 }
2518 added++;
2519 }
2520 }
2521 if (!added)
2522 yyerror("rule expands to no valid combination");
2523 errout:
2524 ret = 0;
2525 ipsecctl_free_rule(rule);
2526 out:
2527 if (peers) {
2528 if (peers->src)
2529 free(peers->src);
2530 if (peers->dst)
2531 free(peers->dst);
2532 }
2533 return (ret);
2534}
2535
2536struct ipsec_rule *
2537reverse_rule(struct ipsec_rule *rule)
2538{
2539 struct ipsec_rule *reverse;
2540
2541 reverse = calloc(1, sizeof(struct ipsec_rule));
2542 if (reverse == NULL((void *)0))
2543 err(1, "%s", __func__);
2544
2545 reverse->type |= RULE_FLOW0x01;
2546
2547 /* Reverse direction */
2548 if (rule->direction == (u_int8_t)IPSEC_OUT)
2549 reverse->direction = (u_int8_t)IPSEC_IN;
2550 else
2551 reverse->direction = (u_int8_t)IPSEC_OUT;
2552
2553 reverse->flowtype = rule->flowtype;
2554 reverse->src = copyhost(rule->dst);
2555 reverse->dst = copyhost(rule->src);
2556 reverse->sport = rule->dport;
2557 reverse->dport = rule->sport;
2558 if (rule->local)
2559 reverse->local = copyhost(rule->local);
2560 if (rule->peer)
2561 reverse->peer = copyhost(rule->peer);
2562 reverse->satype = rule->satype;
2563 reverse->proto = rule->proto;
2564
2565 if (rule->auth) {
2566 reverse->auth = calloc(1, sizeof(struct ipsec_auth));
2567 if (reverse->auth == NULL((void *)0))
2568 err(1, "%s", __func__);
2569 if (rule->auth->dstid && (reverse->auth->dstid =
2570 strdup(rule->auth->dstid)) == NULL((void *)0))
2571 err(1, "%s", __func__);
2572 if (rule->auth->srcid && (reverse->auth->srcid =
2573 strdup(rule->auth->srcid)) == NULL((void *)0))
2574 err(1, "%s", __func__);
2575 reverse->auth->srcid_type = rule->auth->srcid_type;
2576 reverse->auth->dstid_type = rule->auth->dstid_type;
2577 reverse->auth->type = rule->auth->type;
2578 }
2579
2580 return reverse;
2581}
2582
2583struct ipsec_rule *
2584create_ike(u_int8_t proto, struct ipsec_hosts *hosts,
2585 struct ike_mode *phase1mode, struct ike_mode *phase2mode, u_int8_t satype,
2586 u_int8_t tmode, u_int8_t mode, char *srcid, char *dstid,
2587 struct ike_auth *authtype, char *tag)
2588{
2589 struct ipsec_rule *r;
2590
2591 r = calloc(1, sizeof(struct ipsec_rule));
2592 if (r == NULL((void *)0))
2593 err(1, "%s", __func__);
2594
2595 r->type = RULE_IKE0x04;
2596
2597 r->proto = proto;
2598 r->src = hosts->src;
2599 r->sport = hosts->sport;
2600 r->dst = hosts->dst;
2601 r->dport = hosts->dport;
2602 if ((hosts->sport != 0 || hosts->dport != 0) &&
2603 (proto != IPPROTO_TCP6 && proto != IPPROTO_UDP17)) {
2604 yyerror("no protocol supplied with source/destination ports");
2605 goto errout;
2606 }
2607
2608 r->satype = satype;
2609 r->tmode = tmode;
2610 r->ikemode = mode;
2611 if (phase1mode) {
2612 r->p1xfs = phase1mode->xfs;
2613 r->p1life = phase1mode->life;
2614 r->p1ie = phase1mode->ike_exch;
2615 } else {
2616 r->p1ie = IKE_MM;
2617 }
2618 if (phase2mode) {
2619 if (phase2mode->xfs && phase2mode->xfs->encxf &&
2620 phase2mode->xfs->encxf->noauth &&
2621 phase2mode->xfs->authxf) {
2622 yyerror("authentication is implicit for %s",
2623 phase2mode->xfs->encxf->name);
2624 goto errout;
2625 }
2626 r->p2xfs = phase2mode->xfs;
2627 r->p2life = phase2mode->life;
2628 r->p2ie = phase2mode->ike_exch;
2629 } else {
2630 r->p2ie = IKE_QM;
2631 }
2632
2633 r->auth = calloc(1, sizeof(struct ipsec_auth));
2634 if (r->auth == NULL((void *)0))
2635 err(1, "%s", __func__);
2636 r->auth->srcid = srcid;
2637 r->auth->dstid = dstid;
2638 r->auth->srcid_type = get_id_type(srcid);
2639 r->auth->dstid_type = get_id_type(dstid);
2640 r->ikeauth = calloc(1, sizeof(struct ike_auth));
2641 if (r->ikeauth == NULL((void *)0))
2642 err(1, "%s", __func__);
2643 r->ikeauth->type = authtype->type;
2644 r->ikeauth->string = authtype->string;
2645 r->tag = tag;
2646
2647 return (r);
2648
2649errout:
2650 free(r);
2651 free(hosts->src);
2652 hosts->src = NULL((void *)0);
2653 free(hosts->dst);
2654 hosts->dst = NULL((void *)0);
2655 if (phase1mode) {
2656 free(phase1mode->xfs);
2657 phase1mode->xfs = NULL((void *)0);
2658 free(phase1mode->life);
2659 phase1mode->life = NULL((void *)0);
2660 }
2661 if (phase2mode) {
2662 free(phase2mode->xfs);
2663 phase2mode->xfs = NULL((void *)0);
2664 free(phase2mode->life);
2665 phase2mode->life = NULL((void *)0);
2666 }
2667 if (srcid)
2668 free(srcid);
2669 if (dstid)
2670 free(dstid);
2671 return NULL((void *)0);
2672}
2673#line 2666 "parse.c"
2674/* allocate initial stack or double stack size, up to YYMAXDEPTH */
2675static int yygrowstack(void)
2676{
2677 unsigned int newsize;
2678 long sslen;
2679 short *newss;
2680 YYSTYPE *newvs;
2681
2682 if ((newsize = yystacksize) == 0)
2683 newsize = YYINITSTACKSIZE200;
2684 else if (newsize >= YYMAXDEPTH10000)
2685 return -1;
2686 else if ((newsize *= 2) > YYMAXDEPTH10000)
2687 newsize = YYMAXDEPTH10000;
2688 sslen = yyssp - yyss;
2689#ifdef SIZE_MAX
2690#define YY_SIZE_MAX0xffffffffU SIZE_MAX
2691#else
2692#define YY_SIZE_MAX0xffffffffU 0xffffffffU
2693#endif
2694 if (newsize && YY_SIZE_MAX0xffffffffU / newsize < sizeof *newss)
2695 goto bail;
2696 newss = (short *)realloc(yyss, newsize * sizeof *newss);
2697 if (newss == NULL((void *)0))
2698 goto bail;
2699 yyss = newss;
2700 yyssp = newss + sslen;
2701 if (newsize && YY_SIZE_MAX0xffffffffU / newsize < sizeof *newvs)
2702 goto bail;
2703 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
2704 if (newvs == NULL((void *)0))
2705 goto bail;
2706 yyvs = newvs;
2707 yyvsp = newvs + sslen;
2708 yystacksize = newsize;
2709 yysslim = yyss + newsize - 1;
2710 return 0;
2711bail:
2712 if (yyss)
2713 free(yyss);
2714 if (yyvs)
2715 free(yyvs);
2716 yyss = yyssp = NULL((void *)0);
2717 yyvs = yyvsp = NULL((void *)0);
2718 yystacksize = 0;
2719 return -1;
2720}
2721
2722#define YYABORTgoto yyabort goto yyabort
2723#define YYREJECTgoto yyabort goto yyabort
2724#define YYACCEPTgoto yyaccept goto yyaccept
2725#define YYERRORgoto yyerrlab goto yyerrlab
2726int
2727yyparse(void)
2728{
2729 int yym, yyn, yystate;
2730#if YYDEBUG0
2731 const char *yys;
2732
2733 if ((yys = getenv("YYDEBUG")))
2734 {
2735 yyn = *yys;
2736 if (yyn >= '0' && yyn <= '9')
2737 yydebug = yyn - '0';
2738 }
2739#endif /* YYDEBUG */
2740
2741 yynerrs = 0;
2742 yyerrflag = 0;
2743 yychar = (-1);
2744
2745 if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow;
2746 yyssp = yyss;
2747 yyvsp = yyvs;
2748 *yyssp = yystate = 0;
2749
2750yyloop:
2751 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2752 if (yychar < 0)
2753 {
2754 if ((yychar = yylex()) < 0) yychar = 0;
2755#if YYDEBUG0
2756 if (yydebug)
2757 {
2758 yys = 0;
2759 if (yychar <= YYMAXTOKEN309) yys = yyname[yychar];
2760 if (!yys) yys = "illegal-symbol";
2761 printf("%sdebug: state %d, reading %d (%s)\n",
2762 YYPREFIX"yy", yystate, yychar, yys);
2763 }
2764#endif
2765 }
2766 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
2767 yyn <= YYTABLESIZE588 && yycheck[yyn] == yychar)
2768 {
2769#if YYDEBUG0
2770 if (yydebug)
2771 printf("%sdebug: state %d, shifting to state %d\n",
2772 YYPREFIX"yy", yystate, yytable[yyn]);
2773#endif
2774 if (yyssp >= yysslim && yygrowstack())
2775 {
2776 goto yyoverflow;
2777 }
2778 *++yyssp = yystate = yytable[yyn];
2779 *++yyvsp = yylval;
2780 yychar = (-1);
2781 if (yyerrflag > 0) --yyerrflag;
2782 goto yyloop;
2783 }
2784 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
2785 yyn <= YYTABLESIZE588 && yycheck[yyn] == yychar)
2786 {
2787 yyn = yytable[yyn];
2788 goto yyreduce;
2789 }
2790 if (yyerrflag) goto yyinrecovery;
2791#if defined(__GNUC__4)
2792 goto yynewerror;
2793#endif
2794yynewerror:
2795 yyerror("syntax error");
2796#if defined(__GNUC__4)
2797 goto yyerrlab;
2798#endif
2799yyerrlab:
2800 ++yynerrs;
2801yyinrecovery:
2802 if (yyerrflag < 3)
2803 {
2804 yyerrflag = 3;
2805 for (;;)
2806 {
2807 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
2808 yyn <= YYTABLESIZE588 && yycheck[yyn] == YYERRCODE256)
2809 {
2810#if YYDEBUG0
2811 if (yydebug)
2812 printf("%sdebug: state %d, error recovery shifting\
2813 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
2814#endif
2815 if (yyssp >= yysslim && yygrowstack())
2816 {
2817 goto yyoverflow;
2818 }
2819 *++yyssp = yystate = yytable[yyn];
2820 *++yyvsp = yylval;
2821 goto yyloop;
2822 }
2823 else
2824 {
2825#if YYDEBUG0
2826 if (yydebug)
2827 printf("%sdebug: error recovery discarding state %d\n",
2828 YYPREFIX"yy", *yyssp);
2829#endif
2830 if (yyssp <= yyss) goto yyabort;
2831 --yyssp;
2832 --yyvsp;
2833 }
2834 }
2835 }
2836 else
2837 {
2838 if (yychar == 0) goto yyabort;
2839#if YYDEBUG0
2840 if (yydebug)
2841 {
2842 yys = 0;
2843 if (yychar <= YYMAXTOKEN309) yys = yyname[yychar];
2844 if (!yys) yys = "illegal-symbol";
2845 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
2846 YYPREFIX"yy", yystate, yychar, yys);
2847 }
2848#endif
2849 yychar = (-1);
2850 goto yyloop;
2851 }
2852yyreduce:
2853#if YYDEBUG0
2854 if (yydebug)
2855 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
2856 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
2857#endif
2858 yym = yylen[yyn];
2859 if (yym)
2860 yyval = yyvsp[1-yym];
2861 else
2862 memset(&yyval, 0, sizeof yyval);
2863 switch (yyn)
2864 {
2865case 9:
2866#line 330 "/usr/src/sbin/ipsecctl/parse.y"
2867{ file->errors++; }
2868break;
2869case 12:
2870#line 337 "/usr/src/sbin/ipsecctl/parse.y"
2871{
2872 struct file *nfile;
2873
2874 if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL((void *)0)) {
2875 yyerror("failed to include file %s", yyvsp[0].v.string);
2876 free(yyvsp[0].v.string);
2877 YYERRORgoto yyerrlab;
2878 }
2879 free(yyvsp[0].v.string);
2880
2881 file = nfile;
2882 lungetc('\n');
2883 }
2884break;
2885case 13:
2886#line 352 "/usr/src/sbin/ipsecctl/parse.y"
2887{
2888 struct ipsec_rule *r;
2889
2890 r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &yyvsp[-2].v.hosts,
2891 yyvsp[-1].v.spis.spiout, 0, 0, NULL((void *)0), yyvsp[0].v.authkeys.keyout, NULL((void *)0));
2892 if (r == NULL((void *)0))
2893 YYERRORgoto yyerrlab;
2894
2895 if (expand_rule(r, NULL((void *)0), 0, yyvsp[-1].v.spis.spiin, yyvsp[0].v.authkeys.keyin, NULL((void *)0),
2896 NULL((void *)0)))
2897 errx(1, "tcpmd5rule: expand_rule");
2898 }
2899break;
2900case 14:
2901#line 367 "/usr/src/sbin/ipsecctl/parse.y"
2902{
2903 struct ipsec_rule *r;
2904
2905 r = create_sa(yyvsp[-8].v.satype, yyvsp[-7].v.tmode, &yyvsp[-6].v.hosts, yyvsp[-5].v.spis.spiout, yyvsp[-4].v.udpencap.encap, yyvsp[-4].v.udpencap.port,
2906 yyvsp[-3].v.transforms, yyvsp[-2].v.authkeys.keyout, yyvsp[-1].v.enckeys.keyout);
2907 if (r == NULL((void *)0))
2908 YYERRORgoto yyerrlab;
2909
2910 if (expand_rule(r, NULL((void *)0), 0, yyvsp[-5].v.spis.spiin, yyvsp[-2].v.authkeys.keyin,
2911 yyvsp[-1].v.enckeys.keyin, yyvsp[0].v.string))
2912 errx(1, "sarule: expand_rule");
2913 }
2914break;
2915case 15:
2916#line 381 "/usr/src/sbin/ipsecctl/parse.y"
2917{
2918 struct ipsec_rule *r;
2919
2920 r = create_flow(yyvsp[-5].v.dir, yyvsp[-4].v.proto, &yyvsp[-3].v.hosts, yyvsp[-6].v.satype, yyvsp[-1].v.ids.srcid,
2921 yyvsp[-1].v.ids.dstid, yyvsp[0].v.type);
2922 if (r == NULL((void *)0))
2923 YYERRORgoto yyerrlab;
2924
2925 if (expand_rule(r, &yyvsp[-2].v.peers, yyvsp[-5].v.dir, 0, NULL((void *)0), NULL((void *)0), NULL((void *)0)))
2926 errx(1, "flowrule: expand_rule");
2927 }
2928break;
2929case 16:
2930#line 395 "/usr/src/sbin/ipsecctl/parse.y"
2931{
2932 struct ipsec_rule *r;
2933
2934 r = create_ike(yyvsp[-7].v.proto, &yyvsp[-6].v.hosts, yyvsp[-4].v.mode, yyvsp[-3].v.mode, yyvsp[-9].v.satype, yyvsp[-8].v.tmode, yyvsp[-10].v.ikemode,
2935 yyvsp[-2].v.ids.srcid, yyvsp[-2].v.ids.dstid, &yyvsp[-1].v.ikeauth, yyvsp[0].v.string);
2936 if (r == NULL((void *)0))
2937 YYERRORgoto yyerrlab;
2938
2939 if (expand_rule(r, &yyvsp[-5].v.peers, 0, 0, NULL((void *)0), NULL((void *)0), NULL((void *)0)))
2940 errx(1, "ikerule: expand_rule");
2941 }
2942break;
2943case 17:
2944#line 409 "/usr/src/sbin/ipsecctl/parse.y"
2945{
2946 uint8_t proto = 0; /* IPPROTO_IPIP;*/
2947 struct ipsec_hosts hosts;
2948 struct ike_mode *phase1mode = yyvsp[-3].v.mode;
2949 struct ike_mode *phase2mode = yyvsp[-2].v.mode;
2950 uint8_t satype = IPSEC_ESP;
2951 uint8_t tmode = IPSEC_TUNNEL;
2952 uint8_t mode = yyvsp[-6].v.ikemode;
2953 struct ike_auth *authtype = &yyvsp[0].v.ikeauth;
2954 char *tag = NULL((void *)0);
2955
2956 struct ipsec_rule *r;
2957
2958 hosts.src = host_v4("0.0.0.0/0", 1);
2959 hosts.sport = htons(0)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
2960 hosts.dst = host_v4("0.0.0.0/0", 1);
2961 hosts.dport = htons(0)(__uint16_t)(__builtin_constant_p(0) ? (__uint16_t)(((__uint16_t
)(0) & 0xffU) << 8 | ((__uint16_t)(0) & 0xff00U
) >> 8) : __swap16md(0))
;
2962
2963 r = create_ike(proto, &hosts, phase1mode, phase2mode,
2964 satype, tmode, mode, yyvsp[-1].v.ids.srcid, yyvsp[-1].v.ids.dstid,
2965 authtype, tag);
2966 if (r == NULL((void *)0)) {
2967 YYERRORgoto yyerrlab;
2968 }
2969
2970 r->flags |= IPSEC_RULE_F_IFACE(1 << 0);
2971 r->iface = yyvsp[-5].v.unit;
2972
2973 if (expand_rule(r, &yyvsp[-4].v.peers, 0, 0, NULL((void *)0), NULL((void *)0), NULL((void *)0)))
2974 errx(1, "ikerule: expand interface rule");
2975
2976 }
2977break;
2978case 18:
2979#line 443 "/usr/src/sbin/ipsecctl/parse.y"
2980{ yyval.v.satype = IPSEC_ESP; }
2981break;
2982case 19:
2983#line 444 "/usr/src/sbin/ipsecctl/parse.y"
2984{ yyval.v.satype = IPSEC_ESP; }
2985break;
2986case 20:
2987#line 445 "/usr/src/sbin/ipsecctl/parse.y"
2988{ yyval.v.satype = IPSEC_AH; }
2989break;
2990case 21:
2991#line 446 "/usr/src/sbin/ipsecctl/parse.y"
2992{ yyval.v.satype = IPSEC_IPCOMP; }
2993break;
2994case 22:
2995#line 447 "/usr/src/sbin/ipsecctl/parse.y"
2996{ yyval.v.satype = IPSEC_IPIP; }
2997break;
2998case 23:
2999#line 450 "/usr/src/sbin/ipsecctl/parse.y"
3000{ yyval.v.proto = 0; }
3001break;
3002case 24:
3003#line 451 "/usr/src/sbin/ipsecctl/parse.y"
3004{ yyval.v.proto = yyvsp[0].v.number; }
3005break;
3006case 25:
3007#line 452 "/usr/src/sbin/ipsecctl/parse.y"
3008{ yyval.v.proto = IPPROTO_ESP50; }
3009break;
3010case 26:
3011#line 453 "/usr/src/sbin/ipsecctl/parse.y"
3012{ yyval.v.proto = IPPROTO_AH51; }
3013break;
3014case 27:
3015#line 456 "/usr/src/sbin/ipsecctl/parse.y"
3016{
3017 struct protoent *p;
3018
3019 p = getprotobyname(yyvsp[0].v.string);
3020 if (p == NULL((void *)0)) {
3021 yyerror("unknown protocol: %s", yyvsp[0].v.string);
3022 YYERRORgoto yyerrlab;
3023 }
3024 yyval.v.number = p->p_proto;
3025 free(yyvsp[0].v.string);
3026 }
3027break;
3028case 28:
3029#line 467 "/usr/src/sbin/ipsecctl/parse.y"
3030{
3031 if (yyvsp[0].v.number > 255 || yyvsp[0].v.number < 0) {
3032 yyerror("protocol outside range");
3033 YYERRORgoto yyerrlab;
3034 }
3035 }
3036break;
3037case 29:
3038#line 475 "/usr/src/sbin/ipsecctl/parse.y"
3039{ yyval.v.tmode = IPSEC_TUNNEL; }
3040break;
3041case 30:
3042#line 476 "/usr/src/sbin/ipsecctl/parse.y"
3043{ yyval.v.tmode = IPSEC_TUNNEL; }
3044break;
3045case 31:
3046#line 477 "/usr/src/sbin/ipsecctl/parse.y"
3047{ yyval.v.tmode = IPSEC_TRANSPORT; }
3048break;
3049case 32:
3050#line 480 "/usr/src/sbin/ipsecctl/parse.y"
3051{ yyval.v.dir = IPSEC_INOUT; }
3052break;
3053case 33:
3054#line 481 "/usr/src/sbin/ipsecctl/parse.y"
3055{ yyval.v.dir = IPSEC_IN; }
3056break;
3057case 34:
3058#line 482 "/usr/src/sbin/ipsecctl/parse.y"
3059{ yyval.v.dir = IPSEC_OUT; }
3060break;
3061case 35:
3062#line 485 "/usr/src/sbin/ipsecctl/parse.y"
3063{
3064 struct ipsec_addr_wrap *ipa;
3065 for (ipa = yyvsp[-1].v.host; ipa; ipa = ipa->next) {
3066 if (ipa->srcnat) {
3067 yyerror("no flow NAT support for"
3068 " destination network: %s", ipa->name);
3069 YYERRORgoto yyerrlab;
3070 }
3071 }
3072 yyval.v.hosts.src = yyvsp[-4].v.host;
3073 yyval.v.hosts.sport = yyvsp[-3].v.port;
3074 yyval.v.hosts.dst = yyvsp[-1].v.host;
3075 yyval.v.hosts.dport = yyvsp[0].v.port;
3076 }
3077break;
3078case 36:
3079#line 499 "/usr/src/sbin/ipsecctl/parse.y"
3080{
3081 struct ipsec_addr_wrap *ipa;
3082 for (ipa = yyvsp[-4].v.host; ipa; ipa = ipa->next) {
3083 if (ipa->srcnat) {
3084 yyerror("no flow NAT support for"
3085 " destination network: %s", ipa->name);
3086 YYERRORgoto yyerrlab;
3087 }
3088 }
3089 yyval.v.hosts.src = yyvsp[-1].v.host;
3090 yyval.v.hosts.sport = yyvsp[0].v.port;
3091 yyval.v.hosts.dst = yyvsp[-4].v.host;
3092 yyval.v.hosts.dport = yyvsp[-3].v.port;
3093 }
3094break;
3095case 37:
3096#line 515 "/usr/src/sbin/ipsecctl/parse.y"
3097{ yyval.v.port = 0; }
3098break;
3099case 38:
3100#line 516 "/usr/src/sbin/ipsecctl/parse.y"
3101{ yyval.v.port = yyvsp[0].v.number; }
3102break;
3103case 39:
3104#line 519 "/usr/src/sbin/ipsecctl/parse.y"
3105{
3106 struct servent *s;
3107
3108 if ((s = getservbyname(yyvsp[0].v.string, "tcp")) != NULL((void *)0) ||
3109 (s = getservbyname(yyvsp[0].v.string, "udp")) != NULL((void *)0)) {
3110 yyval.v.number = s->s_port;
3111 } else {
3112 yyerror("unknown port: %s", yyvsp[0].v.string);
3113 YYERRORgoto yyerrlab;
3114 }
3115 }
3116break;
3117case 40:
3118#line 530 "/usr/src/sbin/ipsecctl/parse.y"
3119{
3120 if (yyvsp[0].v.number > USHRT_MAX0xffff || yyvsp[0].v.number < 0) {
3121 yyerror("port outside range");
3122 YYERRORgoto yyerrlab;
3123 }
3124 yyval.v.number = htons(yyvsp[0].v.number)(__uint16_t)(__builtin_constant_p(yyvsp[0].v.number) ? (__uint16_t
)(((__uint16_t)(yyvsp[0].v.number) & 0xffU) << 8 | (
(__uint16_t)(yyvsp[0].v.number) & 0xff00U) >> 8) : __swap16md
(yyvsp[0].v.number))
;
3125 }
3126break;
3127case 41:
3128#line 539 "/usr/src/sbin/ipsecctl/parse.y"
3129{
3130 yyval.v.peers.dst = NULL((void *)0);
3131 yyval.v.peers.src = NULL((void *)0);
3132 }
3133break;
3134case 42:
3135#line 543 "/usr/src/sbin/ipsecctl/parse.y"
3136{
3137 yyval.v.peers.dst = yyvsp[-2].v.anyhost;
3138 yyval.v.peers.src = yyvsp[0].v.singlehost;
3139 }
3140break;
3141case 43:
3142#line 547 "/usr/src/sbin/ipsecctl/parse.y"
3143{
3144 yyval.v.peers.dst = yyvsp[0].v.anyhost;
3145 yyval.v.peers.src = yyvsp[-2].v.singlehost;
3146 }
3147break;
3148case 44:
3149#line 551 "/usr/src/sbin/ipsecctl/parse.y"
3150{
3151 yyval.v.peers.dst = yyvsp[0].v.anyhost;
3152 yyval.v.peers.src = NULL((void *)0);
3153 }
3154break;
3155case 45:
3156#line 555 "/usr/src/sbin/ipsecctl/parse.y"
3157{
3158 yyval.v.peers.dst = NULL((void *)0);
3159 yyval.v.peers.src = yyvsp[0].v.singlehost;
3160 }
3161break;
3162case 46:
3163#line 561 "/usr/src/sbin/ipsecctl/parse.y"
3164{ yyval.v.anyhost = yyvsp[0].v.singlehost; }
3165break;
3166case 47:
3167#line 562 "/usr/src/sbin/ipsecctl/parse.y"
3168{
3169 yyval.v.anyhost = host_any();
3170 }
3171break;
3172case 48:
3173#line 566 "/usr/src/sbin/ipsecctl/parse.y"
3174{ yyval.v.singlehost = NULL((void *)0); }
3175break;
3176case 49:
3177#line 567 "/usr/src/sbin/ipsecctl/parse.y"
3178{
3179 if ((yyval.v.singlehost = host(yyvsp[0].v.string)) == NULL((void *)0)) {
3180 free(yyvsp[0].v.string);
3181 yyerror("could not parse host specification");
3182 YYERRORgoto yyerrlab;
3183 }
3184 free(yyvsp[0].v.string);
3185 }
3186break;
3187case 50:
3188#line 577 "/usr/src/sbin/ipsecctl/parse.y"
3189{ yyval.v.host = yyvsp[0].v.host; }
3190break;
3191case 51:
3192#line 578 "/usr/src/sbin/ipsecctl/parse.y"
3193{
3194 if (yyvsp[0].v.host == NULL((void *)0))
3195 yyval.v.host = yyvsp[-2].v.host;
3196 else if (yyvsp[-2].v.host == NULL((void *)0))
3197 yyval.v.host = yyvsp[0].v.host;
3198 else {
3199 yyvsp[-2].v.host->tail->next = yyvsp[0].v.host;
3200 yyvsp[-2].v.host->tail = yyvsp[0].v.host->tail;
3201 yyval.v.host = yyvsp[-2].v.host;
3202 }
3203 }
3204break;
3205case 52:
3206#line 591 "/usr/src/sbin/ipsecctl/parse.y"
3207{
3208 if ((yyval.v.host = host(yyvsp[0].v.string)) == NULL((void *)0)) {
3209 free(yyvsp[0].v.string);
3210 yyerror("could not parse host specification");
3211 YYERRORgoto yyerrlab;
3212 }
3213 free(yyvsp[0].v.string);
3214 }
3215break;
3216case 53:
3217#line 599 "/usr/src/sbin/ipsecctl/parse.y"
3218{
3219 char *buf;
3220
3221 if (asprintf(&buf, "%s/%lld", yyvsp[-2].v.string, yyvsp[0].v.number) == -1)
3222 err(1, "host: asprintf");
3223 free(yyvsp[-2].v.string);
3224 if ((yyval.v.host = host(buf)) == NULL((void *)0)) {
3225 free(buf);
3226 yyerror("could not parse host specification");
3227 YYERRORgoto yyerrlab;
3228 }
3229 free(buf);
3230 }
3231break;
3232case 54:
3233#line 614 "/usr/src/sbin/ipsecctl/parse.y"
3234{ yyval.v.host = yyvsp[0].v.host; }
3235break;
3236case 55:
3237#line 615 "/usr/src/sbin/ipsecctl/parse.y"
3238{
3239 if (yyvsp[-1].v.host->af != yyvsp[-3].v.host->af) {
3240 yyerror("Flow NAT address family mismatch");
3241 YYERRORgoto yyerrlab;
3242 }
3243 yyval.v.host = yyvsp[-3].v.host;
3244 yyval.v.host->srcnat = yyvsp[-1].v.host;
3245 }
3246break;
3247case 56:
3248#line 623 "/usr/src/sbin/ipsecctl/parse.y"
3249{
3250 yyval.v.host = host_any();
3251 }
3252break;
3253case 57:
3254#line 626 "/usr/src/sbin/ipsecctl/parse.y"
3255{ yyval.v.host = yyvsp[-1].v.host; }
3256break;
3257case 58:
3258#line 629 "/usr/src/sbin/ipsecctl/parse.y"
3259{
3260 yyval.v.ids.srcid = NULL((void *)0);
3261 yyval.v.ids.dstid = NULL((void *)0);
3262 }
3263break;
3264case 59:
3265#line 633 "/usr/src/sbin/ipsecctl/parse.y"
3266{
3267 yyval.v.ids.srcid = yyvsp[-2].v.id;
3268 yyval.v.ids.dstid = yyvsp[0].v.id;
3269 }
3270break;
3271case 60:
3272#line 637 "/usr/src/sbin/ipsecctl/parse.y"
3273{
3274 yyval.v.ids.srcid = yyvsp[0].v.id;
3275 yyval.v.ids.dstid = NULL((void *)0);
3276 }
3277break;
3278case 61:
3279#line 641 "/usr/src/sbin/ipsecctl/parse.y"
3280{
3281 yyval.v.ids.srcid = NULL((void *)0);
3282 yyval.v.ids.dstid = yyvsp[0].v.id;
3283 }
3284break;
3285case 62:
3286#line 647 "/usr/src/sbin/ipsecctl/parse.y"
3287{
3288 yyval.v.type = TYPE_UNKNOWN;
3289 }
3290break;
3291case 63:
3292#line 650 "/usr/src/sbin/ipsecctl/parse.y"
3293{
3294 yyval.v.type = TYPE_USE;
3295 }
3296break;
3297case 64:
3298#line 653 "/usr/src/sbin/ipsecctl/parse.y"
3299{
3300 yyval.v.type = TYPE_ACQUIRE;
3301 }
3302break;
3303case 65:
3304#line 656 "/usr/src/sbin/ipsecctl/parse.y"
3305{
3306 yyval.v.type = TYPE_REQUIRE;
3307 }
3308break;
3309case 66:
3310#line 659 "/usr/src/sbin/ipsecctl/parse.y"
3311{
3312 yyval.v.type = TYPE_DENY;
3313 }
3314break;
3315case 67:
3316#line 662 "/usr/src/sbin/ipsecctl/parse.y"
3317{
3318 yyval.v.type = TYPE_BYPASS;
3319 }
3320break;
3321case 68:
3322#line 665 "/usr/src/sbin/ipsecctl/parse.y"
3323{
3324 yyval.v.type = TYPE_DONTACQ;
3325 }
3326break;
3327case 69:
3328#line 670 "/usr/src/sbin/ipsecctl/parse.y"
3329{ yyval.v.id = yyvsp[0].v.string; }
3330break;
3331case 70:
3332#line 673 "/usr/src/sbin/ipsecctl/parse.y"
3333{
3334 u_int32_t spi;
3335 char *p = strchr(yyvsp[0].v.string, ':');
3336
3337 if (p != NULL((void *)0)) {
3338 *p++ = 0;
3339
3340 if (atospi(p, &spi) == -1) {
3341 free(yyvsp[0].v.string);
3342 YYERRORgoto yyerrlab;
3343 }
3344 yyval.v.spis.spiin = spi;
3345 } else
3346 yyval.v.spis.spiin = 0;
3347
3348 if (atospi(yyvsp[0].v.string, &spi) == -1) {
3349 free(yyvsp[0].v.string);
3350 YYERRORgoto yyerrlab;
3351 }
3352 yyval.v.spis.spiout = spi;
3353
3354
3355 free(yyvsp[0].v.string);
3356 }
3357break;
3358case 71:
3359#line 697 "/usr/src/sbin/ipsecctl/parse.y"
3360{
3361 if (yyvsp[0].v.number > UINT_MAX0xffffffffU || yyvsp[0].v.number < 0) {
3362 yyerror("%lld not a valid spi", yyvsp[0].v.number);
3363 YYERRORgoto yyerrlab;
3364 }
3365 if (yyvsp[0].v.number >= SPI_RESERVED_MIN1 && yyvsp[0].v.number <= SPI_RESERVED_MAX255) {
3366 yyerror("%lld within reserved spi range", yyvsp[0].v.number);
3367 YYERRORgoto yyerrlab;
3368 }
3369
3370 yyval.v.spis.spiin = 0;
3371 yyval.v.spis.spiout = yyvsp[0].v.number;
3372 }
3373break;
3374case 72:
3375#line 712 "/usr/src/sbin/ipsecctl/parse.y"
3376{
3377 yyval.v.udpencap.encap = 0;
3378 }
3379break;
3380case 73:
3381#line 715 "/usr/src/sbin/ipsecctl/parse.y"
3382{
3383 yyval.v.udpencap.encap = 1;
3384 yyval.v.udpencap.port = 0;
3385 }
3386break;
3387case 74:
3388#line 719 "/usr/src/sbin/ipsecctl/parse.y"
3389{
3390 yyval.v.udpencap.encap = 1;
3391 yyval.v.udpencap.port = yyvsp[0].v.number;
3392 }
3393break;
3394case 75:
3395#line 725 "/usr/src/sbin/ipsecctl/parse.y"
3396{
3397 if ((ipsec_transforms = calloc(1,
3398 sizeof(struct ipsec_transforms))) == NULL((void *)0))
3399 err(1, "transforms: calloc");
3400 }
3401break;
3402case 76:
3403#line 731 "/usr/src/sbin/ipsecctl/parse.y"
3404{ yyval.v.transforms = ipsec_transforms; }
3405break;
3406case 77:
3407#line 732 "/usr/src/sbin/ipsecctl/parse.y"
3408{
3409 if ((yyval.v.transforms = calloc(1,
3410 sizeof(struct ipsec_transforms))) == NULL((void *)0))
3411 err(1, "transforms: calloc");
3412 }
3413break;
3414case 80:
3415#line 743 "/usr/src/sbin/ipsecctl/parse.y"
3416{
3417 if (ipsec_transforms->authxf)
3418 yyerror("auth already set");
3419 else {
3420 ipsec_transforms->authxf = parse_xf(yyvsp[0].v.string,
3421 authxfs);
3422 if (!ipsec_transforms->authxf)
3423 yyerror("%s not a valid transform", yyvsp[0].v.string);
3424 }
3425 }
3426break;
3427case 81:
3428#line 753 "/usr/src/sbin/ipsecctl/parse.y"
3429{
3430 if (ipsec_transforms->encxf)
3431 yyerror("enc already set");
3432 else {
3433 ipsec_transforms->encxf = parse_xf(yyvsp[0].v.string, encxfs);
3434 if (!ipsec_transforms->encxf)
3435 yyerror("%s not a valid transform", yyvsp[0].v.string);
3436 }
3437 }
3438break;
3439case 82:
3440#line 762 "/usr/src/sbin/ipsecctl/parse.y"
3441{
3442 if (ipsec_transforms->compxf)
3443 yyerror("comp already set");
3444 else {
3445 ipsec_transforms->compxf = parse_xf(yyvsp[0].v.string,
3446 compxfs);
3447 if (!ipsec_transforms->compxf)
3448 yyerror("%s not a valid transform", yyvsp[0].v.string);
3449 }
3450 }
3451break;
3452case 83:
3453#line 772 "/usr/src/sbin/ipsecctl/parse.y"
3454{
3455 if (ipsec_transforms->groupxf)
3456 yyerror("group already set");
3457 else {
3458 ipsec_transforms->groupxf = parse_xf(yyvsp[0].v.string,
3459 groupxfs);
3460 if (!ipsec_transforms->groupxf)
3461 yyerror("%s not a valid transform", yyvsp[0].v.string);
3462 }
3463 }
3464break;
3465case 84:
3466#line 784 "/usr/src/sbin/ipsecctl/parse.y"
3467{
3468 struct ike_mode *p1;
3469
3470 /* We create just an empty main mode */
3471 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL((void *)0))
3472 err(1, "phase1mode: calloc");
3473 p1->ike_exch = IKE_MM;
3474 yyval.v.mode = p1;
3475 }
3476break;
3477case 85:
3478#line 793 "/usr/src/sbin/ipsecctl/parse.y"
3479{
3480 struct ike_mode *p1;
3481
3482 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL((void *)0))
3483 err(1, "phase1mode: calloc");
3484 p1->xfs = yyvsp[-1].v.transforms;
3485 p1->life = yyvsp[0].v.life;
3486 p1->ike_exch = IKE_MM;
3487 yyval.v.mode = p1;
3488 }
3489break;
3490case 86:
3491#line 803 "/usr/src/sbin/ipsecctl/parse.y"
3492{
3493 struct ike_mode *p1;
3494
3495 if ((p1 = calloc(1, sizeof(struct ike_mode))) == NULL((void *)0))
3496 err(1, "phase1mode: calloc");
3497 p1->xfs = yyvsp[-1].v.transforms;
3498 p1->life = yyvsp[0].v.life;
3499 p1->ike_exch = IKE_AM;
3500 yyval.v.mode = p1;
3501 }
3502break;
3503case 87:
3504#line 815 "/usr/src/sbin/ipsecctl/parse.y"
3505{
3506 struct ike_mode *p2;
3507
3508 /* We create just an empty quick mode */
3509 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL((void *)0))
3510 err(1, "phase2mode: calloc");
3511 p2->ike_exch = IKE_QM;
3512 yyval.v.mode = p2;
3513 }
3514break;
3515case 88:
3516#line 824 "/usr/src/sbin/ipsecctl/parse.y"
3517{
3518 struct ike_mode *p2;
3519
3520 if ((p2 = calloc(1, sizeof(struct ike_mode))) == NULL((void *)0))
3521 err(1, "phase2mode: calloc");
3522 p2->xfs = yyvsp[-1].v.transforms;
3523 p2->life = yyvsp[0].v.life;
3524 p2->ike_exch = IKE_QM;
3525 yyval.v.mode = p2;
3526 }
3527break;
3528case 89:
3529#line 836 "/usr/src/sbin/ipsecctl/parse.y"
3530{
3531 struct ipsec_lifetime *life;
3532
3533 /* We create just an empty transform */
3534 if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
3535 == NULL((void *)0))
3536 err(1, "life: calloc");
3537 life->lt_seconds = -1;
3538 life->lt_bytes = -1;
3539 yyval.v.life = life;
3540 }
3541break;
3542case 90:
3543#line 847 "/usr/src/sbin/ipsecctl/parse.y"
3544{
3545 struct ipsec_lifetime *life;
3546
3547 if ((life = calloc(1, sizeof(struct ipsec_lifetime)))
3548 == NULL((void *)0))
3549 err(1, "life: calloc");
3550 life->lt_seconds = yyvsp[0].v.number;
3551 life->lt_bytes = -1;
3552 yyval.v.life = life;
3553 }
3554break;
3555case 91:
3556#line 857 "/usr/src/sbin/ipsecctl/parse.y"
3557{
3558 yyval.v.life = parse_life(yyvsp[0].v.string);
3559 }
3560break;
3561case 92:
3562#line 862 "/usr/src/sbin/ipsecctl/parse.y"
3563{
3564 yyval.v.authkeys.keyout = NULL((void *)0);
3565 yyval.v.authkeys.keyin = NULL((void *)0);
3566 }
3567break;
3568case 93:
3569#line 866 "/usr/src/sbin/ipsecctl/parse.y"
3570{
3571 yyval.v.authkeys.keyout = yyvsp[0].v.keys.keyout;
3572 yyval.v.authkeys.keyin = yyvsp[0].v.keys.keyin;
3573 }
3574break;
3575case 94:
3576#line 872 "/usr/src/sbin/ipsecctl/parse.y"
3577{
3578 yyval.v.enckeys.keyout = NULL((void *)0);
3579 yyval.v.enckeys.keyin = NULL((void *)0);
3580 }
3581break;
3582case 95:
3583#line 876 "/usr/src/sbin/ipsecctl/parse.y"
3584{
3585 yyval.v.enckeys.keyout = yyvsp[0].v.keys.keyout;
3586 yyval.v.enckeys.keyin = yyvsp[0].v.keys.keyin;
3587 }
3588break;
3589case 96:
3590#line 882 "/usr/src/sbin/ipsecctl/parse.y"
3591{ yyval.v.string = NULL((void *)0); }
3592break;
3593case 97:
3594#line 883 "/usr/src/sbin/ipsecctl/parse.y"
3595{ yyval.v.string = yyvsp[0].v.string; }
3596break;
3597case 98:
3598#line 886 "/usr/src/sbin/ipsecctl/parse.y"
3599{
3600 unsigned char *hex;
3601 unsigned char *p = strchr(yyvsp[0].v.string, ':');
3602
3603 if (p != NULL((void *)0) ) {
3604 *p++ = 0;
3605
3606 if (!strncmp(p, "0x", 2))
3607 p += 2;
3608 yyval.v.keys.keyin = parsekey(p, strlen(p));
3609 } else
3610 yyval.v.keys.keyin = NULL((void *)0);
3611
3612 hex = yyvsp[0].v.string;
3613 if (!strncmp(hex, "0x", 2))
3614 hex += 2;
3615 yyval.v.keys.keyout = parsekey(hex, strlen(hex));
3616
3617 free(yyvsp[0].v.string);
3618 }
3619break;
3620case 99:
3621#line 906 "/usr/src/sbin/ipsecctl/parse.y"
3622{
3623 unsigned char *p = strchr(yyvsp[0].v.string, ':');
3624
3625 if (p != NULL((void *)0)) {
3626 *p++ = 0;
3627 yyval.v.keys.keyin = parsekeyfile(p);
3628 }
3629 yyval.v.keys.keyout = parsekeyfile(yyvsp[0].v.string);
3630 free(yyvsp[0].v.string);
3631 }
3632break;
3633case 100:
3634#line 918 "/usr/src/sbin/ipsecctl/parse.y"
3635{ yyval.v.ikemode = IKE_ACTIVE; }
3636break;
3637case 101:
3638#line 919 "/usr/src/sbin/ipsecctl/parse.y"
3639{ yyval.v.ikemode = IKE_PASSIVE; }
3640break;
3641case 102:
3642#line 920 "/usr/src/sbin/ipsecctl/parse.y"
3643{ yyval.v.ikemode = IKE_DYNAMIC; }
3644break;
3645case 103:
3646#line 921 "/usr/src/sbin/ipsecctl/parse.y"
3647{ yyval.v.ikemode = IKE_ACTIVE; }
3648break;
3649case 104:
3650#line 924 "/usr/src/sbin/ipsecctl/parse.y"
3651{
3652 yyval.v.ikeauth.type = IKE_AUTH_RSA;
3653 yyval.v.ikeauth.string = NULL((void *)0);
3654 }
3655break;
3656case 105:
3657#line 928 "/usr/src/sbin/ipsecctl/parse.y"
3658{
3659 yyval.v.ikeauth.type = IKE_AUTH_RSA;
3660 yyval.v.ikeauth.string = NULL((void *)0);
3661 }
3662break;
3663case 106:
3664#line 932 "/usr/src/sbin/ipsecctl/parse.y"
3665{
3666 yyval.v.ikeauth.type = IKE_AUTH_PSK;
3667 if ((yyval.v.ikeauth.string = strdup(yyvsp[0].v.string)) == NULL((void *)0))
3668 err(1, "ikeauth: strdup");
3669 }
3670break;
3671case 107:
3672#line 940 "/usr/src/sbin/ipsecctl/parse.y"
3673{
3674 yyval.v.string = NULL((void *)0);
3675 }
3676break;
3677case 108:
3678#line 944 "/usr/src/sbin/ipsecctl/parse.y"
3679{
3680 yyval.v.string = yyvsp[0].v.string;
3681 }
3682break;
3683case 109:
3684#line 949 "/usr/src/sbin/ipsecctl/parse.y"
3685{
3686 static const char prefix[] = "sec";
3687 const char *errstr = NULL((void *)0);
3688 size_t len, plen;
3689
3690 plen = strlen(prefix);
3691 len = strlen(yyvsp[0].v.string);
3692
3693 if (len <= plen || memcmp(yyvsp[0].v.string, prefix, plen) != 0) {
3694 yyerror("invalid %s interface name", prefix);
3695 free(yyvsp[0].v.string);
3696 YYERRORgoto yyerrlab;
3697 }
3698
3699 yyval.v.unit = strtonum(yyvsp[0].v.string + plen, 0, UINT_MAX0xffffffffU, &errstr);
3700 free(yyvsp[0].v.string);
3701 if (errstr != NULL((void *)0)) {
3702 yyerror("invalid %s interface unit: %s",
3703 prefix, errstr);
3704 YYERRORgoto yyerrlab;
3705 }
3706 }
3707break;
3708case 110:
3709#line 974 "/usr/src/sbin/ipsecctl/parse.y"
3710{
3711 if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1)
3712 err(1, "string: asprintf");
3713 free(yyvsp[-1].v.string);
3714 free(yyvsp[0].v.string);
3715 }
3716break;
3717case 112:
3718#line 984 "/usr/src/sbin/ipsecctl/parse.y"
3719{
3720 char *s = yyvsp[-2].v.string;
3721 if (ipsec->opts & IPSECCTL_OPT_VERBOSE0x0010)
3722 printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
3723 while (*s++) {
3724 if (isspace((unsigned char)*s)) {
3725 yyerror("macro name cannot contain "
3726 "whitespace");
3727 free(yyvsp[-2].v.string);
3728 free(yyvsp[0].v.string);
3729 YYERRORgoto yyerrlab;
3730 }
3731 }
3732 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
3733 err(1, "cannot store variable");
3734 free(yyvsp[-2].v.string);
3735 free(yyvsp[0].v.string);
3736 }
3737break;
3738#line 3731 "parse.c"
3739 }
3740 yyssp -= yym;
3741 yystate = *yyssp;
3742 yyvsp -= yym;
3743 yym = yylhs[yyn];
3744 if (yystate == 0 && yym == 0)
3745 {
3746#if YYDEBUG0
3747 if (yydebug)
3748 printf("%sdebug: after reduction, shifting from state 0 to\
3749 state %d\n", YYPREFIX"yy", YYFINAL1);
3750#endif
3751 yystate = YYFINAL1;
3752 *++yyssp = YYFINAL1;
3753 *++yyvsp = yyval;
3754 if (yychar < 0)
3755 {
3756 if ((yychar = yylex()) < 0) yychar = 0;
3757#if YYDEBUG0
3758 if (yydebug)
3759 {
3760 yys = 0;
3761 if (yychar <= YYMAXTOKEN309) yys = yyname[yychar];
3762 if (!yys) yys = "illegal-symbol";
3763 printf("%sdebug: state %d, reading %d (%s)\n",
3764 YYPREFIX"yy", YYFINAL1, yychar, yys);
3765 }
3766#endif
3767 }
3768 if (yychar == 0) goto yyaccept;
3769 goto yyloop;
3770 }
3771 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
3772 yyn <= YYTABLESIZE588 && yycheck[yyn] == yystate)
3773 yystate = yytable[yyn];
3774 else
3775 yystate = yydgoto[yym];
3776#if YYDEBUG0
3777 if (yydebug)
3778 printf("%sdebug: after reduction, shifting from state %d \
3779to state %d\n", YYPREFIX"yy", *yyssp, yystate);
3780#endif
3781 if (yyssp >= yysslim && yygrowstack())
3782 {
3783 goto yyoverflow;
3784 }
3785 *++yyssp = yystate;
3786 *++yyvsp = yyval;
3787 goto yyloop;
3788yyoverflow:
3789 yyerror("yacc stack overflow");
3790yyabort:
3791 if (yyss)
3792 free(yyss);
3793 if (yyvs)
3794 free(yyvs);
3795 yyss = yyssp = NULL((void *)0);
3796 yyvs = yyvsp = NULL((void *)0);
3797 yystacksize = 0;
3798 return (1);
3799yyaccept:
3800 if (yyss)
3801 free(yyss);
3802 if (yyvs)
3803 free(yyvs);
3804 yyss = yyssp = NULL((void *)0);
3805 yyvs = yyvsp = NULL((void *)0);
3806 yystacksize = 0;
3807 return (0);
3808}