]> git.saurik.com Git - apple/network_cmds.git/blame - racoon.tproj/remoteconf.c
network_cmds-245.tar.gz
[apple/network_cmds.git] / racoon.tproj / remoteconf.c
CommitLineData
ac2f15b3 1/* $KAME: remoteconf.c,v 1.29 2001/12/07 08:39:39 sakane Exp $ */
7ba0088d
A
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
69static 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 */
80struct remoteconf *
81getrmconf(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
139struct remoteconf *
140newrmconf()
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
173void
174delrmconf(rmconf)
175 struct remoteconf *rmconf;
176{
2b484d24 177
7ba0088d
A
178 if (rmconf->etypes)
179 deletypes(rmconf->etypes);
180 if (rmconf->dhgrp)
181 oakley_dhgrp_free(rmconf->dhgrp);
182 if (rmconf->proposal)
183 delisakmpsa(rmconf->proposal);
ac2f15b3
A
184 if (rmconf->idv)
185 vfree(rmconf->idv);
186 if (rmconf->idv_p)
187 vfree(rmconf->idv_p);
188 if (rmconf->remote)
189 racoon_free(rmconf->remote);
190 if (rmconf->shared_secret)
191 vfree(rmconf->shared_secret);
2b484d24
A
192 if (rmconf->keychainCertRef)
193 CFRelease(rmconf->keychainCertRef);
194 if (rmconf->open_dir_auth_group)
195 vfree(rmconf->open_dir_auth_group);
196
7ba0088d
A
197 racoon_free(rmconf);
198}
199
200void
201delisakmpsa(sa)
202 struct isakmpsa *sa;
203{
204 if (sa->dhgrp)
205 oakley_dhgrp_free(sa->dhgrp);
206 if (sa->next)
207 delisakmpsa(sa->next);
208#ifdef HAVE_GSSAPI
209 if (sa->gssid)
210 vfree(sa->gssid);
211#endif
212 racoon_free(sa);
213}
214
215void
216deletypes(e)
217 struct etypes *e;
218{
219 if (e->next)
220 deletypes(e->next);
221 racoon_free(e);
222}
223
224/*
225 * insert into head of list.
226 */
227void
228insrmconf(new)
229 struct remoteconf *new;
230{
231 LIST_INSERT_HEAD(&rmtree, new, chain);
232}
233
234void
235remrmconf(rmconf)
236 struct remoteconf *rmconf;
237{
238 LIST_REMOVE(rmconf, chain);
239}
240
241void
242flushrmconf()
243{
244 struct remoteconf *p, *next;
245
246 for (p = LIST_FIRST(&rmtree); p; p = next) {
247 next = LIST_NEXT(p, chain);
248 remrmconf(p);
249 delrmconf(p);
250 }
251}
252
253void
254initrmconf()
255{
256 LIST_INIT(&rmtree);
257}
258
259/* check exchange type to be acceptable */
260struct etypes *
261check_etypeok(rmconf, etype)
262 struct remoteconf *rmconf;
263 u_int8_t etype;
264{
265 struct etypes *e;
266
267 for (e = rmconf->etypes; e != NULL; e = e->next) {
268 if (e->type == etype)
269 break;
270 }
271
272 return e;
273}
274
275/*%%%*/
276struct isakmpsa *
277newisakmpsa()
278{
279 struct isakmpsa *new;
280
281 new = racoon_calloc(1, sizeof(*new));
282 if (new == NULL)
283 return NULL;
284
285 /*
286 * Just for sanity, make sure this is initialized. This is
287 * filled in for real when the ISAKMP proposal is configured.
288 */
289 new->vendorid = VENDORID_UNKNOWN;
290
291 new->next = NULL;
292 new->rmconf = NULL;
293#ifdef HAVE_GSSAPI
294 new->gssid = NULL;
295#endif
296
297 return new;
298}
299
300/*
301 * insert into tail of list.
302 */
303void
304insisakmpsa(new, rmconf)
305 struct isakmpsa *new;
306 struct remoteconf *rmconf;
307{
308 struct isakmpsa *p;
309
310 new->rmconf = rmconf;
311
312 if (rmconf->proposal == NULL) {
313 rmconf->proposal = new;
314 return;
315 }
316
317 for (p = rmconf->proposal; p->next != NULL; p = p->next)
318 ;
319 p->next = new;
320
321 return;
322}
323
324const char *
325rm2str(rmconf)
326 const struct remoteconf *rmconf;
327{
328 if (rmconf->remote->sa_family == AF_UNSPEC)
329 return "anonymous";
330 return saddr2str(rmconf->remote);
331}