test-policy.c revision 78064
1/*	$FreeBSD: head/lib/libipsec/test-policy.c 78064 2001-06-11 12:39:29Z ume $	*/
2/*	$KAME: test-policy.c,v 1.14 2000/12/27 11:38:11 sakane Exp $	*/
3
4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/types.h>
34#include <sys/param.h>
35#include <sys/socket.h>
36
37#include <netinet/in.h>
38#include <net/pfkeyv2.h>
39#include <netkey/key_debug.h>
40#include <netinet6/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
51struct 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
87int test1 __P((void));
88int test1sub1 __P((struct req_t *));
89int test1sub2 __P((char *, int));
90int test2 __P((void));
91int test2sub __P((int));
92
93int
94main(ac, av)
95	int ac;
96	char **av;
97{
98	test1();
99	test2();
100
101	exit(0);
102}
103
104int
105test1()
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.\n");
117		} else if (result == 1 && reqs[i].result == 0) {
118			warnx("ERROR: expecting success.\n");
119		}
120	}
121
122	return 0;
123}
124
125int
126test1sub1(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
150int
151test1sub2(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
215char 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
222int
223test2()
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.\n");
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\n", ipsec_strerror());
244
245	printf("spdflush()\n");
246	if (pfkey_send_spdflush(so) < 0)
247		errx(1, "ERROR: %s\n", ipsec_strerror());
248	m = pfkey_recv(so);
249	free(m);
250
251#if 0
252	printf("spdsetidx()\n");
253	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
254				(struct sockaddr *)addr, 128,
255				255, sp1, splen1, 0) < 0)
256		errx(1, "ERROR: %s\n", ipsec_strerror());
257	m = pfkey_recv(so);
258	free(m);
259
260	printf("spdupdate()\n");
261	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
262				(struct sockaddr *)addr, 128,
263				255, sp2, splen2, 0) < 0)
264		errx(1, "ERROR: %s\n", ipsec_strerror());
265	m = pfkey_recv(so);
266	free(m);
267
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\n", 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\n", 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\n", ipsec_strerror());
288	m = pfkey_recv(so);
289	free(m);
290
291	sleep(4);
292
293	printf("spddelete2()\n");
294	if (pfkey_send_spddelete2(so, spid) < 0)
295		errx(1, "ERROR: %s\n", ipsec_strerror());
296	m = pfkey_recv(so);
297	free(m);
298#endif
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\n", ipsec_strerror());
305	spid = test2sub(so);
306
307#if 0
308	/* expecting failure */
309	printf("spdupdate()\n");
310	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
311				(struct sockaddr *)addr, 128,
312				255, sp2, splen2, 0) == 0) {
313		warnx("ERROR: expecting failure.\n");
314	}
315#endif
316
317	return 0;
318}
319
320int
321test2sub(so)
322	int so;
323{
324	struct sadb_msg *msg;
325	caddr_t mhp[SADB_EXT_MAX + 1];
326
327	if ((msg = pfkey_recv(so)) == NULL)
328		errx(1, "ERROR: pfkey_recv failure.\n");
329	if (pfkey_align(msg, mhp) < 0)
330		errx(1, "ERROR: pfkey_align failure.\n");
331
332	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
333}
334
335