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