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