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