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