]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/isakmp_cfg.c
ipsec-146.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
CommitLineData
d1e348cf
A
1/* $NetBSD: isakmp_cfg.c,v 1.12.6.1 2007/06/07 20:06:34 manu Exp $ */
2
3/* Id: isakmp_cfg.c,v 1.55 2006/08/22 18:17:17 manubsd Exp */
52b7d2ce
A
4
5/*
6 * Copyright (C) 2004-2006 Emmanuel Dreyfus
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39#include <sys/queue.h>
40
d1e348cf 41#include <utmpx.h>
d1e348cf 42#include <util.h>
e8d9021d 43
d1e348cf
A
44
45#ifdef __FreeBSD__
46# include <libutil.h>
47#endif
48#ifdef __NetBSD__
49# include <util.h>
50#endif
51
52b7d2ce
A
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <stdlib.h>
56#include <stdio.h>
57#include <string.h>
58#include <errno.h>
59#if TIME_WITH_SYS_TIME
60# include <sys/time.h>
61# include <time.h>
62#else
63# if HAVE_SYS_TIME_H
64# include <sys/time.h>
65# else
66# include <time.h>
67# endif
68#endif
69#include <netdb.h>
70#ifdef HAVE_UNISTD_H
71#include <unistd.h>
72#endif
d1e348cf
A
73#if HAVE_STDINT_H
74#include <stdint.h>
75#endif
52b7d2ce 76#include <ctype.h>
d1e348cf 77#include <resolv.h>
52b7d2ce
A
78
79#ifdef HAVE_LIBRADIUS
80#include <sys/utsname.h>
81#include <radlib.h>
82#endif
83
84#include "var.h"
85#include "misc.h"
86#include "vmbuf.h"
87#include "plog.h"
88#include "sockmisc.h"
89#include "schedule.h"
90#include "debug.h"
91
92#include "isakmp_var.h"
93#include "isakmp.h"
94#include "handler.h"
95#include "evt.h"
96#include "throttle.h"
97#include "remoteconf.h"
d1e348cf 98#include "localconf.h"
52b7d2ce
A
99#include "crypto_openssl.h"
100#include "isakmp_inf.h"
101#include "isakmp_xauth.h"
102#include "isakmp_unity.h"
103#include "isakmp_cfg.h"
104#include "strnames.h"
105#include "admin.h"
106#include "privsep.h"
d1e348cf
A
107#include "vpn_control.h"
108#include "vpn_control_var.h"
109#include "ike_session.h"
110#include "ipsecSessionTracer.h"
111#include "ipsecMessageTracer.h"
112#include "nattraversal.h"
52b7d2ce 113
d1e348cf 114struct isakmp_cfg_config isakmp_cfg_config;
52b7d2ce
A
115
116static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
117static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
118#if 0
119static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
120#endif
121static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
122 struct isakmp_data *, in_addr_t *);
123static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
d1e348cf
A
124static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
125 struct isakmp_data *, in_addr_t *, int);
126static void isakmp_cfg_appendaddr4(struct isakmp_data *,
127 struct in_addr *, int *, int);
128static void isakmp_cfg_getstring(struct isakmp_data *,char *);
129void isakmp_cfg_iplist_to_str(char *, int, void *, int);
52b7d2ce
A
130
131#define ISAKMP_CFG_LOGIN 1
132#define ISAKMP_CFG_LOGOUT 2
133static int isakmp_cfg_accounting(struct ph1handle *, int);
134#ifdef HAVE_LIBRADIUS
135static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
136#endif
137
138/*
139 * Handle an ISAKMP config mode packet
140 * We expect HDR, HASH, ATTR
141 */
142void
143isakmp_cfg_r(iph1, msg)
144 struct ph1handle *iph1;
145 vchar_t *msg;
146{
147 struct isakmp *packet;
148 struct isakmp_gen *ph;
149 int tlen;
150 char *npp;
151 int np;
152 vchar_t *dmsg;
153 struct isakmp_ivm *ivm;
d1e348cf
A
154 struct ph2handle *iph2;
155 int error = -1;
52b7d2ce
A
156
157 /* Check that the packet is long enough to have a header */
158 if (msg->l < sizeof(*packet)) {
d1e348cf
A
159 IPSECSESSIONTRACEREVENT(iph1->parent_session,
160 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
161 CONSTSTR("MODE-Config. Unexpected short packet"),
162 CONSTSTR("Failed to process short MODE-Config packet"));
163 plog(LLV_ERROR, LOCATION, NULL, "Unexpected short packet\n");
164 return;
52b7d2ce
A
165 }
166
167 packet = (struct isakmp *)msg->v;
168
169 /* Is it encrypted? It should be encrypted */
170 if ((packet->flags & ISAKMP_FLAG_E) == 0) {
d1e348cf
A
171 IPSECSESSIONTRACEREVENT(iph1->parent_session,
172 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
173 CONSTSTR("MODE-Config. User credentials sent in cleartext"),
174 CONSTSTR("Dropped cleattext User credentials"));
52b7d2ce
A
175 plog(LLV_ERROR, LOCATION, NULL,
176 "User credentials sent in cleartext!\n");
177 return;
178 }
179
180 /*
181 * Decrypt the packet. If this is the beginning of a new
182 * exchange, reinitialize the IV
183 */
d1e348cf
A
184 if (iph1->mode_cfg->ivm == NULL ||
185 iph1->mode_cfg->last_msgid != packet->msgid )
52b7d2ce
A
186 iph1->mode_cfg->ivm =
187 isakmp_cfg_newiv(iph1, packet->msgid);
188 ivm = iph1->mode_cfg->ivm;
189
190 dmsg = oakley_do_decrypt(iph1, msg, ivm->iv, ivm->ive);
191 if (dmsg == NULL) {
d1e348cf
A
192 IPSECSESSIONTRACEREVENT(iph1->parent_session,
193 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
194 CONSTSTR("MODE-Config. Failed to decrypt packet"),
195 CONSTSTR("Failed to decrypt MODE-Config packet"));
52b7d2ce
A
196 plog(LLV_ERROR, LOCATION, NULL,
197 "failed to decrypt message\n");
198 return;
199 }
200
201 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet\n");
202 plogdump(LLV_DEBUG, dmsg->v, dmsg->l);
203
204 /* Now work with the decrypted packet */
205 packet = (struct isakmp *)dmsg->v;
206 tlen = dmsg->l - sizeof(*packet);
207 ph = (struct isakmp_gen *)(packet + 1);
208
209 np = packet->np;
210 while ((tlen > 0) && (np != ISAKMP_NPTYPE_NONE)) {
211 /* Check that the payload header fits in the packet */
212 if (tlen < sizeof(*ph)) {
213 plog(LLV_WARNING, LOCATION, NULL,
214 "Short payload header\n");
215 goto out;
216 }
217
218 /* Check that the payload fits in the packet */
219 if (tlen < ntohs(ph->len)) {
220 plog(LLV_WARNING, LOCATION, NULL,
221 "Short payload\n");
222 goto out;
223 }
224
225 plog(LLV_DEBUG, LOCATION, NULL, "Seen payload %d\n", np);
226 plogdump(LLV_DEBUG, ph, ntohs(ph->len));
227
228 switch(np) {
229 case ISAKMP_NPTYPE_HASH: {
230 vchar_t *check;
231 vchar_t *payload;
232 size_t plen;
233 struct isakmp_gen *nph;
234
235 plen = ntohs(ph->len);
236 nph = (struct isakmp_gen *)((char *)ph + plen);
237 plen = ntohs(nph->len);
e8d9021d
A
238 /* Check that the hash payload fits in the packet */
239 if (tlen < (plen + ntohs(ph->len))) {
240 plog(LLV_WARNING, LOCATION, NULL,
241 "Invalid Hash payload. len %d, overall-len %d\n",
242 ntohs(nph->len),
243 plen);
244 goto out;
245 }
246
52b7d2ce
A
247 if ((payload = vmalloc(plen)) == NULL) {
248 plog(LLV_ERROR, LOCATION, NULL,
249 "Cannot allocate memory\n");
250 goto out;
251 }
252 memcpy(payload->v, nph, plen);
253
254 if ((check = oakley_compute_hash1(iph1,
255 packet->msgid, payload)) == NULL) {
256 plog(LLV_ERROR, LOCATION, NULL,
257 "Cannot compute hash\n");
258 vfree(payload);
259 goto out;
260 }
261
262 if (memcmp(ph + 1, check->v, check->l) != 0) {
263 plog(LLV_ERROR, LOCATION, NULL,
264 "Hash verification failed\n");
265 vfree(payload);
266 vfree(check);
267 goto out;
268 }
269 vfree(payload);
270 vfree(check);
271 break;
272 }
273 case ISAKMP_NPTYPE_ATTR: {
274 struct isakmp_pl_attr *attrpl;
275
276 attrpl = (struct isakmp_pl_attr *)ph;
d1e348cf 277 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
52b7d2ce
A
278
279 break;
280 }
281 default:
282 plog(LLV_WARNING, LOCATION, NULL,
283 "Unexpected next payload %d\n", np);
284 /* Skip to the next payload */
285 break;
286 }
287
288 /* Move to the next payload */
289 np = ph->np;
290 tlen -= ntohs(ph->len);
291 npp = (char *)ph;
292 ph = (struct isakmp_gen *)(npp + ntohs(ph->len));
293 }
294
d1e348cf
A
295 error = 0;
296 /* find phase 2 in case pkt scheduled for resend */
297 iph2 = getph2bymsgid(iph1, packet->msgid);
298 if (iph2 == NULL)
299 goto out; /* no resend scheduled */
300 SCHED_KILL(iph2->scr); /* turn off schedule */
301 unbindph12(iph2);
302 remph2(iph2);
303 delph2(iph2);
304
305 IPSECSESSIONTRACEREVENT(iph1->parent_session,
306 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_SUCC,
307 CONSTSTR("MODE-Config"),
308 CONSTSTR(NULL));
52b7d2ce 309out:
d1e348cf
A
310 if (error) {
311 IPSECSESSIONTRACEREVENT(iph1->parent_session,
312 IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
313 CONSTSTR("MODE-Config"),
314 CONSTSTR("Failed to process Mode-Config packet"));
315 }
52b7d2ce
A
316 vfree(dmsg);
317}
318
319int
d1e348cf 320isakmp_cfg_attr_r(iph1, msgid, attrpl, msg)
52b7d2ce
A
321 struct ph1handle *iph1;
322 u_int32_t msgid;
323 struct isakmp_pl_attr *attrpl;
d1e348cf 324 vchar_t *msg;
52b7d2ce
A
325{
326 int type = attrpl->type;
327
d1e348cf
A
328 plog(LLV_DEBUG, LOCATION, NULL,
329 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
52b7d2ce
A
330 switch (type) {
331 case ISAKMP_CFG_ACK:
332 /* ignore, but this is the time to reinit the IV */
333 oakley_delivm(iph1->mode_cfg->ivm);
334 iph1->mode_cfg->ivm = NULL;
d1e348cf 335 return 0;
52b7d2ce
A
336 break;
337
338 case ISAKMP_CFG_REPLY:
339 return isakmp_cfg_reply(iph1, attrpl);
340 break;
341
342 case ISAKMP_CFG_REQUEST:
343 iph1->msgid = msgid;
d1e348cf 344 return isakmp_cfg_request(iph1, attrpl, msg);
52b7d2ce
A
345 break;
346
347 case ISAKMP_CFG_SET:
348 iph1->msgid = msgid;
d1e348cf 349 return isakmp_cfg_set(iph1, attrpl, msg);
52b7d2ce
A
350 break;
351
352 default:
353 plog(LLV_WARNING, LOCATION, NULL,
354 "Unepected configuration exchange type %d\n", type);
355 return -1;
356 break;
357 }
358
359 return 0;
360}
361
362int
363isakmp_cfg_reply(iph1, attrpl)
364 struct ph1handle *iph1;
365 struct isakmp_pl_attr *attrpl;
366{
367 struct isakmp_data *attr;
368 int tlen;
369 size_t alen;
370 char *npp;
371 int type;
d1e348cf 372 int error;
52b7d2ce 373
d1e348cf
A
374 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
375 return 0; /* already received this - duplicate packet */
376
52b7d2ce
A
377 tlen = ntohs(attrpl->h.len);
378 attr = (struct isakmp_data *)(attrpl + 1);
379 tlen -= sizeof(*attrpl);
d1e348cf 380
52b7d2ce
A
381 while (tlen > 0) {
382 type = ntohs(attr->type);
383
384 /* Handle short attributes */
385 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
386 type &= ~ISAKMP_GEN_MASK;
387
388 plog(LLV_DEBUG, LOCATION, NULL,
d1e348cf
A
389 "Short attribute %s = %d\n",
390 s_isakmp_cfg_type(type), ntohs(attr->lorv));
52b7d2ce 391
d1e348cf 392 switch (type) {
52b7d2ce 393 case XAUTH_TYPE:
d1e348cf
A
394 if ((error = xauth_attr_reply(iph1,
395 attr, ntohs(attrpl->id))) != 0)
396 return error;
397 break;
398
52b7d2ce
A
399 break;
400
401 default:
402 plog(LLV_WARNING, LOCATION, NULL,
d1e348cf
A
403 "Ignored short attribute %s\n",
404 s_isakmp_cfg_type(type));
52b7d2ce
A
405 break;
406 }
407
408 tlen -= sizeof(*attr);
409 attr++;
410 continue;
411 }
412
413 type = ntohs(attr->type);
414 alen = ntohs(attr->lorv);
415
416 /* Check that the attribute fit in the packet */
417 if (tlen < alen) {
418 plog(LLV_ERROR, LOCATION, NULL,
d1e348cf
A
419 "Short attribute %s\n",
420 s_isakmp_cfg_type(type));
52b7d2ce
A
421 return -1;
422 }
423
424 plog(LLV_DEBUG, LOCATION, NULL,
d1e348cf
A
425 "Attribute %s, len %zu\n",
426 s_isakmp_cfg_type(type), alen);
52b7d2ce
A
427
428 switch(type) {
429 case XAUTH_TYPE:
430 case XAUTH_USER_NAME:
431 case XAUTH_USER_PASSWORD:
432 case XAUTH_PASSCODE:
433 case XAUTH_MESSAGE:
434 case XAUTH_CHALLENGE:
435 case XAUTH_DOMAIN:
436 case XAUTH_STATUS:
437 case XAUTH_NEXT_PIN:
438 case XAUTH_ANSWER:
d1e348cf
A
439 if ((error = xauth_attr_reply(iph1,
440 attr, ntohs(attrpl->id))) != 0)
441 return error;
52b7d2ce
A
442 break;
443 case INTERNAL_IP4_ADDRESS:
d1e348cf
A
444 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) == 0) {
445 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->addr4);
446 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_ADDR4;
447 }
52b7d2ce
A
448 break;
449 case INTERNAL_IP4_NETMASK:
d1e348cf
A
450 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4) == 0) {
451 isakmp_cfg_getaddr4(attr, &iph1->mode_cfg->mask4);
452 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_MASK4;
453 }
52b7d2ce
A
454 break;
455 case INTERNAL_IP4_DNS:
d1e348cf
A
456 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) == 0) {
457 isakmp_cfg_appendaddr4(attr,
458 &iph1->mode_cfg->dns4[iph1->mode_cfg->dns4_index],
459 &iph1->mode_cfg->dns4_index, MAXNS);
460 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DNS4;
461 }
52b7d2ce
A
462 break;
463 case INTERNAL_IP4_NBNS:
d1e348cf
A
464 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) == 0) {
465 isakmp_cfg_appendaddr4(attr,
466 &iph1->mode_cfg->wins4[iph1->mode_cfg->wins4_index],
467 &iph1->mode_cfg->wins4_index, MAXNS);
468 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_WINS4;
469 }
52b7d2ce 470 break;
52b7d2ce 471 case UNITY_DEF_DOMAIN:
d1e348cf
A
472 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN) == 0) {
473 isakmp_cfg_getstring(attr,
474 iph1->mode_cfg->default_domain);
475 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_DEFAULT_DOMAIN;
476 }
477 break;
52b7d2ce 478 case UNITY_SPLIT_INCLUDE:
d1e348cf
A
479 case UNITY_LOCAL_LAN:
480 case UNITY_SPLITDNS_NAME:
481 case UNITY_BANNER:
482 case UNITY_SAVE_PASSWD:
52b7d2ce 483 case UNITY_NATT_PORT:
52b7d2ce
A
484 case UNITY_FW_TYPE:
485 case UNITY_BACKUP_SERVERS:
486 case UNITY_DDNS_HOSTNAME:
d1e348cf
A
487 case APPLICATION_VERSION:
488 case UNITY_PFS:
489 isakmp_unity_reply(iph1, attr);
490 break;
491 case INTERNAL_IP4_SUBNET:
492 case INTERNAL_ADDRESS_EXPIRY:
493 if (iph1->started_by_api)
494 break; /* not actually ignored - don't fall thru */
495 // else fall thru
52b7d2ce
A
496 default:
497 plog(LLV_WARNING, LOCATION, NULL,
d1e348cf
A
498 "Ignored attribute %s\n",
499 s_isakmp_cfg_type(type));
52b7d2ce
A
500 break;
501 }
502
503 npp = (char *)attr;
504 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
505 tlen -= (sizeof(*attr) + alen);
506 }
d1e348cf
A
507 iph1->mode_cfg->flags |= ISAKMP_CFG_GOT_REPLY;
508
509 if (iph1->started_by_api || (iph1->is_rekey && iph1->parent_session && iph1->parent_session->is_client)) {
510 /* connection was started by API - save attr list for passing to VPN controller */
511 if (iph1->mode_cfg->attr_list != NULL) /* shouldn't happen */
512 vfree(iph1->mode_cfg->attr_list);
e8d9021d
A
513 if (ntohs(attrpl->h.len) < sizeof(*attrpl)) {
514 plog(LLV_ERROR, LOCATION, NULL,
515 "invalid cfg-attr-list, attr-len %d\n",
516 ntohs(attrpl->h.len));
517 return -1;
518 }
d1e348cf
A
519 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
520 if ((iph1->mode_cfg->attr_list = vmalloc(alen)) == NULL) {
521 plog(LLV_ERROR, LOCATION, NULL,
522 "Cannot allocate memory for mode-cfg attribute list\n");
523 return -1;
524 }
525 memcpy(iph1->mode_cfg->attr_list->v, attrpl + 1, alen);
526 }
527
52b7d2ce
A
528 /*
529 * Call the SA up script hook now that we have the configuration
530 * It is done at the end of phase 1 if ISAKMP mode config is not
531 * requested.
532 */
d1e348cf 533
52b7d2ce 534 if ((iph1->status == PHASE1ST_ESTABLISHED) &&
d1e348cf
A
535 iph1->rmconf->mode_cfg) {
536 switch (AUTHMETHOD(iph1)) {
537 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
538 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
539 /* Unimplemented */
540 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
541 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
542 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
543 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
544 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
545 script_hook(iph1, SCRIPT_PHASE1_UP);
546 break;
547 default:
548 break;
549 }
550 }
551
552#ifdef ENABLE_VPNCONTROL_PORT
553 if (iph1->status == PHASE1ST_ESTABLISHED)
554 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
555#endif
52b7d2ce
A
556
557#ifdef ENABLE_ADMINPORT
558 {
559 vchar_t *buf;
560
e8d9021d
A
561 if (ntohs(attrpl->h.len) < sizeof(*attrpl)) {
562 plog(LLV_ERROR, LOCATION, NULL,
563 "invalid cfg-attr-list, attr-len %d\n",
564 ntohs(attrpl->h.len));
565 return -1;
566 }
52b7d2ce
A
567 alen = ntohs(attrpl->h.len) - sizeof(*attrpl);
568 if ((buf = vmalloc(alen)) == NULL) {
569 plog(LLV_WARNING, LOCATION, NULL,
570 "Cannot allocate memory: %s\n", strerror(errno));
571 } else {
572 memcpy(buf->v, attrpl + 1, buf->l);
573 EVT_PUSH(iph1->local, iph1->remote,
574 EVTT_ISAKMP_CFG_DONE, buf);
575 vfree(buf);
576 }
577 }
578#endif
579
580 return 0;
581}
582
583int
d1e348cf 584isakmp_cfg_request(iph1, attrpl, msg)
52b7d2ce
A
585 struct ph1handle *iph1;
586 struct isakmp_pl_attr *attrpl;
d1e348cf 587 vchar_t *msg;
52b7d2ce
A
588{
589 struct isakmp_data *attr;
590 int tlen;
591 size_t alen;
592 char *npp;
d1e348cf 593 vchar_t *payload = NULL;
52b7d2ce
A
594 struct isakmp_pl_attr *reply;
595 vchar_t *reply_attr;
596 int type;
597 int error = -1;
598
d1e348cf
A
599 tlen = ntohs(attrpl->h.len);
600 attr = (struct isakmp_data *)(attrpl + 1);
601 tlen -= sizeof(*attrpl);
602
603 /*
604 * if started_by_api then we are a VPN client and if we receive
605 * a mode-cfg request it needs to go to the VPN controller to
606 * retrieve the appropriate data (name, pw, pin, etc.)
607 */
608 if (iph1->started_by_api || ike_session_is_client_ph1_rekey(iph1)) {
609 /*
610 * if we already received this one - ignore it
611 * we are waiting for a reply from the vpn control socket
612 */
613 if (iph1->xauth_awaiting_userinput)
614 return 0;
615
616 /* otherwise - save the msg id and call and send the status notification */
617 iph1->pended_xauth_id = attrpl->id; /* network byte order */
618 if (vpncontrol_notify_need_authinfo(iph1, attrpl + 1, tlen))
619 goto end;
620 iph1->xauth_awaiting_userinput = 1;
621 iph1->xauth_awaiting_userinput_msg = vdup(msg); // dup the message for later
622 ike_session_start_xauth_timer(iph1);
e8d9021d
A
623
624 IPSECLOGASLMSG("IPSec Extended Authentication requested.\n");
625
d1e348cf
A
626 return 0;
627 }
628
52b7d2ce
A
629 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
630 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
631 return -1;
632 }
633 memset(payload->v, 0, sizeof(*reply));
52b7d2ce
A
634
635 while (tlen > 0) {
636 reply_attr = NULL;
637 type = ntohs(attr->type);
638
639 /* Handle short attributes */
640 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
641 type &= ~ISAKMP_GEN_MASK;
642
643 plog(LLV_DEBUG, LOCATION, NULL,
d1e348cf
A
644 "Short attribute %s = %d\n",
645 s_isakmp_cfg_type(type), ntohs(attr->lorv));
52b7d2ce
A
646
647 switch (type) {
648 case XAUTH_TYPE:
649 reply_attr = isakmp_xauth_req(iph1, attr);
650 break;
651 default:
652 plog(LLV_WARNING, LOCATION, NULL,
d1e348cf
A
653 "Ignored short attribute %s\n",
654 s_isakmp_cfg_type(type));
52b7d2ce
A
655 break;
656 }
657
658 tlen -= sizeof(*attr);
659 attr++;
660
661 if (reply_attr != NULL) {
662 payload = buffer_cat(payload, reply_attr);
663 vfree(reply_attr);
664 }
665
666 continue;
667 }
d1e348cf 668
52b7d2ce
A
669 type = ntohs(attr->type);
670 alen = ntohs(attr->lorv);
671
672 /* Check that the attribute fit in the packet */
673 if (tlen < alen) {
674 plog(LLV_ERROR, LOCATION, NULL,
d1e348cf
A
675 "Short attribute %s\n",
676 s_isakmp_cfg_type(type));
52b7d2ce
A
677 goto end;
678 }
679
680 plog(LLV_DEBUG, LOCATION, NULL,
d1e348cf
A
681 "Attribute %s, len %zu\n",
682 s_isakmp_cfg_type(type), alen);
52b7d2ce
A
683
684 switch(type) {
685 case INTERNAL_IP4_ADDRESS:
686 case INTERNAL_IP4_NETMASK:
687 case INTERNAL_IP4_DNS:
688 case INTERNAL_IP4_NBNS:
689 case INTERNAL_IP4_SUBNET:
690 reply_attr = isakmp_cfg_net(iph1, attr);
691 break;
692
693 case XAUTH_TYPE:
694 case XAUTH_USER_NAME:
695 case XAUTH_USER_PASSWORD:
696 case XAUTH_PASSCODE:
697 case XAUTH_MESSAGE:
698 case XAUTH_CHALLENGE:
699 case XAUTH_DOMAIN:
700 case XAUTH_STATUS:
701 case XAUTH_NEXT_PIN:
702 case XAUTH_ANSWER:
703 reply_attr = isakmp_xauth_req(iph1, attr);
704 break;
705
706 case APPLICATION_VERSION:
707 reply_attr = isakmp_cfg_string(iph1,
708 attr, ISAKMP_CFG_RACOON_VERSION);
709 break;
710
711 case UNITY_BANNER:
712 case UNITY_PFS:
713 case UNITY_SAVE_PASSWD:
714 case UNITY_DEF_DOMAIN:
715 case UNITY_DDNS_HOSTNAME:
716 case UNITY_FW_TYPE:
717 case UNITY_SPLITDNS_NAME:
718 case UNITY_SPLIT_INCLUDE:
d1e348cf 719 case UNITY_LOCAL_LAN:
52b7d2ce
A
720 case UNITY_NATT_PORT:
721 case UNITY_BACKUP_SERVERS:
722 reply_attr = isakmp_unity_req(iph1, attr);
723 break;
724
725 case INTERNAL_ADDRESS_EXPIRY:
726 default:
727 plog(LLV_WARNING, LOCATION, NULL,
d1e348cf
A
728 "Ignored attribute %s\n",
729 s_isakmp_cfg_type(type));
52b7d2ce
A
730 break;
731 }
732
733 npp = (char *)attr;
734 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
735 tlen -= (sizeof(*attr) + alen);
736
737 if (reply_attr != NULL) {
738 payload = buffer_cat(payload, reply_attr);
739 vfree(reply_attr);
740 }
52b7d2ce
A
741 }
742
743 reply = (struct isakmp_pl_attr *)payload->v;
744 reply->h.len = htons(payload->l);
745 reply->type = ISAKMP_CFG_REPLY;
746 reply->id = attrpl->id;
747
d1e348cf
A
748 plog(LLV_DEBUG, LOCATION, NULL,
749 "Sending MODE_CFG REPLY\n");
750
52b7d2ce 751 error = isakmp_cfg_send(iph1, payload,
d1e348cf
A
752 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
753
754 if (iph1->status == PHASE1ST_ESTABLISHED) {
755 switch (AUTHMETHOD(iph1)) {
756 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
757 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
758 /* Unimplemented */
759 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
760 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
761 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
762 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
763 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
764 script_hook(iph1, SCRIPT_PHASE1_UP);
765 break;
766 default:
767 break;
768 }
769#ifdef ENABLE_VPNCONTROL_PORT
770 vpncontrol_notify_phase_change(0, FROM_LOCAL, iph1, NULL);
771#endif
52b7d2ce 772
d1e348cf
A
773 }
774
52b7d2ce
A
775end:
776 vfree(payload);
777
778 return error;
779}
780
781int
d1e348cf 782isakmp_cfg_set(iph1, attrpl, msg)
52b7d2ce
A
783 struct ph1handle *iph1;
784 struct isakmp_pl_attr *attrpl;
d1e348cf 785 vchar_t *msg;
52b7d2ce
A
786{
787 struct isakmp_data *attr;
788 int tlen;
789 size_t alen;
790 char *npp;
791 vchar_t *payload;
792 struct isakmp_pl_attr *reply;
793 vchar_t *reply_attr;
794 int type;
795 int error = -1;
796
797 if ((payload = vmalloc(sizeof(*reply))) == NULL) {
798 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
799 return -1;
800 }
801 memset(payload->v, 0, sizeof(*reply));
802
803 tlen = ntohs(attrpl->h.len);
804 attr = (struct isakmp_data *)(attrpl + 1);
805 tlen -= sizeof(*attrpl);
806
807 /*
808 * We should send ack for the attributes we accepted
809 */
810 while (tlen > 0) {
811 reply_attr = NULL;
812 type = ntohs(attr->type);
813
d1e348cf
A
814 plog(LLV_DEBUG, LOCATION, NULL,
815 "Attribute %s\n",
816 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
817
52b7d2ce
A
818 switch (type & ~ISAKMP_GEN_MASK) {
819 case XAUTH_STATUS:
820 reply_attr = isakmp_xauth_set(iph1, attr);
821 break;
822 default:
823 plog(LLV_DEBUG, LOCATION, NULL,
d1e348cf
A
824 "Unexpected SET attribute %s\n",
825 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
52b7d2ce
A
826 break;
827 }
828
d1e348cf 829 if (reply_attr != NULL) {
52b7d2ce
A
830 payload = buffer_cat(payload, reply_attr);
831 vfree(reply_attr);
832 }
833
834 /*
835 * Move to next attribute. If we run out of the packet,
836 * tlen becomes negative and we exit.
837 */
838 if ((type & ISAKMP_GEN_MASK) == ISAKMP_GEN_TV) {
839 tlen -= sizeof(*attr);
840 attr++;
841 } else {
842 alen = ntohs(attr->lorv);
843 tlen -= (sizeof(*attr) + alen);
844 npp = (char *)attr;
845 attr = (struct isakmp_data *)
846 (npp + sizeof(*attr) + alen);
847 }
848 }
849
850 reply = (struct isakmp_pl_attr *)payload->v;
851 reply->h.len = htons(payload->l);
852 reply->type = ISAKMP_CFG_ACK;
853 reply->id = attrpl->id;
854
d1e348cf
A
855 plog(LLV_DEBUG, LOCATION, NULL,
856 "Sending MODE_CFG ACK\n");
857
52b7d2ce 858 error = isakmp_cfg_send(iph1, payload,
d1e348cf 859 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
52b7d2ce
A
860
861 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
862 if (iph1->status == PHASE1ST_ESTABLISHED)
863 isakmp_info_send_d1(iph1);
47612122 864 isakmp_ph1expire(iph1);
d1e348cf 865 iph1 = NULL;
52b7d2ce 866 }
52b7d2ce
A
867 vfree(payload);
868
869 /*
d1e348cf 870 * If required, request ISAKMP mode config information: ignore rekeys
52b7d2ce 871 */
d1e348cf 872 if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
52b7d2ce
A
873 error = isakmp_cfg_getconfig(iph1);
874
875 return error;
876}
877
878
879static vchar_t *
880buffer_cat(s, append)
881 vchar_t *s;
882 vchar_t *append;
883{
884 vchar_t *new;
885
886 new = vmalloc(s->l + append->l);
887 if (new == NULL) {
888 plog(LLV_ERROR, LOCATION, NULL,
889 "Cannot allocate memory\n");
890 return s;
891 }
892
893 memcpy(new->v, s->v, s->l);
894 memcpy(new->v + s->l, append->v, append->l);
895
896 vfree(s);
897 return new;
898}
899
900static vchar_t *
901isakmp_cfg_net(iph1, attr)
902 struct ph1handle *iph1;
903 struct isakmp_data *attr;
904{
905 int type;
d1e348cf 906 int confsource;
52b7d2ce
A
907 in_addr_t addr4;
908
909 type = ntohs(attr->type);
910
911 /*
912 * Don't give an address to a peer that did not succeed Xauth
913 */
914 if (xauth_check(iph1) != 0) {
915 plog(LLV_ERROR, LOCATION, NULL,
916 "Attempt to start phase config whereas Xauth failed\n");
917 return NULL;
918 }
919
d1e348cf
A
920 confsource = isakmp_cfg_config.confsource;
921 /*
922 * If we have to fall back to a local
923 * configuration source, we will jump
924 * back to this point.
925 */
926retry_source:
927
52b7d2ce
A
928 switch(type) {
929 case INTERNAL_IP4_ADDRESS:
d1e348cf
A
930 switch(confsource) {
931#ifdef HAVE_LIBLDAP
932 case ISAKMP_CFG_CONF_LDAP:
933 if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
934 break;
935 plog(LLV_INFO, LOCATION, NULL,
936 "No IP from LDAP, using local pool\n");
937 /* FALLTHROUGH */
938 confsource = ISAKMP_CFG_CONF_LOCAL;
939 goto retry_source;
940#endif
52b7d2ce
A
941#ifdef HAVE_LIBRADIUS
942 case ISAKMP_CFG_CONF_RADIUS:
d1e348cf 943 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
52b7d2ce
A
944 && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
945 /*
946 * -2 is 255.255.255.254, RADIUS uses that
947 * to instruct the NAS to use a local pool
948 */
949 break;
950 plog(LLV_INFO, LOCATION, NULL,
951 "No IP from RADIUS, using local pool\n");
952 /* FALLTHROUGH */
d1e348cf
A
953 confsource = ISAKMP_CFG_CONF_LOCAL;
954 goto retry_source;
52b7d2ce
A
955#endif
956 case ISAKMP_CFG_CONF_LOCAL:
957 if (isakmp_cfg_getport(iph1) == -1) {
958 plog(LLV_ERROR, LOCATION, NULL,
959 "Port pool depleted\n");
960 break;
961 }
962
963 iph1->mode_cfg->addr4.s_addr =
964 htonl(ntohl(isakmp_cfg_config.network4)
965 + iph1->mode_cfg->port);
966 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
967 break;
968
969 default:
970 plog(LLV_ERROR, LOCATION, NULL,
971 "Unexpected confsource\n");
972 }
973
974 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
975 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
976
977 return isakmp_cfg_addr4(iph1,
978 attr, &iph1->mode_cfg->addr4.s_addr);
979 break;
980
981 case INTERNAL_IP4_NETMASK:
d1e348cf
A
982 switch(confsource) {
983#ifdef HAVE_LIBLDAP
984 case ISAKMP_CFG_CONF_LDAP:
985 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
986 break;
987 plog(LLV_INFO, LOCATION, NULL,
988 "No mask from LDAP, using local pool\n");
989 /* FALLTHROUGH */
990 confsource = ISAKMP_CFG_CONF_LOCAL;
991 goto retry_source;
992#endif
52b7d2ce
A
993#ifdef HAVE_LIBRADIUS
994 case ISAKMP_CFG_CONF_RADIUS:
d1e348cf 995 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
52b7d2ce
A
996 break;
997 plog(LLV_INFO, LOCATION, NULL,
998 "No mask from RADIUS, using local pool\n");
999 /* FALLTHROUGH */
d1e348cf
A
1000 confsource = ISAKMP_CFG_CONF_LOCAL;
1001 goto retry_source;
52b7d2ce
A
1002#endif
1003 case ISAKMP_CFG_CONF_LOCAL:
1004 iph1->mode_cfg->mask4.s_addr
1005 = isakmp_cfg_config.netmask4;
1006 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
1007 break;
1008
1009 default:
1010 plog(LLV_ERROR, LOCATION, NULL,
1011 "Unexpected confsource\n");
1012 }
1013 return isakmp_cfg_addr4(iph1, attr,
1014 &iph1->mode_cfg->mask4.s_addr);
1015 break;
1016
1017 case INTERNAL_IP4_DNS:
d1e348cf
A
1018 return isakmp_cfg_addr4_list(iph1,
1019 attr, &isakmp_cfg_config.dns4[0],
1020 isakmp_cfg_config.dns4_index);
52b7d2ce
A
1021 break;
1022
1023 case INTERNAL_IP4_NBNS:
d1e348cf
A
1024 return isakmp_cfg_addr4_list(iph1,
1025 attr, &isakmp_cfg_config.nbns4[0],
1026 isakmp_cfg_config.nbns4_index);
52b7d2ce
A
1027 break;
1028
1029 case INTERNAL_IP4_SUBNET:
1030 return isakmp_cfg_addr4(iph1,
1031 attr, &isakmp_cfg_config.network4);
1032 break;
1033
1034 default:
1035 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
1036 break;
1037 }
52b7d2ce
A
1038 return NULL;
1039}
1040
1041#if 0
1042static vchar_t *
1043isakmp_cfg_void(iph1, attr)
1044 struct ph1handle *iph1;
1045 struct isakmp_data *attr;
1046{
1047 vchar_t *buffer;
1048 struct isakmp_data *new;
1049
1050 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1051 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1052 return NULL;
1053 }
1054
1055 new = (struct isakmp_data *)buffer->v;
1056
1057 new->type = attr->type;
1058 new->lorv = htons(0);
1059
1060 return buffer;
1061}
1062#endif
1063
1064vchar_t *
1065isakmp_cfg_copy(iph1, attr)
1066 struct ph1handle *iph1;
1067 struct isakmp_data *attr;
1068{
1069 vchar_t *buffer;
1070 size_t len = 0;
1071
1072 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
1073 len = ntohs(attr->lorv);
1074
1075 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1076 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1077 return NULL;
1078 }
1079
1080 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
1081
1082 return buffer;
1083}
1084
1085vchar_t *
1086isakmp_cfg_short(iph1, attr, value)
1087 struct ph1handle *iph1;
1088 struct isakmp_data *attr;
1089 int value;
1090{
1091 vchar_t *buffer;
1092 struct isakmp_data *new;
1093 int type;
1094
1095 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1096 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1097 return NULL;
1098 }
1099
1100 new = (struct isakmp_data *)buffer->v;
1101 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1102
1103 new->type = htons(type | ISAKMP_GEN_TV);
1104 new->lorv = htons(value);
1105
1106 return buffer;
1107}
1108
1109vchar_t *
d1e348cf 1110isakmp_cfg_varlen(iph1, attr, string, len)
52b7d2ce
A
1111 struct ph1handle *iph1;
1112 struct isakmp_data *attr;
1113 char *string;
d1e348cf 1114 size_t len;
52b7d2ce
A
1115{
1116 vchar_t *buffer;
1117 struct isakmp_data *new;
52b7d2ce
A
1118 char *data;
1119
52b7d2ce
A
1120 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1121 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1122 return NULL;
1123 }
1124
1125 new = (struct isakmp_data *)buffer->v;
1126
1127 new->type = attr->type;
1128 new->lorv = htons(len);
1129 data = (char *)(new + 1);
1130
1131 memcpy(data, string, len);
1132
1133 return buffer;
1134}
d1e348cf
A
1135vchar_t *
1136isakmp_cfg_string(iph1, attr, string)
1137 struct ph1handle *iph1;
1138 struct isakmp_data *attr;
1139 char *string;
1140{
1141 size_t len = strlen(string);
1142 return isakmp_cfg_varlen(iph1, attr, string, len);
1143}
52b7d2ce
A
1144
1145static vchar_t *
1146isakmp_cfg_addr4(iph1, attr, addr)
1147 struct ph1handle *iph1;
1148 struct isakmp_data *attr;
1149 in_addr_t *addr;
1150{
1151 vchar_t *buffer;
1152 struct isakmp_data *new;
1153 size_t len;
1154
1155 len = sizeof(*addr);
1156 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1157 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1158 return NULL;
1159 }
1160
1161 new = (struct isakmp_data *)buffer->v;
1162
1163 new->type = attr->type;
1164 new->lorv = htons(len);
1165 memcpy(new + 1, addr, len);
1166
1167 return buffer;
1168}
1169
d1e348cf
A
1170static vchar_t *
1171isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1172 struct ph1handle *iph1;
1173 struct isakmp_data *attr;
1174 in_addr_t *addr;
1175 int nbr;
1176{
1177 int error = -1;
1178 vchar_t *buffer = NULL;
1179 vchar_t *bufone = NULL;
1180 struct isakmp_data *new;
1181 size_t len;
1182 int i;
1183
1184 len = sizeof(*addr);
1185 if ((buffer = vmalloc(0)) == NULL) {
1186 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1187 goto out;
1188 }
1189 for(i = 0; i < nbr; i++) {
1190 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1191 plog(LLV_ERROR, LOCATION, NULL,
1192 "Cannot allocate memory\n");
1193 goto out;
1194 }
1195 new = (struct isakmp_data *)bufone->v;
1196 new->type = attr->type;
1197 new->lorv = htons(len);
1198 memcpy(new + 1, &addr[i], len);
1199 new += (len + sizeof(*attr));
1200 buffer = buffer_cat(buffer, bufone);
1201 vfree(bufone);
1202 }
1203
1204 error = 0;
1205
1206out:
1207 if ((error != 0) && (buffer != NULL)) {
1208 vfree(buffer);
1209 buffer = NULL;
1210 }
1211
1212 return buffer;
1213}
1214
52b7d2ce
A
1215struct isakmp_ivm *
1216isakmp_cfg_newiv(iph1, msgid)
1217 struct ph1handle *iph1;
1218 u_int32_t msgid;
1219{
1220 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1221
1222 if (ics == NULL) {
1223 plog(LLV_ERROR, LOCATION, NULL,
1224 "isakmp_cfg_newiv called without mode config state\n");
1225 return NULL;
1226 }
1227
1228 if (ics->ivm != NULL)
1229 oakley_delivm(ics->ivm);
1230
1231 ics->ivm = oakley_newiv2(iph1, msgid);
d1e348cf 1232 ics->last_msgid = msgid;
52b7d2ce
A
1233
1234 return ics->ivm;
1235}
1236
1237/* Derived from isakmp_info_send_common */
1238int
d1e348cf 1239isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
52b7d2ce
A
1240 struct ph1handle *iph1;
1241 vchar_t *payload;
1242 u_int32_t np;
1243 int flags;
1244 int new_exchange;
d1e348cf
A
1245 int retry_count;
1246 vchar_t *msg;
52b7d2ce
A
1247{
1248 struct ph2handle *iph2 = NULL;
1249 vchar_t *hash = NULL;
1250 struct isakmp *isakmp;
1251 struct isakmp_gen *gen;
1252 char *p;
1253 int tlen;
1254 int error = -1;
1255 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1256
1257 /* Check if phase 1 is established */
1258 if ((iph1->status != PHASE1ST_ESTABLISHED) ||
1259 (iph1->local == NULL) ||
1260 (iph1->remote == NULL)) {
1261 plog(LLV_ERROR, LOCATION, NULL,
1262 "ISAKMP mode config exchange with immature phase 1\n");
1263 goto end;
1264 }
1265
1266 /* add new entry to isakmp status table */
1267 iph2 = newph2();
d1e348cf
A
1268 if (iph2 == NULL) {
1269 plog(LLV_ERROR, LOCATION, NULL,
1270 "failed to allocate ph2");
52b7d2ce 1271 goto end;
d1e348cf 1272 }
52b7d2ce
A
1273
1274 iph2->dst = dupsaddr(iph1->remote);
d1e348cf
A
1275 if (iph2->dst == NULL) {
1276 plog(LLV_ERROR, LOCATION, NULL,
1277 "failed to duplicate remote address");
1278 delph2(iph2);
1279 goto end;
1280 }
52b7d2ce 1281 iph2->src = dupsaddr(iph1->local);
d1e348cf
A
1282 if (iph2->src == NULL) {
1283 plog(LLV_ERROR, LOCATION, NULL,
1284 "failed to duplicate local address");
1285 delph2(iph2);
1286 goto end;
1287 }
1288
52b7d2ce
A
1289 switch (iph1->remote->sa_family) {
1290 case AF_INET:
d1e348cf 1291#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1292 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1293 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1294#endif
1295 break;
1296#ifdef INET6
1297 case AF_INET6:
d1e348cf 1298#if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
52b7d2ce
A
1299 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1300 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
d1e348cf 1301#endif
52b7d2ce
A
1302 break;
1303#endif
1304 default:
1305 plog(LLV_ERROR, LOCATION, NULL,
1306 "invalid family: %d\n", iph1->remote->sa_family);
1307 delph2(iph2);
1308 goto end;
1309 }
1310 iph2->ph1 = iph1;
1311 iph2->side = INITIATOR;
1312 iph2->status = PHASE2ST_START;
1313
1314 if (new_exchange)
1315 iph2->msgid = isakmp_newmsgid2(iph1);
1316 else
1317 iph2->msgid = iph1->msgid;
1318
1319 /* get IV and HASH(1) if skeyid_a was generated. */
1320 if (iph1->skeyid_a != NULL) {
1321 if (new_exchange) {
1322 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
d1e348cf
A
1323 plog(LLV_ERROR, LOCATION, NULL,
1324 "failed to generate IV");
52b7d2ce
A
1325 delph2(iph2);
1326 goto end;
1327 }
1328 }
1329
1330 /* generate HASH(1) */
1331 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1332 if (hash == NULL) {
d1e348cf
A
1333 plog(LLV_ERROR, LOCATION, NULL,
1334 "failed to generate HASH");
52b7d2ce
A
1335 delph2(iph2);
1336 goto end;
1337 }
1338
1339 /* initialized total buffer length */
1340 tlen = hash->l;
1341 tlen += sizeof(*gen);
1342 } else {
1343 /* IKE-SA is not established */
1344 hash = NULL;
1345
1346 /* initialized total buffer length */
1347 tlen = 0;
1348 }
1349 if ((flags & ISAKMP_FLAG_A) == 0)
1350 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1351 else
1352 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1353
1354 insph2(iph2);
1355 bindph12(iph1, iph2);
1356
1357 tlen += sizeof(*isakmp) + payload->l;
1358
1359 /* create buffer for isakmp payload */
1360 iph2->sendbuf = vmalloc(tlen);
1361 if (iph2->sendbuf == NULL) {
1362 plog(LLV_ERROR, LOCATION, NULL,
1363 "failed to get buffer to send.\n");
1364 goto err;
1365 }
1366
1367 /* create isakmp header */
1368 isakmp = (struct isakmp *)iph2->sendbuf->v;
1369 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1370 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1371 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1372 isakmp->v = iph1->version;
1373 isakmp->etype = ISAKMP_ETYPE_CFG;
1374 isakmp->flags = iph2->flags;
1375 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1376 isakmp->len = htonl(tlen);
1377 p = (char *)(isakmp + 1);
1378
1379 /* create HASH payload */
1380 if (hash != NULL) {
1381 gen = (struct isakmp_gen *)p;
1382 gen->np = np & 0xff;
1383 gen->len = htons(sizeof(*gen) + hash->l);
1384 p += sizeof(*gen);
1385 memcpy(p, hash->v, hash->l);
1386 p += hash->l;
1387 }
1388
1389 /* add payload */
1390 memcpy(p, payload->v, payload->l);
1391 p += payload->l;
1392
1393#ifdef HAVE_PRINT_ISAKMP_C
1394 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1395#endif
d1e348cf
A
1396
1397 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1398 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
52b7d2ce
A
1399
1400 /* encoding */
1401 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1402 vchar_t *tmp;
1403
1404 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1405 ics->ivm->ive, ics->ivm->iv);
1406 VPTRINIT(iph2->sendbuf);
d1e348cf
A
1407 if (tmp == NULL) {
1408 plog(LLV_ERROR, LOCATION, NULL,
1409 "failed to encrypt packet");
52b7d2ce 1410 goto err;
d1e348cf 1411 }
52b7d2ce
A
1412 iph2->sendbuf = tmp;
1413 }
1414
1415 /* HDR*, HASH(1), ATTR */
d1e348cf
A
1416
1417 if (retry_count > 0) {
1418 iph2->retry_counter = retry_count;
1419 if (isakmp_ph2resend(iph2) < 0) {
1420 plog(LLV_ERROR, LOCATION, NULL,
1421 "failed to resend packet");
1422 VPTRINIT(iph2->sendbuf);
1423 goto err;
1424 }
1425 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1426 IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
1427 CONSTSTR("Mode-Config retransmit"),
1428 CONSTSTR(NULL));
1429 error = 0;
1430 goto end;
1431 }
1432
52b7d2ce 1433 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
d1e348cf
A
1434 plog(LLV_ERROR, LOCATION, NULL,
1435 "failed to send packet");
52b7d2ce
A
1436 VPTRINIT(iph2->sendbuf);
1437 goto err;
1438 }
d1e348cf
A
1439 if (msg) {
1440 /* the sending message is added to the received-list. */
1441 if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
e8d9021d 1442 PH2_NON_ESP_EXTRA_LEN(iph2), PH1_FRAG_FLAGS(iph1)) == -1) {
d1e348cf
A
1443 plog(LLV_ERROR , LOCATION, NULL,
1444 "failed to add a response packet to the tree.\n");
1445 }
1446 }
1447
52b7d2ce
A
1448 plog(LLV_DEBUG, LOCATION, NULL,
1449 "sendto mode config %s.\n", s_isakmp_nptype(np));
1450
1451 /*
1452 * XXX We might need to resend the message...
1453 */
1454
1455 error = 0;
1456 VPTRINIT(iph2->sendbuf);
1457
d1e348cf
A
1458 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1459 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1460 CONSTSTR("Mode-Config message"),
1461 CONSTSTR(NULL));
1462
52b7d2ce 1463err:
d1e348cf
A
1464 if (error) {
1465 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1466 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1467 CONSTSTR("Mode-Config message"),
1468 CONSTSTR("Failed to transmit Mode-Config message"));
1469 }
52b7d2ce
A
1470 unbindph12(iph2);
1471 remph2(iph2);
1472 delph2(iph2);
1473end:
1474 if (hash)
1475 vfree(hash);
1476 return error;
1477}
1478
1479
1480void
1481isakmp_cfg_rmstate(iph1)
1482 struct ph1handle *iph1;
1483{
1484 struct isakmp_cfg_state *state = iph1->mode_cfg;
1485
1486 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1487 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1488
1489 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1490 isakmp_cfg_putport(iph1, state->port);
1491
d1e348cf
A
1492 /* Delete the IV if it's still there */
1493 if(iph1->mode_cfg->ivm) {
1494 oakley_delivm(iph1->mode_cfg->ivm);
1495 iph1->mode_cfg->ivm = NULL;
1496 }
1497
1498 /* Free any allocated splitnet lists */
1499 if(iph1->mode_cfg->split_include != NULL)
1500 splitnet_list_free(iph1->mode_cfg->split_include,
1501 &iph1->mode_cfg->include_count);
1502 if(iph1->mode_cfg->split_local != NULL)
1503 splitnet_list_free(iph1->mode_cfg->split_local,
1504 &iph1->mode_cfg->local_count);
1505
52b7d2ce 1506 xauth_rmstate(&state->xauth);
d1e348cf
A
1507
1508 if (state->attr_list)
1509 vfree(state->attr_list);
52b7d2ce
A
1510
1511 racoon_free(state);
1512 iph1->mode_cfg = NULL;
1513
1514 return;
1515}
1516
1517struct isakmp_cfg_state *
1518isakmp_cfg_mkstate(void)
1519{
1520 struct isakmp_cfg_state *state;
1521
1522 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1523 plog(LLV_ERROR, LOCATION, NULL,
1524 "Cannot allocate memory for mode config state\n");
1525 return NULL;
1526 }
1527 memset(state, 0, sizeof(*state));
1528
1529 return state;
1530}
1531
1532int
1533isakmp_cfg_getport(iph1)
1534 struct ph1handle *iph1;
1535{
1536 unsigned int i;
1537 size_t size = isakmp_cfg_config.pool_size;
1538
1539 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1540 return iph1->mode_cfg->port;
1541
1542 if (isakmp_cfg_config.port_pool == NULL) {
1543 plog(LLV_ERROR, LOCATION, NULL,
1544 "isakmp_cfg_config.port_pool == NULL\n");
1545 return -1;
1546 }
1547
1548 for (i = 0; i < size; i++) {
1549 if (isakmp_cfg_config.port_pool[i].used == 0)
1550 break;
1551 }
1552
1553 if (i == size) {
1554 plog(LLV_ERROR, LOCATION, NULL,
1555 "No more addresses available\n");
1556 return -1;
1557 }
1558
1559 isakmp_cfg_config.port_pool[i].used = 1;
1560
1561 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1562
1563 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1564 iph1->mode_cfg->port = i;
1565
1566 return i;
1567}
1568
1569int
1570isakmp_cfg_putport(iph1, index)
1571 struct ph1handle *iph1;
1572 unsigned int index;
1573{
1574 if (isakmp_cfg_config.port_pool == NULL) {
1575 plog(LLV_ERROR, LOCATION, NULL,
1576 "isakmp_cfg_config.port_pool == NULL\n");
1577 return -1;
1578 }
1579
1580 if (isakmp_cfg_config.port_pool[index].used == 0) {
1581 plog(LLV_ERROR, LOCATION, NULL,
1582 "Attempt to release an unallocated address (port %d)\n",
1583 index);
1584 return -1;
1585 }
1586
1587#ifdef HAVE_LIBPAM
1588 /* Cleanup PAM status associated with the port */
1589 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1590 privsep_cleanup_pam(index);
1591#endif
1592 isakmp_cfg_config.port_pool[index].used = 0;
1593 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1594
1595 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1596
1597 return 0;
1598}
1599
1600#ifdef HAVE_LIBPAM
1601void
1602cleanup_pam(port)
1603 int port;
1604{
1605 if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1606 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1607 isakmp_cfg_config.port_pool[port].pam = NULL;
1608 }
1609
1610 return;
1611}
1612#endif
1613
1614/* Accounting, only for RADIUS or PAM */
1615static int
1616isakmp_cfg_accounting(iph1, inout)
1617 struct ph1handle *iph1;
1618 int inout;
1619{
1620#ifdef HAVE_LIBPAM
1621 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1622 return privsep_accounting_pam(iph1->mode_cfg->port,
1623 inout);
1624#endif
1625#ifdef HAVE_LIBRADIUS
1626 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1627 return isakmp_cfg_accounting_radius(iph1, inout);
1628#endif
e8d9021d 1629#ifdef HAVE_OPENSSL
d1e348cf
A
1630 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1631 return privsep_accounting_system(iph1->mode_cfg->port,
1632 iph1->remote, iph1->mode_cfg->login, inout);
e8d9021d 1633#endif
52b7d2ce
A
1634 return 0;
1635}
1636
1637#ifdef HAVE_LIBPAM
1638int
1639isakmp_cfg_accounting_pam(port, inout)
1640 int port;
1641 int inout;
1642{
1643 int error = 0;
1644 pam_handle_t *pam;
1645
1646 if (isakmp_cfg_config.port_pool == NULL) {
1647 plog(LLV_ERROR, LOCATION, NULL,
1648 "isakmp_cfg_config.port_pool == NULL\n");
1649 return -1;
1650 }
1651
1652 pam = isakmp_cfg_config.port_pool[port].pam;
1653 if (pam == NULL) {
1654 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1655 return -1;
1656 }
1657
1658 switch (inout) {
1659 case ISAKMP_CFG_LOGIN:
1660 error = pam_open_session(pam, 0);
1661 break;
1662 case ISAKMP_CFG_LOGOUT:
1663 error = pam_close_session(pam, 0);
1664 pam_end(pam, error);
1665 isakmp_cfg_config.port_pool[port].pam = NULL;
1666 break;
1667 default:
1668 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1669 break;
1670 }
1671
1672 if (error != 0) {
1673 plog(LLV_ERROR, LOCATION, NULL,
1674 "pam_open_session/pam_close_session failed: %s\n",
1675 pam_strerror(pam, error));
1676 return -1;
1677 }
1678
1679 return 0;
1680}
1681#endif /* HAVE_LIBPAM */
1682
1683#ifdef HAVE_LIBRADIUS
1684static int
1685isakmp_cfg_accounting_radius(iph1, inout)
1686 struct ph1handle *iph1;
1687 int inout;
1688{
1689 /* For first time use, initialize Radius */
1690 if (radius_acct_state == NULL) {
1691 if ((radius_acct_state = rad_acct_open()) == NULL) {
1692 plog(LLV_ERROR, LOCATION, NULL,
1693 "Cannot init librradius\n");
1694 return -1;
1695 }
1696
1697 if (rad_config(radius_acct_state, NULL) != 0) {
1698 plog(LLV_ERROR, LOCATION, NULL,
1699 "Cannot open librarius config file: %s\n",
1700 rad_strerror(radius_acct_state));
1701 rad_close(radius_acct_state);
1702 radius_acct_state = NULL;
1703 return -1;
1704 }
1705 }
1706
1707 if (rad_create_request(radius_acct_state,
1708 RAD_ACCOUNTING_REQUEST) != 0) {
1709 plog(LLV_ERROR, LOCATION, NULL,
1710 "rad_create_request failed: %s\n",
1711 rad_strerror(radius_acct_state));
1712 return -1;
1713 }
1714
1715 if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1716 iph1->mode_cfg->login) != 0) {
1717 plog(LLV_ERROR, LOCATION, NULL,
1718 "rad_put_string failed: %s\n",
1719 rad_strerror(radius_acct_state));
1720 return -1;
1721 }
1722
1723 switch (inout) {
1724 case ISAKMP_CFG_LOGIN:
1725 inout = RAD_START;
1726 break;
1727 case ISAKMP_CFG_LOGOUT:
1728 inout = RAD_STOP;
1729 break;
1730 default:
1731 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1732 break;
1733 }
1734
1735 if (rad_put_addr(radius_acct_state,
1736 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1737 plog(LLV_ERROR, LOCATION, NULL,
1738 "rad_put_addr failed: %s\n",
1739 rad_strerror(radius_acct_state));
1740 return -1;
1741 }
1742
1743 if (rad_put_addr(radius_acct_state,
1744 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1745 plog(LLV_ERROR, LOCATION, NULL,
1746 "rad_put_addr failed: %s\n",
1747 rad_strerror(radius_acct_state));
1748 return -1;
1749 }
1750
1751 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1752 plog(LLV_ERROR, LOCATION, NULL,
1753 "rad_put_int failed: %s\n",
1754 rad_strerror(radius_acct_state));
1755 return -1;
1756 }
1757
1758 if (isakmp_cfg_radius_common(radius_acct_state,
1759 iph1->mode_cfg->port) != 0)
1760 return -1;
1761
1762 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1763 plog(LLV_ERROR, LOCATION, NULL,
1764 "rad_send_request failed: %s\n",
1765 rad_strerror(radius_acct_state));
1766 return -1;
1767 }
1768
1769 return 0;
1770}
1771#endif /* HAVE_LIBRADIUS */
1772
1773/*
1774 * Attributes common to all RADIUS requests
1775 */
1776#ifdef HAVE_LIBRADIUS
1777int
1778isakmp_cfg_radius_common(radius_state, port)
1779 struct rad_handle *radius_state;
1780 int port;
1781{
1782 struct utsname name;
1783 static struct hostent *host = NULL;
1784 struct in_addr nas_addr;
1785
1786 /*
1787 * Find our own IP by resolving our nodename
1788 */
1789 if (host == NULL) {
1790 if (uname(&name) != 0) {
1791 plog(LLV_ERROR, LOCATION, NULL,
1792 "uname failed: %s\n", strerror(errno));
1793 return -1;
1794 }
1795
1796 if ((host = gethostbyname(name.nodename)) == NULL) {
1797 plog(LLV_ERROR, LOCATION, NULL,
1798 "gethostbyname failed: %s\n", strerror(errno));
1799 return -1;
1800 }
1801 }
1802
1803 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1804 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1805 plog(LLV_ERROR, LOCATION, NULL,
1806 "rad_put_addr failed: %s\n",
1807 rad_strerror(radius_state));
1808 return -1;
1809 }
1810
1811 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1812 plog(LLV_ERROR, LOCATION, NULL,
1813 "rad_put_int failed: %s\n",
1814 rad_strerror(radius_state));
1815 return -1;
1816 }
1817
1818 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1819 plog(LLV_ERROR, LOCATION, NULL,
1820 "rad_put_int failed: %s\n",
1821 rad_strerror(radius_state));
1822 return -1;
1823 }
1824
1825 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1826 plog(LLV_ERROR, LOCATION, NULL,
1827 "rad_put_int failed: %s\n",
1828 rad_strerror(radius_state));
1829 return -1;
1830 }
1831
1832 return 0;
1833}
1834#endif
d1e348cf
A
1835
1836/*
1837 Logs the user into the utmp system files.
1838*/
1839
1840int
1841isakmp_cfg_accounting_system(port, raddr, usr, inout)
1842 int port;
1843 struct sockaddr *raddr;
1844 char *usr;
1845 int inout;
1846{
1847 int error = 0;
1848 struct utmpx ut;
1849 char term[_UTX_LINESIZE];
1850 char addr[NI_MAXHOST];
1851
1852 if (usr == NULL || usr[0]=='\0') {
1853 plog(LLV_ERROR, LOCATION, NULL,
1854 "system accounting : no login found\n");
1855 return -1;
1856 }
1857
1858 snprintf(term, sizeof(term), TERMSPEC, port);
1859
1860 switch (inout) {
1861 case ISAKMP_CFG_LOGIN:
1862 strlcpy(ut.ut_user, usr, sizeof(ut.ut_user));
1863
1864 strlcpy(ut.ut_line, term, sizeof(ut.ut_line));
1865
1866 GETNAMEINFO_NULL(raddr, addr);
1867 strlcpy(ut.ut_host, addr, sizeof(ut.ut_host));
1868
1869 ut.ut_pid = getpid();
1870
1871 ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS;
1872
1873 gettimeofday(&ut.ut_tv, NULL);
1874
1875 plog(LLV_INFO, LOCATION, NULL,
1876 "Accounting : '%s' logging on '%s' from %s.\n",
1877 ut.ut_user, ut.ut_line, ut.ut_host);
1878
1879 if (pututxline(&ut) == NULL)
1880 return -1;
1881
1882 break;
1883 case ISAKMP_CFG_LOGOUT:
1884
1885 plog(LLV_INFO, LOCATION, NULL,
1886 "Accounting : '%s' unlogging from '%s'.\n",
1887 usr, term);
1888
1889 ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS;
1890
1891 gettimeofday(&ut.ut_tv, NULL);
1892
1893 if (pututxline(&ut) == NULL)
1894 return -1;
1895
1896 break;
1897 default:
1898 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1899 break;
1900 }
1901
1902 return 0;
1903}
52b7d2ce
A
1904
1905int
1906isakmp_cfg_getconfig(iph1)
1907 struct ph1handle *iph1;
1908{
1909 vchar_t *buffer;
1910 struct isakmp_pl_attr *attrpl;
1911 struct isakmp_data *attr;
1912 size_t len;
d1e348cf 1913 vchar_t *version = NULL;
52b7d2ce
A
1914 int error;
1915 int attrcount;
1916 int i;
1917 int attrlist[] = {
1918 INTERNAL_IP4_ADDRESS,
1919 INTERNAL_IP4_NETMASK,
1920 INTERNAL_IP4_DNS,
1921 INTERNAL_IP4_NBNS,
d1e348cf 1922 INTERNAL_ADDRESS_EXPIRY,
52b7d2ce 1923 APPLICATION_VERSION,
d1e348cf
A
1924 UNITY_BANNER,
1925 UNITY_DEF_DOMAIN,
1926 UNITY_SPLITDNS_NAME,
1927 UNITY_SPLIT_INCLUDE,
1928 UNITY_LOCAL_LAN,
52b7d2ce
A
1929 };
1930
1931 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1932 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
d1e348cf
A
1933
1934 if (iph1->started_by_api) {
1935 if (iph1->remote->sa_family == AF_INET) {
1936 struct vpnctl_socket_elem *sock_elem;
1937 struct bound_addr *bound_addr;
1938 u_int32_t address;
1939
1940 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1941 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1942 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1943 if (bound_addr->address == address) {
1944 if (version = bound_addr->version)
1945 len += bound_addr->version->l;
1946 break;
1947 }
1948 }
1949 }
1950 }
1951 }
1952
52b7d2ce
A
1953 if ((buffer = vmalloc(len)) == NULL) {
1954 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1955 return -1;
1956 }
1957
1958 attrpl = (struct isakmp_pl_attr *)buffer->v;
1959 attrpl->h.len = htons(len);
1960 attrpl->type = ISAKMP_CFG_REQUEST;
1961 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1962
1963 attr = (struct isakmp_data *)(attrpl + 1);
1964
1965 for (i = 0; i < attrcount; i++) {
d1e348cf
A
1966 switch (attrlist[i]) {
1967 case APPLICATION_VERSION:
1968 if (version) {
1969 attr->type = htons(attrlist[i]);
1970 attr->lorv = htons(version->l);
1971 memcpy(attr + 1, version->v, version->l);
1972 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1973 break;
1974 } else /* fall thru */;
1975 default:
1976 attr->type = htons(attrlist[i]);
1977 attr->lorv = htons(0);
1978 attr++;
1979 break;
1980 }
52b7d2ce
A
1981 }
1982
d1e348cf
A
1983 plog(LLV_DEBUG, LOCATION, NULL,
1984 "Sending MODE_CFG REQUEST\n");
1985
52b7d2ce 1986 error = isakmp_cfg_send(iph1, buffer,
d1e348cf 1987 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
52b7d2ce
A
1988
1989 vfree(buffer);
1990
e8d9021d
A
1991 IPSECLOGASLMSG("IPSec Network Configuration requested.\n");
1992
52b7d2ce
A
1993 return error;
1994}
1995
1996static void
1997isakmp_cfg_getaddr4(attr, ip)
1998 struct isakmp_data *attr;
1999 struct in_addr *ip;
2000{
2001 size_t alen = ntohs(attr->lorv);
2002 in_addr_t *addr;
2003
2004 if (alen != sizeof(*ip)) {
2005 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2006 return;
2007 }
2008
2009 addr = (in_addr_t *)(attr + 1);
2010 ip->s_addr = *addr;
2011
2012 return;
2013}
2014
d1e348cf
A
2015static void
2016isakmp_cfg_appendaddr4(attr, ip, num, max)
2017 struct isakmp_data *attr;
2018 struct in_addr *ip;
2019 int *num;
2020 int max;
2021{
2022 size_t alen = ntohs(attr->lorv);
2023 in_addr_t *addr;
2024
2025 if (alen != sizeof(*ip)) {
2026 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2027 return;
2028 }
2029 if (*num == max) {
2030 plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
2031 return;
2032 }
2033
2034 addr = (in_addr_t *)(attr + 1);
2035 ip->s_addr = *addr;
2036 (*num)++;
2037
2038 return;
2039}
2040
2041static void
2042isakmp_cfg_getstring(attr, str)
2043 struct isakmp_data *attr;
2044 char *str;
2045{
2046 size_t alen = ntohs(attr->lorv);
2047 char *src;
2048 src = (char *)(attr + 1);
2049
2050 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
2051
2052 return;
2053}
2054
2055#define IP_MAX 40
2056
2057void
2058isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
2059 char *dest;
2060 int count;
2061 void *addr;
2062 int withmask;
2063{
2064 int i;
2065 int p;
2066 int l;
2067 struct unity_network tmp;
2068 for(i = 0, p = 0; i < count; i++) {
2069 if(withmask == 1)
2070 l = sizeof(struct unity_network);
2071 else
2072 l = sizeof(struct in_addr);
2073 memcpy(&tmp, addr, l);
2074 addr += l;
2075 if((uint32_t)tmp.addr4.s_addr == 0)
2076 break;
2077
2078 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
2079 p += strlen(dest + p);
2080 if(withmask == 1) {
2081 dest[p] = '/';
2082 p++;
2083 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
2084 p += strlen(dest + p);
2085 }
2086 dest[p] = ' ';
2087 p++;
2088 }
2089 if(p > 0)
2090 dest[p-1] = '\0';
2091 else
2092 dest[0] = '\0';
2093}
2094
52b7d2ce
A
2095int
2096isakmp_cfg_setenv(iph1, envp, envc)
2097 struct ph1handle *iph1;
2098 char ***envp;
2099 int *envc;
2100{
52b7d2ce 2101 char addrstr[IP_MAX];
d1e348cf
A
2102 char addrlist[IP_MAX * MAXNS + MAXNS];
2103 char *splitlist = addrlist;
2104 char defdom[MAXPATHLEN + 1];
2105 int cidr, tmp;
2106 char cidrstr[4];
2107 int i, p;
2108 int test;
2109
2110 plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
52b7d2ce
A
2111
2112 /*
2113 * Internal IPv4 address, either if
2114 * we are a client or a server.
2115 */
2116 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
d1e348cf
A
2117#ifdef HAVE_LIBLDAP
2118 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2119#endif
52b7d2ce 2120#ifdef HAVE_LIBRADIUS
d1e348cf 2121 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
52b7d2ce
A
2122#endif
2123 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
2124 inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
2125 addrstr, IP_MAX);
2126 } else
2127 addrstr[0] = '\0';
2128
2129 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
2130 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
2131 return -1;
2132 }
2133
d1e348cf
A
2134 if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
2135 if (script_env_append(envp, envc, "XAUTH_USER",
2136 iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
2137 plog(LLV_ERROR, LOCATION, NULL,
2138 "Cannot set XAUTH_USER\n");
2139 return -1;
2140 }
2141 }
2142
52b7d2ce
A
2143 /* Internal IPv4 mask */
2144 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
2145 inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
2146 addrstr, IP_MAX);
2147 else
2148 addrstr[0] = '\0';
2149
d1e348cf
A
2150 /*
2151 * During several releases, documentation adverised INTERNAL_NETMASK4
2152 * while code was using INTERNAL_MASK4. We now do both.
2153 */
52b7d2ce 2154
d1e348cf
A
2155 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
2156 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
2157 return -1;
2158 }
2159
2160 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
2161 plog(LLV_ERROR, LOCATION, NULL,
2162 "Cannot set INTERNAL_NETMASK4\n");
2163 return -1;
2164 }
2165
2166 tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
2167 for (cidr = 0; tmp != 0; cidr++)
2168 tmp <<= 1;
2169 snprintf(cidrstr, 3, "%d", cidr);
2170
2171 if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
2172 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
2173 return -1;
2174 }
52b7d2ce
A
2175
2176 /* Internal IPv4 DNS */
d1e348cf
A
2177 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
2178 /* First Internal IPv4 DNS (for compatibilty with older code */
2179 inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
52b7d2ce 2180 addrstr, IP_MAX);
d1e348cf
A
2181
2182 /* Internal IPv4 DNS - all */
2183 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
2184 (void *)iph1->mode_cfg->dns4, 0);
2185 } else {
52b7d2ce 2186 addrstr[0] = '\0';
d1e348cf
A
2187 addrlist[0] = '\0';
2188 }
52b7d2ce 2189
d1e348cf 2190 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
52b7d2ce
A
2191 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
2192 return -1;
2193 }
d1e348cf
A
2194 if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
2195 plog(LLV_ERROR, LOCATION, NULL,
2196 "Cannot set INTERNAL_DNS4_LIST\n");
2197 return -1;
2198 }
2199
52b7d2ce 2200 /* Internal IPv4 WINS */
d1e348cf
A
2201 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
2202 /*
2203 * First Internal IPv4 WINS
2204 * (for compatibilty with older code
2205 */
2206 inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
52b7d2ce 2207 addrstr, IP_MAX);
d1e348cf
A
2208
2209 /* Internal IPv4 WINS - all */
2210 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
2211 (void *)iph1->mode_cfg->wins4, 0);
2212 } else {
52b7d2ce 2213 addrstr[0] = '\0';
d1e348cf
A
2214 addrlist[0] = '\0';
2215 }
52b7d2ce 2216
d1e348cf
A
2217 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
2218 plog(LLV_ERROR, LOCATION, NULL,
2219 "Cannot set INTERNAL_WINS4\n");
2220 return -1;
2221 }
2222 if (script_env_append(envp, envc,
2223 "INTERNAL_WINS4_LIST", addrlist) != 0) {
2224 plog(LLV_ERROR, LOCATION, NULL,
2225 "Cannot set INTERNAL_WINS4_LIST\n");
52b7d2ce
A
2226 return -1;
2227 }
2228
d1e348cf
A
2229 /* Deault domain */
2230 if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2231 strlcpy(defdom,
2232 iph1->mode_cfg->default_domain,
2233 sizeof(defdom));
2234 else
2235 defdom[0] = '\0';
2236
2237 if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2238 plog(LLV_ERROR, LOCATION, NULL,
2239 "Cannot set DEFAULT_DOMAIN\n");
2240 return -1;
2241 }
2242
2243 /* Split networks */
2244 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
2245 splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
2246 else {
2247 splitlist = addrlist;
2248 addrlist[0] = '\0';
2249 }
2250
2251 if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2252 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2253 return -1;
2254 }
2255 if (splitlist != addrlist)
2256 racoon_free(splitlist);
2257
2258 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
2259 splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
2260 else {
2261 splitlist = addrlist;
2262 addrlist[0] = '\0';
2263 }
2264
2265 if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2266 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2267 return -1;
2268 }
2269 if (splitlist != addrlist)
2270 racoon_free(splitlist);
2271
52b7d2ce
A
2272 return 0;
2273}
d1e348cf
A
2274
2275int
2276isakmp_cfg_resize_pool(size)
2277 int size;
2278{
2279 struct isakmp_cfg_port *new_pool;
2280 size_t len;
2281 int i;
2282
2283 if (size == isakmp_cfg_config.pool_size)
2284 return 0;
2285
2286 plog(LLV_INFO, LOCATION, NULL,
2287 "Resize address pool from %zu to %d\n",
2288 isakmp_cfg_config.pool_size, size);
2289
2290 /* If a pool already exists, check if we can shrink it */
2291 if ((isakmp_cfg_config.port_pool != NULL) &&
2292 (size < isakmp_cfg_config.pool_size)) {
47612122 2293 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
d1e348cf
A
2294 if (isakmp_cfg_config.port_pool[i].used) {
2295 plog(LLV_ERROR, LOCATION, NULL,
2296 "resize pool from %zu to %d impossible "
2297 "port %d is in use\n",
2298 isakmp_cfg_config.pool_size, size, i);
2299 size = i;
2300 break;
2301 }
2302 }
2303 }
2304
2305 len = size * sizeof(*isakmp_cfg_config.port_pool);
2306 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2307 if (new_pool == NULL) {
2308 plog(LLV_ERROR, LOCATION, NULL,
2309 "resize pool from %zu to %d impossible: %s",
2310 isakmp_cfg_config.pool_size, size, strerror(errno));
2311 return -1;
2312 }
2313
2314 /* If size increase, intialize correctly the new records */
2315 if (size > isakmp_cfg_config.pool_size) {
2316 size_t unit;
2317 size_t old_size;
2318
2319 unit = sizeof(*isakmp_cfg_config.port_pool);
2320 old_size = isakmp_cfg_config.pool_size;
2321
2322 bzero((char *)new_pool + (old_size * unit),
2323 (size - old_size) * unit);
2324 }
2325
2326 isakmp_cfg_config.port_pool = new_pool;
2327 isakmp_cfg_config.pool_size = size;
2328
2329 return 0;
2330}
2331
2332int
2333isakmp_cfg_init(cold)
2334 int cold;
2335{
2336 int i;
2337 int error;
2338
2339 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2340 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2341 for (i = 0; i < MAXNS; i++)
2342 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2343 isakmp_cfg_config.dns4_index = 0;
2344 for (i = 0; i < MAXWINS; i++)
2345 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2346 isakmp_cfg_config.nbns4_index = 0;
2347 if (cold != ISAKMP_CFG_INIT_COLD) {
2348 if (isakmp_cfg_config.port_pool) {
2349 racoon_free(isakmp_cfg_config.port_pool);
2350 }
2351 }
2352 isakmp_cfg_config.port_pool = NULL;
2353 isakmp_cfg_config.pool_size = 0;
2354 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2355 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2356 if (cold != ISAKMP_CFG_INIT_COLD) {
2357 if (isakmp_cfg_config.grouplist != NULL) {
2358 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2359 racoon_free(isakmp_cfg_config.grouplist[i]);
2360 racoon_free(isakmp_cfg_config.grouplist);
2361 }
2362 }
2363 isakmp_cfg_config.grouplist = NULL;
2364 isakmp_cfg_config.groupcount = 0;
2365 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2366 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2367 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2368 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2369 sizeof(isakmp_cfg_config.default_domain));
2370 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
2371
2372 if (cold != ISAKMP_CFG_INIT_COLD )
2373 if (isakmp_cfg_config.splitnet_list != NULL)
2374 splitnet_list_free(isakmp_cfg_config.splitnet_list,
2375 &isakmp_cfg_config.splitnet_count);
2376 isakmp_cfg_config.splitnet_list = NULL;
2377 isakmp_cfg_config.splitnet_count = 0;
2378 isakmp_cfg_config.splitnet_type = 0;
2379
2380 isakmp_cfg_config.pfs_group = 0;
2381 isakmp_cfg_config.save_passwd = 0;
2382
2383 if (cold != ISAKMP_CFG_INIT_COLD )
2384 if (isakmp_cfg_config.splitdns_list != NULL)
2385 racoon_free(isakmp_cfg_config.splitdns_list);
2386 isakmp_cfg_config.splitdns_list = NULL;
2387 isakmp_cfg_config.splitdns_len = 0;
2388
47612122 2389#if 0
d1e348cf
A
2390 if (cold == ISAKMP_CFG_INIT_COLD) {
2391 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2392 return error;
2393 }
47612122 2394#endif
d1e348cf
A
2395
2396 return 0;
2397}
2398