test-policy.c revision 121572
118334Speter/*	$KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $	*/
250397Sobrien
318334Speter/*
418334Speter * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
518334Speter * All rights reserved.
618334Speter *
718334Speter * Redistribution and use in source and binary forms, with or without
818334Speter * modification, are permitted provided that the following conditions
918334Speter * are met:
1018334Speter * 1. Redistributions of source code must retain the above copyright
1118334Speter *    notice, this list of conditions and the following disclaimer.
1218334Speter * 2. Redistributions in binary form must reproduce the above copyright
1318334Speter *    notice, this list of conditions and the following disclaimer in the
1418334Speter *    documentation and/or other materials provided with the distribution.
1518334Speter * 3. Neither the name of the project nor the names of its contributors
1618334Speter *    may be used to endorse or promote products derived from this software
1718334Speter *    without specific prior written permission.
1818334Speter *
1918334Speter * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2018334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2118334Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2218334Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2318334Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2418334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2518334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2618334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2718334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2818334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2918334Speter * SUCH DAMAGE.
3018334Speter */
3118334Speter
3218334Speter#include <sys/cdefs.h>
3318334Speter__FBSDID("$FreeBSD: head/lib/libipsec/test-policy.c 121572 2003-10-26 12:00:27Z ume $");
3418334Speter
3518334Speter#include <sys/types.h>
3618334Speter#include <sys/param.h>
3718334Speter#include <sys/socket.h>
3850397Sobrien
3918334Speter#include <netinet/in.h>
4018334Speter#include <net/pfkeyv2.h>
4118334Speter#include <netkey/key_debug.h>
4218334Speter#include <netinet6/ipsec.h>
4318334Speter
4418334Speter#include <stdio.h>
4518334Speter#include <stdlib.h>
4618334Speter#include <unistd.h>
4718334Speter#include <string.h>
4850397Sobrien#include <errno.h>
4918334Speter#include <err.h>
5018334Speter
5118334Speter#include "libpfkey.h"
5218334Speter
5350397Sobrienstruct req_t {
5418334Speter	int result;	/* expected result; 0:ok 1:ng */
5518334Speter	char *str;
5650397Sobrien} reqs[] = {
5750397Sobrien{ 0, "out ipsec" },
5850397Sobrien{ 1, "must_error" },
5950397Sobrien{ 1, "in ipsec must_error" },
6050397Sobrien{ 1, "out ipsec esp/must_error" },
6150397Sobrien{ 1, "out discard" },
6250397Sobrien{ 1, "out none" },
6350397Sobrien{ 0, "in entrust" },
6450397Sobrien{ 0, "out entrust" },
6550397Sobrien{ 1, "out ipsec esp" },
6650397Sobrien{ 0, "in ipsec ah/transport" },
6750397Sobrien{ 1, "in ipsec ah/tunnel" },
6850397Sobrien{ 0, "out ipsec ah/transport/" },
6918334Speter{ 1, "out ipsec ah/tunnel/" },
7018334Speter{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
7118334Speter{ 0, "in ipsec esp/tunnel/::1-::2" },
7218334Speter{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
7350397Sobrien{ 0, "in ipsec esp/tunnel/::1-::2/require" },
7418334Speter{ 0, "out ipsec ah/transport//use" },
7518334Speter{ 1, "out ipsec ah/transport esp/use" },
7618334Speter{ 1, "in ipsec ah/transport esp/tunnel" },
7718334Speter{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
7850397Sobrien{ 0, "in ipsec
7950397Sobrien	ah / transport
8050397Sobrien	esp / tunnel / ::1-::2" },
8150397Sobrien{ 0, "out ipsec
8250397Sobrien	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8350397Sobrien	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8450397Sobrien	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8550397Sobrien	" },
8650397Sobrien{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
8750397Sobrien};
8850397Sobrien
8950397Sobrienint test1(void);
9050397Sobrienint test1sub1(struct req_t *);
9150397Sobrienint test1sub2(char *, int);
9250397Sobrienint test2(void);
9350397Sobrienint test2sub(int);
9450397Sobrien
9550397Sobrienint
9618334Spetermain(ac, av)
9750397Sobrien	int ac;
9850397Sobrien	char **av;
9950397Sobrien{
10018334Speter	test1();
10118334Speter	test2();
10250397Sobrien
10350397Sobrien	exit(0);
10450397Sobrien}
10518334Speter
10618334Speterint
10718334Spetertest1()
10850397Sobrien{
10918334Speter	int i;
11018334Speter	int result;
11118334Speter
11218334Speter	printf("TEST1\n");
11318334Speter	for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
11418334Speter		printf("#%d [%s]\n", i + 1, reqs[i].str);
11518334Speter
11618334Speter		result = test1sub1(&reqs[i]);
11718334Speter		if (result == 0 && reqs[i].result == 1) {
11818334Speter			warnx("ERROR: expecting failure.");
11950397Sobrien		} else if (result == 1 && reqs[i].result == 0) {
12018334Speter			warnx("ERROR: expecting success.");
12150397Sobrien		}
12218334Speter	}
12350397Sobrien
12450397Sobrien	return 0;
12550397Sobrien}
12618334Speter
12750397Sobrienint
12850397Sobrientest1sub1(req)
12950397Sobrien	struct req_t *req;
13050397Sobrien{
13118334Speter	char *buf;
13218334Speter
13350397Sobrien	buf = ipsec_set_policy(req->str, strlen(req->str));
13450397Sobrien	if (buf == NULL) {
13550397Sobrien		printf("ipsec_set_policy: %s\n", ipsec_strerror());
13618334Speter		return 1;
13718334Speter	}
13818334Speter
13918334Speter	if (test1sub2(buf, PF_INET) != 0
14050397Sobrien	 || test1sub2(buf, PF_INET6) != 0) {
14150397Sobrien		free(buf);
14250397Sobrien		return 1;
14350397Sobrien	}
14450397Sobrien#if 0
14550397Sobrien	kdebug_sadb_x_policy((struct sadb_ext *)buf);
14650397Sobrien#endif
14750397Sobrien
14850397Sobrien	free(buf);
14950397Sobrien	return 0;
15050397Sobrien}
15150397Sobrien
15250397Sobrienint
15350397Sobrientest1sub2(policy, family)
15450397Sobrien	char *policy;
15550397Sobrien	int family;
15650397Sobrien{
15750397Sobrien	int so;
15850397Sobrien	int proto = 0, optname = 0;
15950397Sobrien	int len;
16050397Sobrien	char getbuf[1024];
16150397Sobrien
16250397Sobrien	switch (family) {
16350397Sobrien	case PF_INET:
16450397Sobrien		proto = IPPROTO_IP;
16550397Sobrien		optname = IP_IPSEC_POLICY;
16650397Sobrien		break;
16750397Sobrien	case PF_INET6:
16850397Sobrien		proto = IPPROTO_IPV6;
16950397Sobrien		optname = IPV6_IPSEC_POLICY;
17050397Sobrien		break;
17150397Sobrien	}
17250397Sobrien
17350397Sobrien	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
17450397Sobrien		err(1, "socket");
17550397Sobrien
17650397Sobrien	len = ipsec_get_policylen(policy);
17750397Sobrien#if 0
17850397Sobrien	printf("\tsetlen:%d\n", len);
17950397Sobrien#endif
18050397Sobrien
18150397Sobrien	if (setsockopt(so, proto, optname, policy, len) < 0) {
18250397Sobrien		printf("fail to set sockopt; %s\n", strerror(errno));
18350397Sobrien		close(so);
18450397Sobrien		return 1;
18550397Sobrien	}
18650397Sobrien
18750397Sobrien	memset(getbuf, 0, sizeof(getbuf));
18850397Sobrien	memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
18950397Sobrien	if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
19050397Sobrien		printf("fail to get sockopt; %s\n", strerror(errno));
19150397Sobrien		close(so);
19250397Sobrien		return 1;
19350397Sobrien	}
19450397Sobrien
19550397Sobrien    {
19650397Sobrien	char *buf = NULL;
19750397Sobrien
19850397Sobrien#if 0
19950397Sobrien	printf("\tgetlen:%d\n", len);
20050397Sobrien#endif
20150397Sobrien
20250397Sobrien	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
20350397Sobrien		printf("%s\n", ipsec_strerror());
20450397Sobrien		close(so);
20550397Sobrien		return 1;
20650397Sobrien	}
20750397Sobrien#if 0
20818334Speter	printf("\t[%s]\n", buf);
20918334Speter#endif
21018334Speter	free(buf);
21118334Speter    }
21218334Speter
21318334Speter	close (so);
21418334Speter	return 0;
21518334Speter}
21618334Speter
21718334Speterchar addr[] = {
21818334Speter	28, 28, 0, 0,
21918334Speter	0, 0, 0, 0,
22018334Speter	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
22118334Speter	0, 0, 0, 0,
22218334Speter};
22350397Sobrien
22418334Speterint
22518334Spetertest2()
22618334Speter{
22718334Speter	int so;
22818334Speter	char *pol1 = "out ipsec";
22950397Sobrien	char *pol2 = "out ipsec ah/transport//use";
23018334Speter	char *sp1, *sp2;
23150397Sobrien	int splen1, splen2;
23250397Sobrien	int spid;
23350397Sobrien	struct sadb_msg *m;
23450397Sobrien
23550397Sobrien	printf("TEST2\n");
23650397Sobrien	if (getuid() != 0)
23750397Sobrien		errx(1, "root privilege required.");
23850397Sobrien
23950397Sobrien	sp1 = ipsec_set_policy(pol1, strlen(pol1));
24050397Sobrien	splen1 = ipsec_get_policylen(sp1);
24150397Sobrien	sp2 = ipsec_set_policy(pol2, strlen(pol2));
24218334Speter	splen2 = ipsec_get_policylen(sp2);
24318334Speter
24418334Speter	if ((so = pfkey_open()) < 0)
24518334Speter		errx(1, "ERROR: %s", ipsec_strerror());
24618334Speter
24718334Speter	printf("spdflush()\n");
24818334Speter	if (pfkey_send_spdflush(so) < 0)
24918334Speter		errx(1, "ERROR: %s", ipsec_strerror());
25018334Speter	m = pfkey_recv(so);
25118334Speter	free(m);
25218334Speter
25318334Speter	printf("spdsetidx()\n");
25418334Speter	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
25518334Speter				(struct sockaddr *)addr, 128,
25618334Speter				255, sp1, splen1, 0) < 0)
25718334Speter		errx(1, "ERROR: %s", ipsec_strerror());
25818334Speter	m = pfkey_recv(so);
25918334Speter	free(m);
26018334Speter
26118334Speter	printf("spdupdate()\n");
26218334Speter	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
26318334Speter				(struct sockaddr *)addr, 128,
26450397Sobrien				255, sp2, splen2, 0) < 0)
26550397Sobrien		errx(1, "ERROR: %s", ipsec_strerror());
26618334Speter	m = pfkey_recv(so);
26718334Speter	free(m);
26850397Sobrien
26918334Speter	printf("sleep(4)\n");
27018334Speter	sleep(4);
27118334Speter
27218334Speter	printf("spddelete()\n");
27318334Speter	if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
27418334Speter				(struct sockaddr *)addr, 128,
27518334Speter				255, sp1, splen1, 0) < 0)
27650397Sobrien		errx(1, "ERROR: %s", ipsec_strerror());
27718334Speter	m = pfkey_recv(so);
27818334Speter	free(m);
27918334Speter
28050397Sobrien	printf("spdadd()\n");
28118334Speter	if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
28218334Speter				(struct sockaddr *)addr, 128,
28318334Speter				255, sp2, splen2, 0) < 0)
28450397Sobrien		errx(1, "ERROR: %s", ipsec_strerror());
28518334Speter	spid = test2sub(so);
28618334Speter
28718334Speter	printf("spdget(%u)\n", spid);
28850397Sobrien	if (pfkey_send_spdget(so, spid) < 0)
28918334Speter		errx(1, "ERROR: %s", ipsec_strerror());
29050397Sobrien	m = pfkey_recv(so);
29118334Speter	free(m);
29250397Sobrien
29318334Speter	printf("sleep(4)\n");
29450397Sobrien	sleep(4);
29518334Speter
29650397Sobrien	printf("spddelete2()\n");
29718334Speter	if (pfkey_send_spddelete2(so, spid) < 0)
29818334Speter		errx(1, "ERROR: %s", ipsec_strerror());
29918334Speter	m = pfkey_recv(so);
30018334Speter	free(m);
30118334Speter
30218334Speter	printf("spdadd() with lifetime's 10(s)\n");
30350397Sobrien	if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
30418334Speter				(struct sockaddr *)addr, 128,
30518334Speter				255, 0, 10, sp2, splen2, 0) < 0)
30618334Speter		errx(1, "ERROR: %s", ipsec_strerror());
30750397Sobrien	spid = test2sub(so);
30818334Speter
30950397Sobrien	/* expecting failure */
31050397Sobrien	printf("spdupdate()\n");
31150397Sobrien	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
31250397Sobrien				(struct sockaddr *)addr, 128,
31350397Sobrien				255, sp2, splen2, 0) == 0) {
314		warnx("ERROR: expecting failure.");
315	}
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.");
329	if (pfkey_align(msg, mhp) < 0)
330		errx(1, "ERROR: pfkey_align failure.");
331
332	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
333}
334
335