test-policy.c revision 78064
162583Sitojun/*	$FreeBSD: head/lib/libipsec/test-policy.c 78064 2001-06-11 12:39:29Z ume $	*/
278064Sume/*	$KAME: test-policy.c,v 1.14 2000/12/27 11:38:11 sakane Exp $	*/
362583Sitojun
455505Sshin/*
555505Sshin * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
655505Sshin * All rights reserved.
755505Sshin *
855505Sshin * Redistribution and use in source and binary forms, with or without
955505Sshin * modification, are permitted provided that the following conditions
1055505Sshin * are met:
1155505Sshin * 1. Redistributions of source code must retain the above copyright
1255505Sshin *    notice, this list of conditions and the following disclaimer.
1355505Sshin * 2. Redistributions in binary form must reproduce the above copyright
1455505Sshin *    notice, this list of conditions and the following disclaimer in the
1555505Sshin *    documentation and/or other materials provided with the distribution.
1655505Sshin * 3. Neither the name of the project nor the names of its contributors
1755505Sshin *    may be used to endorse or promote products derived from this software
1855505Sshin *    without specific prior written permission.
1955505Sshin *
2055505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2155505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2255505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2355505Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2455505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2555505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2655505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2755505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2855505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2955505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3055505Sshin * SUCH DAMAGE.
3155505Sshin */
3255505Sshin
3355505Sshin#include <sys/types.h>
3455505Sshin#include <sys/param.h>
3555505Sshin#include <sys/socket.h>
3655505Sshin
3755505Sshin#include <netinet/in.h>
3857855Sshin#include <net/pfkeyv2.h>
3955505Sshin#include <netkey/key_debug.h>
4055505Sshin#include <netinet6/ipsec.h>
4155505Sshin
4255505Sshin#include <stdio.h>
4355505Sshin#include <stdlib.h>
4455505Sshin#include <unistd.h>
4555505Sshin#include <string.h>
4662583Sitojun#include <errno.h>
4755505Sshin#include <err.h>
4855505Sshin
4978064Sume#include "libpfkey.h"
5078064Sume
5162583Sitojunstruct req_t {
5262583Sitojun	int result;	/* expected result; 0:ok 1:ng */
5362583Sitojun	char *str;
5462583Sitojun} reqs[] = {
5562583Sitojun{ 0, "out ipsec" },
5662583Sitojun{ 1, "must_error" },
5762583Sitojun{ 1, "in ipsec must_error" },
5862583Sitojun{ 1, "out ipsec esp/must_error" },
5962583Sitojun{ 1, "out discard" },
6062583Sitojun{ 1, "out none" },
6162583Sitojun{ 0, "in entrust" },
6262583Sitojun{ 0, "out entrust" },
6362583Sitojun{ 1, "out ipsec esp" },
6462583Sitojun{ 0, "in ipsec ah/transport" },
6562583Sitojun{ 1, "in ipsec ah/tunnel" },
6662583Sitojun{ 0, "out ipsec ah/transport/" },
6762583Sitojun{ 1, "out ipsec ah/tunnel/" },
6862583Sitojun{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
6962583Sitojun{ 0, "in ipsec esp/tunnel/::1-::2" },
7062583Sitojun{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
7162583Sitojun{ 0, "in ipsec esp/tunnel/::1-::2/require" },
7262583Sitojun{ 0, "out ipsec ah/transport//use" },
7362583Sitojun{ 1, "out ipsec ah/transport esp/use" },
7462583Sitojun{ 1, "in ipsec ah/transport esp/tunnel" },
7562583Sitojun{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
7662583Sitojun{ 0, "in ipsec
7755505Sshin	ah / transport
7862583Sitojun	esp / tunnel / ::1-::2" },
7962583Sitojun{ 0, "out ipsec
8062583Sitojun	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8162583Sitojun	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8262583Sitojun	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
8362583Sitojun	" },
8462583Sitojun{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
8555505Sshin};
8655505Sshin
8762583Sitojunint test1 __P((void));
8862583Sitojunint test1sub1 __P((struct req_t *));
8962583Sitojunint test1sub2 __P((char *, int));
9062583Sitojunint test2 __P((void));
9162583Sitojunint test2sub __P((int));
9255505Sshin
9355505Sshinint
9455505Sshinmain(ac, av)
9555505Sshin	int ac;
9655505Sshin	char **av;
9755505Sshin{
9862583Sitojun	test1();
9962583Sitojun	test2();
10062583Sitojun
10162583Sitojun	exit(0);
10262583Sitojun}
10362583Sitojun
10462583Sitojunint
10562583Sitojuntest1()
10662583Sitojun{
10755505Sshin	int i;
10862583Sitojun	int result;
10955505Sshin
11062583Sitojun	printf("TEST1\n");
11162583Sitojun	for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
11262583Sitojun		printf("#%d [%s]\n", i + 1, reqs[i].str);
11355505Sshin
11462583Sitojun		result = test1sub1(&reqs[i]);
11562583Sitojun		if (result == 0 && reqs[i].result == 1) {
11678064Sume			warnx("ERROR: expecting failure.\n");
11762583Sitojun		} else if (result == 1 && reqs[i].result == 0) {
11878064Sume			warnx("ERROR: expecting success.\n");
11955505Sshin		}
12062583Sitojun	}
12155505Sshin
12262583Sitojun	return 0;
12362583Sitojun}
12455505Sshin
12562583Sitojunint
12662583Sitojuntest1sub1(req)
12762583Sitojun	struct req_t *req;
12862583Sitojun{
12962583Sitojun	char *buf;
13055505Sshin
13162583Sitojun	buf = ipsec_set_policy(req->str, strlen(req->str));
13262583Sitojun	if (buf == NULL) {
13362583Sitojun		printf("ipsec_set_policy: %s\n", ipsec_strerror());
13462583Sitojun		return 1;
13562583Sitojun	}
13662583Sitojun
13762583Sitojun	if (test1sub2(buf, PF_INET) != 0
13862583Sitojun	 || test1sub2(buf, PF_INET6) != 0) {
13955505Sshin		free(buf);
14062583Sitojun		return 1;
14155505Sshin	}
14262583Sitojun#if 0
14362583Sitojun	kdebug_sadb_x_policy((struct sadb_ext *)buf);
14462583Sitojun#endif
14555505Sshin
14662583Sitojun	free(buf);
14755505Sshin	return 0;
14855505Sshin}
14955505Sshin
15055505Sshinint
15162583Sitojuntest1sub2(policy, family)
15255505Sshin	char *policy;
15355505Sshin	int family;
15455505Sshin{
15562583Sitojun	int so;
15662583Sitojun	int proto = 0, optname = 0;
15755505Sshin	int len;
15855505Sshin	char getbuf[1024];
15955505Sshin
16055505Sshin	switch (family) {
16155505Sshin	case PF_INET:
16255505Sshin		proto = IPPROTO_IP;
16355505Sshin		optname = IP_IPSEC_POLICY;
16455505Sshin		break;
16555505Sshin	case PF_INET6:
16655505Sshin		proto = IPPROTO_IPV6;
16755505Sshin		optname = IPV6_IPSEC_POLICY;
16855505Sshin		break;
16955505Sshin	}
17055505Sshin
17155505Sshin	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
17255505Sshin		err(1, "socket");
17355505Sshin
17455505Sshin	len = ipsec_get_policylen(policy);
17562583Sitojun#if 0
17662583Sitojun	printf("\tsetlen:%d\n", len);
17762583Sitojun#endif
17862583Sitojun
17955505Sshin	if (setsockopt(so, proto, optname, policy, len) < 0) {
18062583Sitojun		printf("fail to set sockopt; %s\n", strerror(errno));
18162583Sitojun		close(so);
18262583Sitojun		return 1;
18355505Sshin	}
18455505Sshin
18555505Sshin	memset(getbuf, 0, sizeof(getbuf));
18662583Sitojun	memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
18755505Sshin	if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
18862583Sitojun		printf("fail to get sockopt; %s\n", strerror(errno));
18962583Sitojun		close(so);
19062583Sitojun		return 1;
19155505Sshin	}
19255505Sshin
19355505Sshin    {
19455505Sshin	char *buf = NULL;
19555505Sshin
19662583Sitojun#if 0
19755505Sshin	printf("\tgetlen:%d\n", len);
19862583Sitojun#endif
19955505Sshin
20055505Sshin	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
20155505Sshin		printf("%s\n", ipsec_strerror());
20262583Sitojun		close(so);
20362583Sitojun		return 1;
20455505Sshin	}
20562583Sitojun#if 0
20662583Sitojun	printf("\t[%s]\n", buf);
20762583Sitojun#endif
20862583Sitojun	free(buf);
20955505Sshin    }
21055505Sshin
21155505Sshin	close (so);
21262583Sitojun	return 0;
21362583Sitojun}
21455505Sshin
21562583Sitojunchar addr[] = {
21662583Sitojun	28, 28, 0, 0,
21762583Sitojun	0, 0, 0, 0,
21862583Sitojun	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
21962583Sitojun	0, 0, 0, 0,
22062583Sitojun};
22162583Sitojun
22262583Sitojunint
22362583Sitojuntest2()
22462583Sitojun{
22562583Sitojun	int so;
22662583Sitojun	char *pol1 = "out ipsec";
22762583Sitojun	char *pol2 = "out ipsec ah/transport//use";
22862583Sitojun	char *sp1, *sp2;
22962583Sitojun	int splen1, splen2;
23062583Sitojun	int spid;
23162583Sitojun	struct sadb_msg *m;
23262583Sitojun
23362583Sitojun	printf("TEST2\n");
23462583Sitojun	if (getuid() != 0)
23562583Sitojun		errx(1, "root privilege required.\n");
23662583Sitojun
23762583Sitojun	sp1 = ipsec_set_policy(pol1, strlen(pol1));
23862583Sitojun	splen1 = ipsec_get_policylen(sp1);
23962583Sitojun	sp2 = ipsec_set_policy(pol2, strlen(pol2));
24062583Sitojun	splen2 = ipsec_get_policylen(sp2);
24162583Sitojun
24262583Sitojun	if ((so = pfkey_open()) < 0)
24362583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
24462583Sitojun
24562583Sitojun	printf("spdflush()\n");
24662583Sitojun	if (pfkey_send_spdflush(so) < 0)
24762583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
24862583Sitojun	m = pfkey_recv(so);
24962583Sitojun	free(m);
25078064Sume
25178064Sume#if 0
25262583Sitojun	printf("spdsetidx()\n");
25362583Sitojun	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
25462583Sitojun				(struct sockaddr *)addr, 128,
25562583Sitojun				255, sp1, splen1, 0) < 0)
25662583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
25762583Sitojun	m = pfkey_recv(so);
25862583Sitojun	free(m);
25962583Sitojun
26062583Sitojun	printf("spdupdate()\n");
26162583Sitojun	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
26262583Sitojun				(struct sockaddr *)addr, 128,
26362583Sitojun				255, sp2, splen2, 0) < 0)
26462583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
26562583Sitojun	m = pfkey_recv(so);
26662583Sitojun	free(m);
26762583Sitojun
26878064Sume	sleep(4);
26978064Sume
27062583Sitojun	printf("spddelete()\n");
27162583Sitojun	if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
27262583Sitojun				(struct sockaddr *)addr, 128,
27362583Sitojun				255, sp1, splen1, 0) < 0)
27462583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
27562583Sitojun	m = pfkey_recv(so);
27662583Sitojun	free(m);
27762583Sitojun
27862583Sitojun	printf("spdadd()\n");
27962583Sitojun	if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
28062583Sitojun				(struct sockaddr *)addr, 128,
28162583Sitojun				255, sp2, splen2, 0) < 0)
28262583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
28362583Sitojun	spid = test2sub(so);
28462583Sitojun
28562583Sitojun	printf("spdget(%u)\n", spid);
28662583Sitojun	if (pfkey_send_spdget(so, spid) < 0)
28762583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
28862583Sitojun	m = pfkey_recv(so);
28962583Sitojun	free(m);
29062583Sitojun
29178064Sume	sleep(4);
29278064Sume
29362583Sitojun	printf("spddelete2()\n");
29462583Sitojun	if (pfkey_send_spddelete2(so, spid) < 0)
29562583Sitojun		errx(1, "ERROR: %s\n", ipsec_strerror());
29662583Sitojun	m = pfkey_recv(so);
29762583Sitojun	free(m);
29878064Sume#endif
29962583Sitojun
30078064Sume	printf("spdadd() with lifetime's 10(s)\n");
30178064Sume	if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
30278064Sume				(struct sockaddr *)addr, 128,
30378064Sume				255, 0, 10, sp2, splen2, 0) < 0)
30478064Sume		errx(1, "ERROR: %s\n", ipsec_strerror());
30578064Sume	spid = test2sub(so);
30678064Sume
30778064Sume#if 0
30862583Sitojun	/* expecting failure */
30962583Sitojun	printf("spdupdate()\n");
31062583Sitojun	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
31162583Sitojun				(struct sockaddr *)addr, 128,
31262583Sitojun				255, sp2, splen2, 0) == 0) {
31378064Sume		warnx("ERROR: expecting failure.\n");
31462583Sitojun	}
31578064Sume#endif
31662583Sitojun
31755505Sshin	return 0;
31855505Sshin}
31955505Sshin
32062583Sitojunint
32162583Sitojuntest2sub(so)
32262583Sitojun	int so;
32362583Sitojun{
32462583Sitojun	struct sadb_msg *msg;
32562583Sitojun	caddr_t mhp[SADB_EXT_MAX + 1];
32662583Sitojun
32762583Sitojun	if ((msg = pfkey_recv(so)) == NULL)
32862583Sitojun		errx(1, "ERROR: pfkey_recv failure.\n");
32962583Sitojun	if (pfkey_align(msg, mhp) < 0)
33062583Sitojun		errx(1, "ERROR: pfkey_align failure.\n");
33162583Sitojun
33262583Sitojun	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
33362583Sitojun}
33462583Sitojun
335