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$"); 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 55 struct 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 90 int test1(void); 91 int test1sub1(struct req_t *); 92 int test1sub2(char *, int); 93 int test2(void); 94 int test2sub(int); 95 96 int 97 main(ac, av) 98 int ac; 99 char **av; 100 { 101 test1(); 102 test2(); 103 104 exit(0); 105 } 106 107 int 108 test1() 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 128 int 129 test1sub1(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 153 int 154 test1sub2(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 218 char 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 225 int 226 test2() 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 321 int 322 test2sub(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