1 /* $NetBSD: test-policy.c,v 1.4 2006/09/09 16:22:09 manu Exp $ */
2
3 /* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37
38 #include <netinet/in.h>
39 #include <net/pfkeyv2.h>
40 #include <netinet/ipsec.h>
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <unistd.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <err.h>
48
49 #include "libpfkey.h"
50
51 struct req_t {
52 int result; /* expected result; 0:ok 1:ng */
53 char *str;
54 } reqs[] = {
55 { 0, "out ipsec" },
56 { 1, "must_error" },
57 { 1, "in ipsec must_error" },
58 { 1, "out ipsec esp/must_error" },
59 { 1, "out discard" },
60 { 1, "out none" },
61 { 0, "in entrust" },
62 { 0, "out entrust" },
63 { 1, "out ipsec esp" },
64 { 0, "in ipsec ah/transport" },
65 { 1, "in ipsec ah/tunnel" },
66 { 0, "out ipsec ah/transport/" },
67 { 1, "out ipsec ah/tunnel/" },
68 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
69 { 0, "in ipsec esp/tunnel/::1-::2" },
70 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
71 { 0, "in ipsec esp/tunnel/::1-::2/require" },
72 { 0, "out ipsec ah/transport//use" },
73 { 1, "out ipsec ah/transport esp/use" },
74 { 1, "in ipsec ah/transport esp/tunnel" },
75 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
76 { 0, "in ipsec
77 ah / transport
78 esp / tunnel / ::1-::2" },
79 { 0, "out ipsec
80 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
81 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
82 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
83 " },
84 { 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
85 };
86
87 int test1 __P((void));
88 int test1sub1 __P((struct req_t *));
89 int test1sub2 __P((char *, int));
90 int test2 __P((void));
91 int test2sub __P((int));
92
93 int
main(ac,av)94 main(ac, av)
95 int ac;
96 char **av;
97 {
98 test1();
99 test2();
100
101 exit(0);
102 }
103
104 int
test1()105 test1()
106 {
107 int i;
108 int result;
109
110 printf("TEST1\n");
111 for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
112 printf("#%d [%s]\n", i + 1, reqs[i].str);
113
114 result = test1sub1(&reqs[i]);
115 if (result == 0 && reqs[i].result == 1) {
116 warnx("ERROR: expecting failure.");
117 } else if (result == 1 && reqs[i].result == 0) {
118 warnx("ERROR: expecting success.");
119 }
120 }
121
122 return 0;
123 }
124
125 int
test1sub1(req)126 test1sub1(req)
127 struct req_t *req;
128 {
129 char *buf;
130
131 buf = ipsec_set_policy(req->str, strlen(req->str));
132 if (buf == NULL) {
133 printf("ipsec_set_policy: %s\n", ipsec_strerror());
134 return 1;
135 }
136
137 if (test1sub2(buf, PF_INET) != 0
138 || test1sub2(buf, PF_INET6) != 0) {
139 free(buf);
140 return 1;
141 }
142 #if 0
143 kdebug_sadb_x_policy((struct sadb_ext *)buf);
144 #endif
145
146 free(buf);
147 return 0;
148 }
149
150 int
test1sub2(policy,family)151 test1sub2(policy, family)
152 char *policy;
153 int family;
154 {
155 int so;
156 int proto = 0, optname = 0;
157 int len;
158 char getbuf[1024];
159
160 switch (family) {
161 case PF_INET:
162 proto = IPPROTO_IP;
163 optname = IP_IPSEC_POLICY;
164 break;
165 case PF_INET6:
166 proto = IPPROTO_IPV6;
167 optname = IPV6_IPSEC_POLICY;
168 break;
169 }
170
171 if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
172 err(1, "socket");
173
174 len = ipsec_get_policylen(policy);
175 #if 0
176 printf("\tsetlen:%d\n", len);
177 #endif
178
179 if (setsockopt(so, proto, optname, policy, len) < 0) {
180 printf("fail to set sockopt; %s\n", strerror(errno));
181 close(so);
182 return 1;
183 }
184
185 memset(getbuf, 0, sizeof(getbuf));
186 memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
187 if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
188 printf("fail to get sockopt; %s\n", strerror(errno));
189 close(so);
190 return 1;
191 }
192
193 {
194 char *buf = NULL;
195
196 #if 0
197 printf("\tgetlen:%d\n", len);
198 #endif
199
200 if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
201 printf("%s\n", ipsec_strerror());
202 close(so);
203 return 1;
204 }
205 #if 0
206 printf("\t[%s]\n", buf);
207 #endif
208 free(buf);
209 }
210
211 close (so);
212 return 0;
213 }
214
215 char addr[] = {
216 28, 28, 0, 0,
217 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
219 0, 0, 0, 0,
220 };
221
222 int
test2()223 test2()
224 {
225 int so;
226 char *pol1 = "out ipsec";
227 char *pol2 = "out ipsec ah/transport//use";
228 char *sp1, *sp2;
229 int splen1, splen2;
230 int spid;
231 struct sadb_msg *m;
232
233 printf("TEST2\n");
234 if (getuid() != 0)
235 errx(1, "root privilege required.");
236
237 sp1 = ipsec_set_policy(pol1, strlen(pol1));
238 splen1 = ipsec_get_policylen(sp1);
239 sp2 = ipsec_set_policy(pol2, strlen(pol2));
240 splen2 = ipsec_get_policylen(sp2);
241
242 if ((so = pfkey_open()) < 0)
243 errx(1, "ERROR: %s", ipsec_strerror());
244
245 printf("spdflush()\n");
246 if (pfkey_send_spdflush(so) < 0)
247 errx(1, "ERROR: %s", ipsec_strerror());
248 m = pfkey_recv(so);
249 free(m);
250
251 printf("spdsetidx()\n");
252 if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
253 (struct sockaddr *)addr, 128,
254 255, sp1, splen1, 0) < 0)
255 errx(1, "ERROR: %s", ipsec_strerror());
256 m = pfkey_recv(so);
257 free(m);
258
259 printf("spdupdate()\n");
260 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
261 (struct sockaddr *)addr, 128,
262 255, sp2, splen2, 0) < 0)
263 errx(1, "ERROR: %s", ipsec_strerror());
264 m = pfkey_recv(so);
265 free(m);
266
267 printf("sleep(4)\n");
268 sleep(4);
269
270 printf("spddelete()\n");
271 if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
272 (struct sockaddr *)addr, 128,
273 255, sp1, splen1, 0) < 0)
274 errx(1, "ERROR: %s", ipsec_strerror());
275 m = pfkey_recv(so);
276 free(m);
277
278 printf("spdadd()\n");
279 if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
280 (struct sockaddr *)addr, 128,
281 255, sp2, splen2, 0) < 0)
282 errx(1, "ERROR: %s", ipsec_strerror());
283 spid = test2sub(so);
284
285 printf("spdget(%u)\n", spid);
286 if (pfkey_send_spdget(so, spid) < 0)
287 errx(1, "ERROR: %s", ipsec_strerror());
288 m = pfkey_recv(so);
289 free(m);
290
291 printf("sleep(4)\n");
292 sleep(4);
293
294 printf("spddelete2()\n");
295 if (pfkey_send_spddelete2(so, spid) < 0)
296 errx(1, "ERROR: %s", ipsec_strerror());
297 m = pfkey_recv(so);
298 free(m);
299
300 printf("spdadd() with lifetime's 10(s)\n");
301 if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
302 (struct sockaddr *)addr, 128,
303 255, 0, 10, sp2, splen2, 0) < 0)
304 errx(1, "ERROR: %s", ipsec_strerror());
305 spid = test2sub(so);
306
307 /* expecting failure */
308 printf("spdupdate()\n");
309 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
310 (struct sockaddr *)addr, 128,
311 255, sp2, splen2, 0) == 0) {
312 warnx("ERROR: expecting failure.");
313 }
314
315 return 0;
316 }
317
318 int
test2sub(so)319 test2sub(so)
320 int so;
321 {
322 struct sadb_msg *msg;
323 caddr_t mhp[SADB_EXT_MAX + 1];
324
325 if ((msg = pfkey_recv(so)) == NULL)
326 errx(1, "ERROR: pfkey_recv failure.");
327 if (pfkey_align(msg, mhp) < 0)
328 errx(1, "ERROR: pfkey_align failure.");
329
330 return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
331 }
332
333