test-policy.c revision 62583
142421Syokota/* $FreeBSD: head/lib/libipsec/test-policy.c 62583 2000-07-04 16:22:05Z itojun $ */ 242421Syokota/* $KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun Exp $ */ 342421Syokota 442421Syokota/* 542421Syokota * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 642421Syokota * All rights reserved. 742421Syokota * 842421Syokota * Redistribution and use in source and binary forms, with or without 942421Syokota * modification, are permitted provided that the following conditions 1042421Syokota * are met: 1142421Syokota * 1. Redistributions of source code must retain the above copyright 1242421Syokota * notice, this list of conditions and the following disclaimer. 1342421Syokota * 2. Redistributions in binary form must reproduce the above copyright 1442421Syokota * notice, this list of conditions and the following disclaimer in the 1542421Syokota * documentation and/or other materials provided with the distribution. 1642421Syokota * 3. Neither the name of the project nor the names of its contributors 1742421Syokota * may be used to endorse or promote products derived from this software 1842421Syokota * without specific prior written permission. 1942421Syokota * 2042421Syokota * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2142421Syokota * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2242421Syokota * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2342421Syokota * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2442421Syokota * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2542421Syokota * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2648878Syokota * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2742421Syokota * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2842421Syokota * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2942421Syokota * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3042421Syokota * SUCH DAMAGE. 3144628Syokota */ 3242421Syokota 3342421Syokota#include <sys/types.h> 3442421Syokota#include <sys/param.h> 3542421Syokota#include <sys/socket.h> 3642421Syokota 3742421Syokota#include <netinet/in.h> 3842421Syokota#include <net/pfkeyv2.h> 3942421Syokota#include <netkey/key_debug.h> 4047336Syokota#include <netinet6/ipsec.h> 4142421Syokota 4242421Syokota#include <stdio.h> 4342421Syokota#include <stdlib.h> 4442421Syokota#include <unistd.h> 4542421Syokota#include <string.h> 4642421Syokota#include <errno.h> 4742421Syokota#include <err.h> 4842421Syokota 4942421Syokotastruct req_t { 5042831Syokota int result; /* expected result; 0:ok 1:ng */ 5142831Syokota char *str; 5242421Syokota} reqs[] = { 5342421Syokota{ 0, "out ipsec" }, 5442421Syokota{ 1, "must_error" }, 5547336Syokota{ 1, "in ipsec must_error" }, 5642421Syokota{ 1, "out ipsec esp/must_error" }, 5742421Syokota{ 1, "out discard" }, 5842421Syokota{ 1, "out none" }, 5942421Syokota{ 0, "in entrust" }, 6042421Syokota{ 0, "out entrust" }, 6142421Syokota{ 1, "out ipsec esp" }, 6242421Syokota{ 0, "in ipsec ah/transport" }, 6342421Syokota{ 1, "in ipsec ah/tunnel" }, 6442421Syokota{ 0, "out ipsec ah/transport/" }, 6542421Syokota{ 1, "out ipsec ah/tunnel/" }, 6642421Syokota{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" }, 6747625Sphk{ 0, "in ipsec esp/tunnel/::1-::2" }, 6847625Sphk{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" }, 6947625Sphk{ 0, "in ipsec esp/tunnel/::1-::2/require" }, 7047625Sphk{ 0, "out ipsec ah/transport//use" }, 7147625Sphk{ 1, "out ipsec ah/transport esp/use" }, 7247625Sphk{ 1, "in ipsec ah/transport esp/tunnel" }, 7347625Sphk{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" }, 7447625Sphk{ 0, "in ipsec 7547625Sphk ah / transport 7647625Sphk esp / tunnel / ::1-::2" }, 7747625Sphk{ 0, "out ipsec 7847625Sphk ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 7947625Sphk ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 8047625Sphk ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 8147625Sphk " }, 8247625Sphk{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" }, 8347625Sphk}; 8447625Sphk 8547625Sphkint test1 __P((void)); 8647625Sphkint test1sub1 __P((struct req_t *)); 8742421Syokotaint test1sub2 __P((char *, int)); 8842421Syokotaint test2 __P((void)); 8942421Syokotaint test2sub __P((int)); 9042421Syokota 9142421Syokotaint 9244628Syokotamain(ac, av) 9342421Syokota int ac; 9442421Syokota char **av; 9542421Syokota{ 9644628Syokota test1(); 9742421Syokota test2(); 9842421Syokota 9942421Syokota exit(0); 10042421Syokota} 10142421Syokota 10242421Syokotaint 10342421Syokotatest1() 10444628Syokota{ 10544628Syokota int i; 10644628Syokota int result; 10744628Syokota 10842421Syokota printf("TEST1\n"); 10942421Syokota for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) { 11042421Syokota printf("#%d [%s]\n", i + 1, reqs[i].str); 11144628Syokota 11242421Syokota result = test1sub1(&reqs[i]); 11342421Syokota if (result == 0 && reqs[i].result == 1) { 11444628Syokota errx(1, "ERROR: expecting failure.\n"); 11542421Syokota } else if (result == 1 && reqs[i].result == 0) { 11642421Syokota errx(1, "ERROR: expecting success.\n"); 11742421Syokota } 11842421Syokota } 11942421Syokota 12042421Syokota return 0; 12142421Syokota} 12242421Syokota 12342421Syokotaint 12442421Syokotatest1sub1(req) 12544628Syokota struct req_t *req; 12644628Syokota{ 12744628Syokota char *buf; 12844628Syokota 12942421Syokota buf = ipsec_set_policy(req->str, strlen(req->str)); 13044628Syokota if (buf == NULL) { 13144628Syokota printf("ipsec_set_policy: %s\n", ipsec_strerror()); 13244628Syokota return 1; 13344628Syokota } 13442421Syokota 13542421Syokota if (test1sub2(buf, PF_INET) != 0 13642421Syokota || test1sub2(buf, PF_INET6) != 0) { 13742421Syokota free(buf); 13842421Syokota return 1; 13942421Syokota } 14042421Syokota#if 0 14142421Syokota kdebug_sadb_x_policy((struct sadb_ext *)buf); 14242421Syokota#endif 14342421Syokota 14442421Syokota free(buf); 14542421Syokota return 0; 14642421Syokota} 14742421Syokota 14842421Syokotaint 14942421Syokotatest1sub2(policy, family) 15042421Syokota char *policy; 15142421Syokota int family; 15242421Syokota{ 15342421Syokota int so; 15442421Syokota int proto = 0, optname = 0; 15542421Syokota int len; 15642421Syokota char getbuf[1024]; 15742421Syokota 15842421Syokota switch (family) { 15942421Syokota case PF_INET: 16042421Syokota proto = IPPROTO_IP; 16142421Syokota optname = IP_IPSEC_POLICY; 16242421Syokota break; 16342421Syokota case PF_INET6: 16442421Syokota proto = IPPROTO_IPV6; 16542421Syokota optname = IPV6_IPSEC_POLICY; 16642421Syokota break; 16742421Syokota } 16842421Syokota 16942421Syokota if ((so = socket(family, SOCK_DGRAM, 0)) < 0) 17042421Syokota err(1, "socket"); 17142421Syokota 17242421Syokota len = ipsec_get_policylen(policy); 17342421Syokota#if 0 17442421Syokota printf("\tsetlen:%d\n", len); 17542421Syokota#endif 17642421Syokota 17742421Syokota if (setsockopt(so, proto, optname, policy, len) < 0) { 17842421Syokota printf("fail to set sockopt; %s\n", strerror(errno)); 17942421Syokota close(so); 18042421Syokota return 1; 18142421Syokota } 18242421Syokota 18342421Syokota memset(getbuf, 0, sizeof(getbuf)); 18442421Syokota memcpy(getbuf, policy, sizeof(struct sadb_x_policy)); 18542421Syokota if (getsockopt(so, proto, optname, getbuf, &len) < 0) { 18642421Syokota printf("fail to get sockopt; %s\n", strerror(errno)); 18744628Syokota close(so); 18842421Syokota return 1; 18942421Syokota } 19042421Syokota 19142421Syokota { 19242421Syokota char *buf = NULL; 19342421Syokota 19442421Syokota#if 0 19542421Syokota printf("\tgetlen:%d\n", len); 19642421Syokota#endif 19742421Syokota 19842421Syokota if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { 19942421Syokota printf("%s\n", ipsec_strerror()); 20042421Syokota close(so); 20142421Syokota return 1; 20244628Syokota } 20344628Syokota#if 0 20442421Syokota printf("\t[%s]\n", buf); 20542421Syokota#endif 20642421Syokota free(buf); 20742421Syokota } 20842421Syokota 20942421Syokota close (so); 21042421Syokota return 0; 21142421Syokota} 21242421Syokota 21342421Syokotachar addr[] = { 21442421Syokota 28, 28, 0, 0, 21542421Syokota 0, 0, 0, 0, 21642421Syokota 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 21742421Syokota 0, 0, 0, 0, 21842421Syokota}; 21942421Syokota 22042421Syokotaint 22142421Syokotatest2() 22242421Syokota{ 22342421Syokota int so; 22442421Syokota char *pol1 = "out ipsec"; 22542421Syokota char *pol2 = "out ipsec ah/transport//use"; 22642421Syokota char *sp1, *sp2; 22742421Syokota int splen1, splen2; 22842421Syokota int spid; 22942421Syokota struct sadb_msg *m; 23042421Syokota 23142421Syokota printf("TEST2\n"); 23242421Syokota if (getuid() != 0) 23342421Syokota errx(1, "root privilege required.\n"); 23442421Syokota 23542421Syokota sp1 = ipsec_set_policy(pol1, strlen(pol1)); 23642421Syokota splen1 = ipsec_get_policylen(sp1); 23742421Syokota sp2 = ipsec_set_policy(pol2, strlen(pol2)); 23842421Syokota splen2 = ipsec_get_policylen(sp2); 23942421Syokota 24042421Syokota if ((so = pfkey_open()) < 0) 24142421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 24242421Syokota 24342421Syokota printf("spdflush()\n"); 24442421Syokota if (pfkey_send_spdflush(so) < 0) 24542421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 24642421Syokota m = pfkey_recv(so); 24742421Syokota free(m); 24842421Syokota 24942421Syokota printf("spdsetidx()\n"); 25042421Syokota if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128, 25142421Syokota (struct sockaddr *)addr, 128, 25242421Syokota 255, sp1, splen1, 0) < 0) 25342421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 25442421Syokota m = pfkey_recv(so); 25542421Syokota free(m); 25642421Syokota 25742421Syokota printf("spdupdate()\n"); 25842421Syokota if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 25942421Syokota (struct sockaddr *)addr, 128, 26042421Syokota 255, sp2, splen2, 0) < 0) 26142421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 26242421Syokota m = pfkey_recv(so); 26342421Syokota free(m); 26442421Syokota 26542421Syokota printf("spddelete()\n"); 26644628Syokota if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128, 26742421Syokota (struct sockaddr *)addr, 128, 26842421Syokota 255, sp1, splen1, 0) < 0) 26942421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 27042421Syokota m = pfkey_recv(so); 27142421Syokota free(m); 27242421Syokota 27342421Syokota printf("spdadd()\n"); 27442421Syokota if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128, 27542421Syokota (struct sockaddr *)addr, 128, 27642421Syokota 255, sp2, splen2, 0) < 0) 27742421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 27842421Syokota spid = test2sub(so); 27942421Syokota 28042421Syokota printf("spdget(%u)\n", spid); 28142421Syokota if (pfkey_send_spdget(so, spid) < 0) 28242421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 28342421Syokota m = pfkey_recv(so); 28442421Syokota free(m); 28542421Syokota 28642421Syokota printf("spddelete2()\n"); 28742421Syokota if (pfkey_send_spddelete2(so, spid) < 0) 28842421Syokota errx(1, "ERROR: %s\n", ipsec_strerror()); 28942421Syokota m = pfkey_recv(so); 29042421Syokota free(m); 29144628Syokota 29242421Syokota /* expecting failure */ 29342421Syokota printf("spdupdate()\n"); 29442421Syokota if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 29542421Syokota (struct sockaddr *)addr, 128, 29642421Syokota 255, sp2, splen2, 0) == 0) { 29742421Syokota errx(1, "ERROR: expecting failure.\n"); 29842421Syokota } 29942421Syokota 30042421Syokota return 0; 30142421Syokota} 30242421Syokota 30342421Syokotaint 30442421Syokotatest2sub(so) 30542421Syokota int so; 30642421Syokota{ 30742421Syokota struct sadb_msg *msg; 30842421Syokota caddr_t mhp[SADB_EXT_MAX + 1]; 30942421Syokota 31042421Syokota if ((msg = pfkey_recv(so)) == NULL) 31144628Syokota errx(1, "ERROR: pfkey_recv failure.\n"); 31242421Syokota if (pfkey_align(msg, mhp) < 0) 31342421Syokota errx(1, "ERROR: pfkey_align failure.\n"); 31442421Syokota 31542421Syokota return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; 31642421Syokota} 31742421Syokota 31842421Syokota