]> git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/remoteconf.c
09089760f861a161543f2ea87f205a4f6ddafb43
[apple/network_cmds.git] / racoon.tproj / remoteconf.c
1 /* $KAME: remoteconf.c,v 1.28 2001/10/02 03:46:41 sakane Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 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/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
35 #include <sys/queue.h>
36
37 #include <netinet/in.h>
38 #include <netkey/key_var.h>
39
40 #ifdef IPV6_INRIA_VERSION
41 #include <netinet/ipsec.h>
42 #else
43 #include <netinet6/ipsec.h>
44 #endif
45
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <errno.h>
50
51 #include "var.h"
52 #include "misc.h"
53 #include "vmbuf.h"
54 #include "plog.h"
55 #include "sockmisc.h"
56 #include "debug.h"
57
58 #include "isakmp_var.h"
59 #include "isakmp.h"
60 #include "ipsec_doi.h"
61 #include "oakley.h"
62 #include "remoteconf.h"
63 #include "localconf.h"
64 #include "grabmyaddr.h"
65 #include "proposal.h"
66 #include "vendorid.h"
67 #include "gcmalloc.h"
68
69 static LIST_HEAD(_rmtree, remoteconf) rmtree;
70
71 /*%%%*/
72 /*
73 * search remote configuration.
74 * don't use port number to search if its value is either IPSEC_PORT_ANY.
75 * If matching anonymous entry, then new entry is copied from anonymous entry.
76 * If no anonymous entry found, then return NULL.
77 * OUT: NULL: NG
78 * Other: remote configuration entry.
79 */
80 struct remoteconf *
81 getrmconf(remote)
82 struct sockaddr *remote;
83 {
84 struct remoteconf *p;
85 struct remoteconf *anon = NULL;
86 int withport;
87 char buf[NI_MAXHOST + NI_MAXSERV + 10];
88 char addr[NI_MAXHOST], port[NI_MAXSERV];
89
90 withport = 0;
91
92 switch (remote->sa_family) {
93 case AF_INET:
94 if (((struct sockaddr_in *)remote)->sin_port != IPSEC_PORT_ANY)
95 withport = 1;
96 break;
97 #ifdef INET6
98 case AF_INET6:
99 if (((struct sockaddr_in6 *)remote)->sin6_port != IPSEC_PORT_ANY)
100 withport = 1;
101 break;
102 #endif
103 default:
104 plog(LLV_ERROR, LOCATION, NULL,
105 "invalid family: %d\n", remote->sa_family);
106 exit(1);
107 }
108
109 GETNAMEINFO(remote, addr, port);
110 snprintf(buf, sizeof(buf), "%s%s%s%s", addr,
111 withport ? "[" : "",
112 withport ? port : "",
113 withport ? "]" : "");
114
115 LIST_FOREACH(p, &rmtree, chain) {
116 if ((!withport && cmpsaddrwop(remote, p->remote) == 0)
117 || (withport && cmpsaddrstrict(remote, p->remote) == 0)) {
118 plog(LLV_DEBUG, LOCATION, NULL,
119 "configuration found for %s.\n", buf);
120 return p;
121 }
122
123 /* save the pointer to the anonymous configuration */
124 if (p->remote->sa_family == AF_UNSPEC)
125 anon = p;
126 }
127
128 if (anon != NULL) {
129 plog(LLV_DEBUG, LOCATION, NULL,
130 "anonymous configuration selected for %s.\n", buf);
131 return anon;
132 }
133
134 plog(LLV_DEBUG, LOCATION, NULL,
135 "no remote configuration found.\n");
136 return NULL;
137 }
138
139 struct remoteconf *
140 newrmconf()
141 {
142 struct remoteconf *new;
143
144 new = racoon_calloc(1, sizeof(*new));
145 if (new == NULL)
146 return NULL;
147
148 new->proposal = NULL;
149
150 /* set default */
151 new->doitype = IPSEC_DOI;
152 new->sittype = IPSECDOI_SIT_IDENTITY_ONLY;
153 new->idvtype = IDTYPE_ADDRESS;
154 new->idvtype_p = IDTYPE_ADDRESS;
155 new->nonce_size = DEFAULT_NONCE_SIZE;
156 new->keepalive = FALSE;
157 new->passive = FALSE;
158 new->ini_contact = TRUE;
159 new->pcheck_level = PROP_CHECK_STRICT;
160 new->verify_identifier = FALSE;
161 new->verify_cert = TRUE;
162 new->getcert_method = ISAKMP_GETCERT_PAYLOAD;
163 new->send_cert = TRUE;
164 new->send_cr = TRUE;
165 new->support_mip6 = FALSE;
166 new->gen_policy = FALSE;
167 new->retry_counter = lcconf->retry_counter;
168 new->retry_interval = lcconf->retry_interval;
169
170 return new;
171 }
172
173 void
174 delrmconf(rmconf)
175 struct remoteconf *rmconf;
176 {
177 if (rmconf->etypes)
178 deletypes(rmconf->etypes);
179 if (rmconf->dhgrp)
180 oakley_dhgrp_free(rmconf->dhgrp);
181 if (rmconf->proposal)
182 delisakmpsa(rmconf->proposal);
183 racoon_free(rmconf);
184 }
185
186 void
187 delisakmpsa(sa)
188 struct isakmpsa *sa;
189 {
190 if (sa->dhgrp)
191 oakley_dhgrp_free(sa->dhgrp);
192 if (sa->next)
193 delisakmpsa(sa->next);
194 #ifdef HAVE_GSSAPI
195 if (sa->gssid)
196 vfree(sa->gssid);
197 #endif
198 racoon_free(sa);
199 }
200
201 void
202 deletypes(e)
203 struct etypes *e;
204 {
205 if (e->next)
206 deletypes(e->next);
207 racoon_free(e);
208 }
209
210 /*
211 * insert into head of list.
212 */
213 void
214 insrmconf(new)
215 struct remoteconf *new;
216 {
217 LIST_INSERT_HEAD(&rmtree, new, chain);
218 }
219
220 void
221 remrmconf(rmconf)
222 struct remoteconf *rmconf;
223 {
224 LIST_REMOVE(rmconf, chain);
225 }
226
227 void
228 flushrmconf()
229 {
230 struct remoteconf *p, *next;
231
232 for (p = LIST_FIRST(&rmtree); p; p = next) {
233 next = LIST_NEXT(p, chain);
234 remrmconf(p);
235 delrmconf(p);
236 }
237 }
238
239 void
240 initrmconf()
241 {
242 LIST_INIT(&rmtree);
243 }
244
245 /* check exchange type to be acceptable */
246 struct etypes *
247 check_etypeok(rmconf, etype)
248 struct remoteconf *rmconf;
249 u_int8_t etype;
250 {
251 struct etypes *e;
252
253 for (e = rmconf->etypes; e != NULL; e = e->next) {
254 if (e->type == etype)
255 break;
256 }
257
258 return e;
259 }
260
261 /*%%%*/
262 struct isakmpsa *
263 newisakmpsa()
264 {
265 struct isakmpsa *new;
266
267 new = racoon_calloc(1, sizeof(*new));
268 if (new == NULL)
269 return NULL;
270
271 /*
272 * Just for sanity, make sure this is initialized. This is
273 * filled in for real when the ISAKMP proposal is configured.
274 */
275 new->vendorid = VENDORID_UNKNOWN;
276
277 new->next = NULL;
278 new->rmconf = NULL;
279 #ifdef HAVE_GSSAPI
280 new->gssid = NULL;
281 #endif
282
283 return new;
284 }
285
286 /*
287 * insert into tail of list.
288 */
289 void
290 insisakmpsa(new, rmconf)
291 struct isakmpsa *new;
292 struct remoteconf *rmconf;
293 {
294 struct isakmpsa *p;
295
296 new->rmconf = rmconf;
297
298 if (rmconf->proposal == NULL) {
299 rmconf->proposal = new;
300 return;
301 }
302
303 for (p = rmconf->proposal; p->next != NULL; p = p->next)
304 ;
305 p->next = new;
306
307 return;
308 }
309
310 const char *
311 rm2str(rmconf)
312 const struct remoteconf *rmconf;
313 {
314 if (rmconf->remote->sa_family == AF_UNSPEC)
315 return "anonymous";
316 return saddr2str(rmconf->remote);
317 }