test-policy.c revision 62583
1/*	$FreeBSD: head/lib/libipsec/test-policy.c 62583 2000-07-04 16:22:05Z itojun $	*/
2/*	$KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun 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
49struct req_t {
50	int result;	/* expected result; 0:ok 1:ng */
51	char *str;
52} reqs[] = {
53{ 0, "out ipsec" },
54{ 1, "must_error" },
55{ 1, "in ipsec must_error" },
56{ 1, "out ipsec esp/must_error" },
57{ 1, "out discard" },
58{ 1, "out none" },
59{ 0, "in entrust" },
60{ 0, "out entrust" },
61{ 1, "out ipsec esp" },
62{ 0, "in ipsec ah/transport" },
63{ 1, "in ipsec ah/tunnel" },
64{ 0, "out ipsec ah/transport/" },
65{ 1, "out ipsec ah/tunnel/" },
66{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
67{ 0, "in ipsec esp/tunnel/::1-::2" },
68{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
69{ 0, "in ipsec esp/tunnel/::1-::2/require" },
70{ 0, "out ipsec ah/transport//use" },
71{ 1, "out ipsec ah/transport esp/use" },
72{ 1, "in ipsec ah/transport esp/tunnel" },
73{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
74{ 0, "in ipsec
75	ah / transport
76	esp / tunnel / ::1-::2" },
77{ 0, "out ipsec
78	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
79	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
80	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
81	" },
82{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
83};
84
85int test1 __P((void));
86int test1sub1 __P((struct req_t *));
87int test1sub2 __P((char *, int));
88int test2 __P((void));
89int test2sub __P((int));
90
91int
92main(ac, av)
93	int ac;
94	char **av;
95{
96	test1();
97	test2();
98
99	exit(0);
100}
101
102int
103test1()
104{
105	int i;
106	int result;
107
108	printf("TEST1\n");
109	for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
110		printf("#%d [%s]\n", i + 1, reqs[i].str);
111
112		result = test1sub1(&reqs[i]);
113		if (result == 0 && reqs[i].result == 1) {
114			errx(1, "ERROR: expecting failure.\n");
115		} else if (result == 1 && reqs[i].result == 0) {
116			errx(1, "ERROR: expecting success.\n");
117		}
118	}
119
120	return 0;
121}
122
123int
124test1sub1(req)
125	struct req_t *req;
126{
127	char *buf;
128
129	buf = ipsec_set_policy(req->str, strlen(req->str));
130	if (buf == NULL) {
131		printf("ipsec_set_policy: %s\n", ipsec_strerror());
132		return 1;
133	}
134
135	if (test1sub2(buf, PF_INET) != 0
136	 || test1sub2(buf, PF_INET6) != 0) {
137		free(buf);
138		return 1;
139	}
140#if 0
141	kdebug_sadb_x_policy((struct sadb_ext *)buf);
142#endif
143
144	free(buf);
145	return 0;
146}
147
148int
149test1sub2(policy, family)
150	char *policy;
151	int family;
152{
153	int so;
154	int proto = 0, optname = 0;
155	int len;
156	char getbuf[1024];
157
158	switch (family) {
159	case PF_INET:
160		proto = IPPROTO_IP;
161		optname = IP_IPSEC_POLICY;
162		break;
163	case PF_INET6:
164		proto = IPPROTO_IPV6;
165		optname = IPV6_IPSEC_POLICY;
166		break;
167	}
168
169	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
170		err(1, "socket");
171
172	len = ipsec_get_policylen(policy);
173#if 0
174	printf("\tsetlen:%d\n", len);
175#endif
176
177	if (setsockopt(so, proto, optname, policy, len) < 0) {
178		printf("fail to set sockopt; %s\n", strerror(errno));
179		close(so);
180		return 1;
181	}
182
183	memset(getbuf, 0, sizeof(getbuf));
184	memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
185	if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
186		printf("fail to get sockopt; %s\n", strerror(errno));
187		close(so);
188		return 1;
189	}
190
191    {
192	char *buf = NULL;
193
194#if 0
195	printf("\tgetlen:%d\n", len);
196#endif
197
198	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
199		printf("%s\n", ipsec_strerror());
200		close(so);
201		return 1;
202	}
203#if 0
204	printf("\t[%s]\n", buf);
205#endif
206	free(buf);
207    }
208
209	close (so);
210	return 0;
211}
212
213char addr[] = {
214	28, 28, 0, 0,
215	0, 0, 0, 0,
216	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
217	0, 0, 0, 0,
218};
219
220int
221test2()
222{
223	int so;
224	char *pol1 = "out ipsec";
225	char *pol2 = "out ipsec ah/transport//use";
226	char *sp1, *sp2;
227	int splen1, splen2;
228	int spid;
229	struct sadb_msg *m;
230
231	printf("TEST2\n");
232	if (getuid() != 0)
233		errx(1, "root privilege required.\n");
234
235	sp1 = ipsec_set_policy(pol1, strlen(pol1));
236	splen1 = ipsec_get_policylen(sp1);
237	sp2 = ipsec_set_policy(pol2, strlen(pol2));
238	splen2 = ipsec_get_policylen(sp2);
239
240	if ((so = pfkey_open()) < 0)
241		errx(1, "ERROR: %s\n", ipsec_strerror());
242
243	printf("spdflush()\n");
244	if (pfkey_send_spdflush(so) < 0)
245		errx(1, "ERROR: %s\n", ipsec_strerror());
246	m = pfkey_recv(so);
247	free(m);
248
249	printf("spdsetidx()\n");
250	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
251				(struct sockaddr *)addr, 128,
252				255, sp1, splen1, 0) < 0)
253		errx(1, "ERROR: %s\n", ipsec_strerror());
254	m = pfkey_recv(so);
255	free(m);
256
257	printf("spdupdate()\n");
258	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
259				(struct sockaddr *)addr, 128,
260				255, sp2, splen2, 0) < 0)
261		errx(1, "ERROR: %s\n", ipsec_strerror());
262	m = pfkey_recv(so);
263	free(m);
264
265	printf("spddelete()\n");
266	if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
267				(struct sockaddr *)addr, 128,
268				255, sp1, splen1, 0) < 0)
269		errx(1, "ERROR: %s\n", ipsec_strerror());
270	m = pfkey_recv(so);
271	free(m);
272
273	printf("spdadd()\n");
274	if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
275				(struct sockaddr *)addr, 128,
276				255, sp2, splen2, 0) < 0)
277		errx(1, "ERROR: %s\n", ipsec_strerror());
278	spid = test2sub(so);
279
280	printf("spdget(%u)\n", spid);
281	if (pfkey_send_spdget(so, spid) < 0)
282		errx(1, "ERROR: %s\n", ipsec_strerror());
283	m = pfkey_recv(so);
284	free(m);
285
286	printf("spddelete2()\n");
287	if (pfkey_send_spddelete2(so, spid) < 0)
288		errx(1, "ERROR: %s\n", ipsec_strerror());
289	m = pfkey_recv(so);
290	free(m);
291
292	/* expecting failure */
293	printf("spdupdate()\n");
294	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
295				(struct sockaddr *)addr, 128,
296				255, sp2, splen2, 0) == 0) {
297		errx(1, "ERROR: expecting failure.\n");
298	}
299
300	return 0;
301}
302
303int
304test2sub(so)
305	int so;
306{
307	struct sadb_msg *msg;
308	caddr_t mhp[SADB_EXT_MAX + 1];
309
310	if ((msg = pfkey_recv(so)) == NULL)
311		errx(1, "ERROR: pfkey_recv failure.\n");
312	if (pfkey_align(msg, mhp) < 0)
313		errx(1, "ERROR: pfkey_align failure.\n");
314
315	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
316}
317
318