1 1.8 rillig /* $NetBSD: ipsec.c,v 1.8 2021/09/03 21:02:04 rillig Exp $ */ 2 1.1 itojun 3 1.1 itojun /* 4 1.1 itojun * Copyright (C) 1999 WIDE Project. 5 1.1 itojun * All rights reserved. 6 1.6 rillig * 7 1.1 itojun * Redistribution and use in source and binary forms, with or without 8 1.1 itojun * modification, are permitted provided that the following conditions 9 1.1 itojun * are met: 10 1.1 itojun * 1. Redistributions of source code must retain the above copyright 11 1.1 itojun * notice, this list of conditions and the following disclaimer. 12 1.1 itojun * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 itojun * notice, this list of conditions and the following disclaimer in the 14 1.1 itojun * documentation and/or other materials provided with the distribution. 15 1.1 itojun * 3. Neither the name of the project nor the names of its contributors 16 1.1 itojun * may be used to endorse or promote products derived from this software 17 1.1 itojun * without specific prior written permission. 18 1.6 rillig * 19 1.1 itojun * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 1.1 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 1.1 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 itojun * SUCH DAMAGE. 30 1.1 itojun */ 31 1.1 itojun 32 1.1 itojun #include <sys/param.h> 33 1.1 itojun #include <sys/stat.h> 34 1.1 itojun #include <sys/socket.h> 35 1.1 itojun 36 1.1 itojun #include <netinet/in.h> 37 1.1 itojun #include <arpa/inet.h> 38 1.1 itojun 39 1.7 rillig #include <stdbool.h> 40 1.1 itojun #include <stdio.h> 41 1.1 itojun #include <stdlib.h> 42 1.1 itojun #include <string.h> 43 1.1 itojun #include <unistd.h> 44 1.1 itojun #include <ctype.h> 45 1.1 itojun 46 1.1 itojun #ifdef IPSEC 47 1.4 drochner #include <netipsec/ipsec.h> 48 1.1 itojun #ifndef IPSEC_POLICY_IPSEC /* no ipsec support on old ipsec */ 49 1.1 itojun #undef IPSEC 50 1.1 itojun #endif 51 1.1 itojun #endif 52 1.1 itojun 53 1.1 itojun #include "ipsec.h" 54 1.1 itojun 55 1.1 itojun #ifdef IPSEC 56 1.1 itojun int 57 1.3 christos ipsecsetup(int af, int fd, const char *policy) 58 1.1 itojun { 59 1.1 itojun char *p0, *p; 60 1.1 itojun int error; 61 1.1 itojun 62 1.7 rillig if (policy == NULL || *policy == '\0') 63 1.1 itojun p0 = p = strdup("in entrust; out entrust"); 64 1.1 itojun else 65 1.1 itojun p0 = p = strdup(policy); 66 1.1 itojun 67 1.1 itojun error = 0; 68 1.3 christos for (;;) { 69 1.1 itojun p = strtok(p, ";"); 70 1.1 itojun if (p == NULL) 71 1.1 itojun break; 72 1.8 rillig while (isspace((unsigned char)*p)) 73 1.1 itojun p++; 74 1.7 rillig if (*p == '\0') { 75 1.1 itojun p = NULL; 76 1.1 itojun continue; 77 1.1 itojun } 78 1.7 rillig error = ipsecsetup0(af, fd, p, true); 79 1.1 itojun if (error < 0) 80 1.1 itojun break; 81 1.1 itojun p = NULL; 82 1.1 itojun } 83 1.1 itojun 84 1.1 itojun free(p0); 85 1.1 itojun return error; 86 1.1 itojun } 87 1.1 itojun 88 1.1 itojun int 89 1.3 christos ipsecsetup_test(const char *policy) 90 1.1 itojun { 91 1.1 itojun char *p0, *p; 92 1.1 itojun char *buf; 93 1.1 itojun int error; 94 1.1 itojun 95 1.7 rillig if (policy == NULL) 96 1.1 itojun return -1; 97 1.3 christos p0 = p = strdup(policy); 98 1.3 christos if (p == NULL) 99 1.3 christos return -1; 100 1.1 itojun 101 1.1 itojun error = 0; 102 1.3 christos for (;;) { 103 1.1 itojun p = strtok(p, ";"); 104 1.1 itojun if (p == NULL) 105 1.1 itojun break; 106 1.8 rillig while (isspace((unsigned char)*p)) 107 1.1 itojun p++; 108 1.7 rillig if (*p == '\0') { 109 1.1 itojun p = NULL; 110 1.1 itojun continue; 111 1.1 itojun } 112 1.3 christos buf = ipsec_set_policy(p, (int)strlen(p)); 113 1.1 itojun if (buf == NULL) { 114 1.1 itojun error = -1; 115 1.1 itojun break; 116 1.1 itojun } 117 1.1 itojun free(buf); 118 1.1 itojun p = NULL; 119 1.1 itojun } 120 1.1 itojun 121 1.1 itojun free(p0); 122 1.1 itojun return error; 123 1.1 itojun } 124 1.1 itojun 125 1.1 itojun int 126 1.3 christos ipsecsetup0(int af, int fd, const char *policy, int commit) 127 1.1 itojun { 128 1.1 itojun int level; 129 1.1 itojun int opt; 130 1.1 itojun char *buf; 131 1.1 itojun int error; 132 1.1 itojun 133 1.1 itojun switch (af) { 134 1.1 itojun case AF_INET: 135 1.1 itojun level = IPPROTO_IP; 136 1.1 itojun opt = IP_IPSEC_POLICY; 137 1.1 itojun break; 138 1.1 itojun #ifdef INET6 139 1.1 itojun case AF_INET6: 140 1.1 itojun level = IPPROTO_IPV6; 141 1.1 itojun opt = IPV6_IPSEC_POLICY; 142 1.1 itojun break; 143 1.1 itojun #endif 144 1.1 itojun default: 145 1.1 itojun return -1; 146 1.1 itojun } 147 1.1 itojun 148 1.3 christos buf = ipsec_set_policy(policy, (int)strlen(policy)); 149 1.1 itojun if (buf != NULL) { 150 1.1 itojun error = 0; 151 1.1 itojun if (commit && setsockopt(fd, level, opt, 152 1.3 christos buf, (socklen_t)ipsec_get_policylen(buf)) < 0) { 153 1.1 itojun error = -1; 154 1.1 itojun } 155 1.1 itojun free(buf); 156 1.1 itojun } else 157 1.1 itojun error = -1; 158 1.1 itojun return error; 159 1.1 itojun } 160 1.1 itojun #endif 161