]> git.saurik.com Git - apple/network_cmds.git/blame - racoon.tproj/remoteconf.c
network_cmds-115.tar.gz
[apple/network_cmds.git] / racoon.tproj / remoteconf.c
CommitLineData
7ba0088d
A
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
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);
183 racoon_free(rmconf);
184}
185
186void
187delisakmpsa(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
201void
202deletypes(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 */
213void
214insrmconf(new)
215 struct remoteconf *new;
216{
217 LIST_INSERT_HEAD(&rmtree, new, chain);
218}
219
220void
221remrmconf(rmconf)
222 struct remoteconf *rmconf;
223{
224 LIST_REMOVE(rmconf, chain);
225}
226
227void
228flushrmconf()
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
239void
240initrmconf()
241{
242 LIST_INIT(&rmtree);
243}
244
245/* check exchange type to be acceptable */
246struct etypes *
247check_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/*%%%*/
262struct isakmpsa *
263newisakmpsa()
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 */
289void
290insisakmpsa(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
310const char *
311rm2str(rmconf)
312 const struct remoteconf *rmconf;
313{
314 if (rmconf->remote->sa_family == AF_UNSPEC)
315 return "anonymous";
316 return saddr2str(rmconf->remote);
317}