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