Bug Summary

File:src/sbin/ipsecctl/obj/parse.c
Warning:line 2698, column 13
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

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