]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/isakmp_cfg.c
ipsec-164.10.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / isakmp_cfg.c
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 */
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
41 #include <utmpx.h>
42 #include <util.h>
43
44
45 #ifdef __FreeBSD__
46 # include <libutil.h>
47 #endif
48 #ifdef __NetBSD__
49 # include <util.h>
50 #endif
51
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
73 #if HAVE_STDINT_H
74 #include <stdint.h>
75 #endif
76 #include <ctype.h>
77 #include <resolv.h>
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"
98 #include "localconf.h"
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"
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"
113
114 struct isakmp_cfg_config isakmp_cfg_config;
115
116 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
117 static vchar_t *isakmp_cfg_net(struct ph1handle *, struct isakmp_data *);
118 #if 0
119 static vchar_t *isakmp_cfg_void(struct ph1handle *, struct isakmp_data *);
120 #endif
121 static vchar_t *isakmp_cfg_addr4(struct ph1handle *,
122 struct isakmp_data *, in_addr_t *);
123 static void isakmp_cfg_getaddr4(struct isakmp_data *, struct in_addr *);
124 static vchar_t *isakmp_cfg_addr4_list(struct ph1handle *,
125 struct isakmp_data *, in_addr_t *, int);
126 static void isakmp_cfg_appendaddr4(struct isakmp_data *,
127 struct in_addr *, int *, int);
128 static void isakmp_cfg_getstring(struct isakmp_data *,char *);
129 void isakmp_cfg_iplist_to_str(char *, int, void *, int);
130
131 #define ISAKMP_CFG_LOGIN 1
132 #define ISAKMP_CFG_LOGOUT 2
133 static int isakmp_cfg_accounting(struct ph1handle *, int);
134 #ifdef HAVE_LIBRADIUS
135 static 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 */
142 void
143 isakmp_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;
154 struct ph2handle *iph2;
155 int error = -1;
156
157 /* Check that the packet is long enough to have a header */
158 if (msg->l < sizeof(*packet)) {
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;
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) {
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"));
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 */
184 if (iph1->mode_cfg->ivm == NULL ||
185 iph1->mode_cfg->last_msgid != packet->msgid )
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) {
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"));
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);
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
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;
277 isakmp_cfg_attr_r(iph1, packet->msgid, attrpl, msg);
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
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));
309 out:
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 }
316 vfree(dmsg);
317 }
318
319 int
320 isakmp_cfg_attr_r(iph1, msgid, attrpl, msg)
321 struct ph1handle *iph1;
322 u_int32_t msgid;
323 struct isakmp_pl_attr *attrpl;
324 vchar_t *msg;
325 {
326 int type = attrpl->type;
327
328 plog(LLV_DEBUG, LOCATION, NULL,
329 "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
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;
335 return 0;
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;
344 return isakmp_cfg_request(iph1, attrpl, msg);
345 break;
346
347 case ISAKMP_CFG_SET:
348 iph1->msgid = msgid;
349 return isakmp_cfg_set(iph1, attrpl, msg);
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
362 int
363 isakmp_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;
372 int error;
373
374 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_REPLY)
375 return 0; /* already received this - duplicate packet */
376
377 tlen = ntohs(attrpl->h.len);
378 attr = (struct isakmp_data *)(attrpl + 1);
379 tlen -= sizeof(*attrpl);
380
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,
389 "Short attribute %s = %d\n",
390 s_isakmp_cfg_type(type), ntohs(attr->lorv));
391
392 switch (type) {
393 case XAUTH_TYPE:
394 if ((error = xauth_attr_reply(iph1,
395 attr, ntohs(attrpl->id))) != 0)
396 return error;
397 break;
398
399 break;
400
401 default:
402 plog(LLV_WARNING, LOCATION, NULL,
403 "Ignored short attribute %s\n",
404 s_isakmp_cfg_type(type));
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,
419 "Short attribute %s\n",
420 s_isakmp_cfg_type(type));
421 return -1;
422 }
423
424 plog(LLV_DEBUG, LOCATION, NULL,
425 "Attribute %s, len %zu\n",
426 s_isakmp_cfg_type(type), alen);
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:
439 if ((error = xauth_attr_reply(iph1,
440 attr, ntohs(attrpl->id))) != 0)
441 return error;
442 break;
443 case INTERNAL_IP4_ADDRESS:
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 }
448 break;
449 case INTERNAL_IP4_NETMASK:
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 }
454 break;
455 case INTERNAL_IP4_DNS:
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 }
462 break;
463 case INTERNAL_IP4_NBNS:
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 }
470 break;
471 case UNITY_DEF_DOMAIN:
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;
478 case UNITY_SPLIT_INCLUDE:
479 case UNITY_LOCAL_LAN:
480 case UNITY_SPLITDNS_NAME:
481 case UNITY_BANNER:
482 case UNITY_SAVE_PASSWD:
483 case UNITY_NATT_PORT:
484 case UNITY_FW_TYPE:
485 case UNITY_BACKUP_SERVERS:
486 case UNITY_DDNS_HOSTNAME:
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
496 default:
497 plog(LLV_WARNING, LOCATION, NULL,
498 "Ignored attribute %s\n",
499 s_isakmp_cfg_type(type));
500 break;
501 }
502
503 npp = (char *)attr;
504 attr = (struct isakmp_data *)(npp + sizeof(*attr) + alen);
505 tlen -= (sizeof(*attr) + alen);
506 }
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);
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 }
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
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 */
533
534 if ((iph1->status == PHASE1ST_ESTABLISHED) &&
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
556
557 #ifdef ENABLE_ADMINPORT
558 {
559 vchar_t *buf;
560
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 }
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
583 int
584 isakmp_cfg_request(iph1, attrpl, msg)
585 struct ph1handle *iph1;
586 struct isakmp_pl_attr *attrpl;
587 vchar_t *msg;
588 {
589 struct isakmp_data *attr;
590 int tlen;
591 size_t alen;
592 char *npp;
593 vchar_t *payload = NULL;
594 struct isakmp_pl_attr *reply;
595 vchar_t *reply_attr;
596 int type;
597 int error = -1;
598
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);
623
624 IPSECLOGASLMSG("IPSec Extended Authentication requested.\n");
625
626 return 0;
627 }
628
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));
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,
644 "Short attribute %s = %d\n",
645 s_isakmp_cfg_type(type), ntohs(attr->lorv));
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,
653 "Ignored short attribute %s\n",
654 s_isakmp_cfg_type(type));
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 }
668
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,
675 "Short attribute %s\n",
676 s_isakmp_cfg_type(type));
677 goto end;
678 }
679
680 plog(LLV_DEBUG, LOCATION, NULL,
681 "Attribute %s, len %zu\n",
682 s_isakmp_cfg_type(type), alen);
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:
719 case UNITY_LOCAL_LAN:
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,
728 "Ignored attribute %s\n",
729 s_isakmp_cfg_type(type));
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 }
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
748 plog(LLV_DEBUG, LOCATION, NULL,
749 "Sending MODE_CFG REPLY\n");
750
751 error = isakmp_cfg_send(iph1, payload,
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
772
773 }
774
775 end:
776 vfree(payload);
777
778 return error;
779 }
780
781 int
782 isakmp_cfg_set(iph1, attrpl, msg)
783 struct ph1handle *iph1;
784 struct isakmp_pl_attr *attrpl;
785 vchar_t *msg;
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
814 plog(LLV_DEBUG, LOCATION, NULL,
815 "Attribute %s\n",
816 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
817
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,
824 "Unexpected SET attribute %s\n",
825 s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
826 break;
827 }
828
829 if (reply_attr != NULL) {
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
855 plog(LLV_DEBUG, LOCATION, NULL,
856 "Sending MODE_CFG ACK\n");
857
858 error = isakmp_cfg_send(iph1, payload,
859 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 0, 0, msg);
860
861 if (iph1->mode_cfg->flags & ISAKMP_CFG_DELETE_PH1) {
862 if (iph1->status == PHASE1ST_ESTABLISHED)
863 isakmp_info_send_d1(iph1);
864 isakmp_ph1expire(iph1);
865 iph1 = NULL;
866 }
867 vfree(payload);
868
869 /*
870 * If required, request ISAKMP mode config information: ignore rekeys
871 */
872 if ((iph1 != NULL) && (!iph1->is_rekey) && (iph1->rmconf->mode_cfg) && (error == 0))
873 error = isakmp_cfg_getconfig(iph1);
874
875 return error;
876 }
877
878
879 static vchar_t *
880 buffer_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
900 static vchar_t *
901 isakmp_cfg_net(iph1, attr)
902 struct ph1handle *iph1;
903 struct isakmp_data *attr;
904 {
905 int type;
906 int confsource;
907
908 type = ntohs(attr->type);
909
910 /*
911 * Don't give an address to a peer that did not succeed Xauth
912 */
913 if (xauth_check(iph1) != 0) {
914 plog(LLV_ERROR, LOCATION, NULL,
915 "Attempt to start phase config whereas Xauth failed\n");
916 return NULL;
917 }
918
919 confsource = isakmp_cfg_config.confsource;
920 /*
921 * If we have to fall back to a local
922 * configuration source, we will jump
923 * back to this point.
924 */
925 retry_source:
926
927 switch(type) {
928 case INTERNAL_IP4_ADDRESS:
929 switch(confsource) {
930 #ifdef HAVE_LIBLDAP
931 case ISAKMP_CFG_CONF_LDAP:
932 if (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
933 break;
934 plog(LLV_INFO, LOCATION, NULL,
935 "No IP from LDAP, using local pool\n");
936 /* FALLTHROUGH */
937 confsource = ISAKMP_CFG_CONF_LOCAL;
938 goto retry_source;
939 #endif
940 #ifdef HAVE_LIBRADIUS
941 case ISAKMP_CFG_CONF_RADIUS:
942 if ((iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN)
943 && (iph1->mode_cfg->addr4.s_addr != htonl(-2)))
944 /*
945 * -2 is 255.255.255.254, RADIUS uses that
946 * to instruct the NAS to use a local pool
947 */
948 break;
949 plog(LLV_INFO, LOCATION, NULL,
950 "No IP from RADIUS, using local pool\n");
951 /* FALLTHROUGH */
952 confsource = ISAKMP_CFG_CONF_LOCAL;
953 goto retry_source;
954 #endif
955 case ISAKMP_CFG_CONF_LOCAL:
956 if (isakmp_cfg_getport(iph1) == -1) {
957 plog(LLV_ERROR, LOCATION, NULL,
958 "Port pool depleted\n");
959 break;
960 }
961
962 iph1->mode_cfg->addr4.s_addr =
963 htonl(ntohl(isakmp_cfg_config.network4)
964 + iph1->mode_cfg->port);
965 iph1->mode_cfg->flags |= ISAKMP_CFG_ADDR4_LOCAL;
966 break;
967
968 default:
969 plog(LLV_ERROR, LOCATION, NULL,
970 "Unexpected confsource\n");
971 }
972
973 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGIN) != 0)
974 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
975
976 return isakmp_cfg_addr4(iph1,
977 attr, &iph1->mode_cfg->addr4.s_addr);
978 break;
979
980 case INTERNAL_IP4_NETMASK:
981 switch(confsource) {
982 #ifdef HAVE_LIBLDAP
983 case ISAKMP_CFG_CONF_LDAP:
984 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
985 break;
986 plog(LLV_INFO, LOCATION, NULL,
987 "No mask from LDAP, using local pool\n");
988 /* FALLTHROUGH */
989 confsource = ISAKMP_CFG_CONF_LOCAL;
990 goto retry_source;
991 #endif
992 #ifdef HAVE_LIBRADIUS
993 case ISAKMP_CFG_CONF_RADIUS:
994 if (iph1->mode_cfg->flags & ISAKMP_CFG_MASK4_EXTERN)
995 break;
996 plog(LLV_INFO, LOCATION, NULL,
997 "No mask from RADIUS, using local pool\n");
998 /* FALLTHROUGH */
999 confsource = ISAKMP_CFG_CONF_LOCAL;
1000 goto retry_source;
1001 #endif
1002 case ISAKMP_CFG_CONF_LOCAL:
1003 iph1->mode_cfg->mask4.s_addr
1004 = isakmp_cfg_config.netmask4;
1005 iph1->mode_cfg->flags |= ISAKMP_CFG_MASK4_LOCAL;
1006 break;
1007
1008 default:
1009 plog(LLV_ERROR, LOCATION, NULL,
1010 "Unexpected confsource\n");
1011 }
1012 return isakmp_cfg_addr4(iph1, attr,
1013 &iph1->mode_cfg->mask4.s_addr);
1014 break;
1015
1016 case INTERNAL_IP4_DNS:
1017 return isakmp_cfg_addr4_list(iph1,
1018 attr, &isakmp_cfg_config.dns4[0],
1019 isakmp_cfg_config.dns4_index);
1020 break;
1021
1022 case INTERNAL_IP4_NBNS:
1023 return isakmp_cfg_addr4_list(iph1,
1024 attr, &isakmp_cfg_config.nbns4[0],
1025 isakmp_cfg_config.nbns4_index);
1026 break;
1027
1028 case INTERNAL_IP4_SUBNET:
1029 return isakmp_cfg_addr4(iph1,
1030 attr, &isakmp_cfg_config.network4);
1031 break;
1032
1033 default:
1034 plog(LLV_ERROR, LOCATION, NULL, "Unexpected type %d\n", type);
1035 break;
1036 }
1037 return NULL;
1038 }
1039
1040 #if 0
1041 static vchar_t *
1042 isakmp_cfg_void(iph1, attr)
1043 struct ph1handle *iph1;
1044 struct isakmp_data *attr;
1045 {
1046 vchar_t *buffer;
1047 struct isakmp_data *new;
1048
1049 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1050 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1051 return NULL;
1052 }
1053
1054 new = (struct isakmp_data *)buffer->v;
1055
1056 new->type = attr->type;
1057 new->lorv = htons(0);
1058
1059 return buffer;
1060 }
1061 #endif
1062
1063 vchar_t *
1064 isakmp_cfg_copy(iph1, attr)
1065 struct ph1handle *iph1;
1066 struct isakmp_data *attr;
1067 {
1068 vchar_t *buffer;
1069 size_t len = 0;
1070
1071 if ((ntohs(attr->type) & ISAKMP_GEN_MASK) == ISAKMP_GEN_TLV)
1072 len = ntohs(attr->lorv);
1073
1074 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1075 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1076 return NULL;
1077 }
1078
1079 memcpy(buffer->v, attr, sizeof(*attr) + ntohs(attr->lorv));
1080
1081 return buffer;
1082 }
1083
1084 vchar_t *
1085 isakmp_cfg_short(iph1, attr, value)
1086 struct ph1handle *iph1;
1087 struct isakmp_data *attr;
1088 int value;
1089 {
1090 vchar_t *buffer;
1091 struct isakmp_data *new;
1092 int type;
1093
1094 if ((buffer = vmalloc(sizeof(*attr))) == NULL) {
1095 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1096 return NULL;
1097 }
1098
1099 new = (struct isakmp_data *)buffer->v;
1100 type = ntohs(attr->type) & ~ISAKMP_GEN_MASK;
1101
1102 new->type = htons(type | ISAKMP_GEN_TV);
1103 new->lorv = htons(value);
1104
1105 return buffer;
1106 }
1107
1108 vchar_t *
1109 isakmp_cfg_varlen(iph1, attr, string, len)
1110 struct ph1handle *iph1;
1111 struct isakmp_data *attr;
1112 char *string;
1113 size_t len;
1114 {
1115 vchar_t *buffer;
1116 struct isakmp_data *new;
1117 char *data;
1118
1119 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1120 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1121 return NULL;
1122 }
1123
1124 new = (struct isakmp_data *)buffer->v;
1125
1126 new->type = attr->type;
1127 new->lorv = htons(len);
1128 data = (char *)(new + 1);
1129
1130 memcpy(data, string, len);
1131
1132 return buffer;
1133 }
1134 vchar_t *
1135 isakmp_cfg_string(iph1, attr, string)
1136 struct ph1handle *iph1;
1137 struct isakmp_data *attr;
1138 char *string;
1139 {
1140 size_t len = strlen(string);
1141 return isakmp_cfg_varlen(iph1, attr, string, len);
1142 }
1143
1144 static vchar_t *
1145 isakmp_cfg_addr4(iph1, attr, addr)
1146 struct ph1handle *iph1;
1147 struct isakmp_data *attr;
1148 in_addr_t *addr;
1149 {
1150 vchar_t *buffer;
1151 struct isakmp_data *new;
1152 size_t len;
1153
1154 len = sizeof(*addr);
1155 if ((buffer = vmalloc(sizeof(*attr) + len)) == NULL) {
1156 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1157 return NULL;
1158 }
1159
1160 new = (struct isakmp_data *)buffer->v;
1161
1162 new->type = attr->type;
1163 new->lorv = htons(len);
1164 memcpy(new + 1, addr, len);
1165
1166 return buffer;
1167 }
1168
1169 static vchar_t *
1170 isakmp_cfg_addr4_list(iph1, attr, addr, nbr)
1171 struct ph1handle *iph1;
1172 struct isakmp_data *attr;
1173 in_addr_t *addr;
1174 int nbr;
1175 {
1176 int error = -1;
1177 vchar_t *buffer = NULL;
1178 vchar_t *bufone = NULL;
1179 struct isakmp_data *new;
1180 size_t len;
1181 int i;
1182
1183 len = sizeof(*addr);
1184 if ((buffer = vmalloc(0)) == NULL) {
1185 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1186 goto out;
1187 }
1188 for(i = 0; i < nbr; i++) {
1189 if ((bufone = vmalloc(sizeof(*attr) + len)) == NULL) {
1190 plog(LLV_ERROR, LOCATION, NULL,
1191 "Cannot allocate memory\n");
1192 goto out;
1193 }
1194 new = (struct isakmp_data *)bufone->v;
1195 new->type = attr->type;
1196 new->lorv = htons(len);
1197 memcpy(new + 1, &addr[i], len);
1198 new += (len + sizeof(*attr));
1199 buffer = buffer_cat(buffer, bufone);
1200 vfree(bufone);
1201 }
1202
1203 error = 0;
1204
1205 out:
1206 if ((error != 0) && (buffer != NULL)) {
1207 vfree(buffer);
1208 buffer = NULL;
1209 }
1210
1211 return buffer;
1212 }
1213
1214 struct isakmp_ivm *
1215 isakmp_cfg_newiv(iph1, msgid)
1216 struct ph1handle *iph1;
1217 u_int32_t msgid;
1218 {
1219 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1220
1221 if (ics == NULL) {
1222 plog(LLV_ERROR, LOCATION, NULL,
1223 "isakmp_cfg_newiv called without mode config state\n");
1224 return NULL;
1225 }
1226
1227 if (ics->ivm != NULL)
1228 oakley_delivm(ics->ivm);
1229
1230 ics->ivm = oakley_newiv2(iph1, msgid);
1231 ics->last_msgid = msgid;
1232
1233 return ics->ivm;
1234 }
1235
1236 /* Derived from isakmp_info_send_common */
1237 int
1238 isakmp_cfg_send(iph1, payload, np, flags, new_exchange, retry_count, msg)
1239 struct ph1handle *iph1;
1240 vchar_t *payload;
1241 u_int32_t np;
1242 int flags;
1243 int new_exchange;
1244 int retry_count;
1245 vchar_t *msg;
1246 {
1247 struct ph2handle *iph2 = NULL;
1248 vchar_t *hash = NULL;
1249 struct isakmp *isakmp;
1250 struct isakmp_gen *gen;
1251 char *p;
1252 int tlen;
1253 int error = -1;
1254 struct isakmp_cfg_state *ics = iph1->mode_cfg;
1255
1256 /* Check if phase 1 is established */
1257 if ((iph1->status != PHASE1ST_ESTABLISHED) ||
1258 (iph1->local == NULL) ||
1259 (iph1->remote == NULL)) {
1260 plog(LLV_ERROR, LOCATION, NULL,
1261 "ISAKMP mode config exchange with immature phase 1\n");
1262 goto end;
1263 }
1264
1265 /* add new entry to isakmp status table */
1266 iph2 = newph2();
1267 if (iph2 == NULL) {
1268 plog(LLV_ERROR, LOCATION, NULL,
1269 "failed to allocate ph2");
1270 goto end;
1271 }
1272
1273 iph2->dst = dupsaddr((struct sockaddr *)iph1->remote);
1274 if (iph2->dst == NULL) {
1275 plog(LLV_ERROR, LOCATION, NULL,
1276 "failed to duplicate remote address");
1277 delph2(iph2);
1278 goto end;
1279 }
1280 iph2->src = dupsaddr((struct sockaddr *)iph1->local);
1281 if (iph2->src == NULL) {
1282 plog(LLV_ERROR, LOCATION, NULL,
1283 "failed to duplicate local address");
1284 delph2(iph2);
1285 goto end;
1286 }
1287
1288 switch (iph1->remote->ss_family) {
1289 case AF_INET:
1290 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1291 ((struct sockaddr_in *)iph2->dst)->sin_port = 0;
1292 ((struct sockaddr_in *)iph2->src)->sin_port = 0;
1293 #endif
1294 break;
1295 #ifdef INET6
1296 case AF_INET6:
1297 #if (!defined(ENABLE_NATT)) || (defined(BROKEN_NATT))
1298 ((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
1299 ((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
1300 #endif
1301 break;
1302 #endif
1303 default:
1304 plog(LLV_ERROR, LOCATION, NULL,
1305 "invalid family: %d\n", iph1->remote->ss_family);
1306 delph2(iph2);
1307 goto end;
1308 }
1309 iph2->ph1 = iph1;
1310 iph2->side = INITIATOR;
1311 iph2->status = PHASE2ST_START;
1312
1313 if (new_exchange)
1314 iph2->msgid = isakmp_newmsgid2(iph1);
1315 else
1316 iph2->msgid = iph1->msgid;
1317
1318 /* get IV and HASH(1) if skeyid_a was generated. */
1319 if (iph1->skeyid_a != NULL) {
1320 if (new_exchange) {
1321 if (isakmp_cfg_newiv(iph1, iph2->msgid) == NULL) {
1322 plog(LLV_ERROR, LOCATION, NULL,
1323 "failed to generate IV");
1324 delph2(iph2);
1325 goto end;
1326 }
1327 }
1328
1329 /* generate HASH(1) */
1330 hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
1331 if (hash == NULL) {
1332 plog(LLV_ERROR, LOCATION, NULL,
1333 "failed to generate HASH");
1334 delph2(iph2);
1335 goto end;
1336 }
1337
1338 /* initialized total buffer length */
1339 tlen = hash->l;
1340 tlen += sizeof(*gen);
1341 } else {
1342 /* IKE-SA is not established */
1343 hash = NULL;
1344
1345 /* initialized total buffer length */
1346 tlen = 0;
1347 }
1348 if ((flags & ISAKMP_FLAG_A) == 0)
1349 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
1350 else
1351 iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
1352
1353 insph2(iph2);
1354 bindph12(iph1, iph2);
1355
1356 tlen += sizeof(*isakmp) + payload->l;
1357
1358 /* create buffer for isakmp payload */
1359 iph2->sendbuf = vmalloc(tlen);
1360 if (iph2->sendbuf == NULL) {
1361 plog(LLV_ERROR, LOCATION, NULL,
1362 "failed to get buffer to send.\n");
1363 goto err;
1364 }
1365
1366 /* create isakmp header */
1367 isakmp = (struct isakmp *)iph2->sendbuf->v;
1368 memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
1369 memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
1370 isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
1371 isakmp->v = iph1->version;
1372 isakmp->etype = ISAKMP_ETYPE_CFG;
1373 isakmp->flags = iph2->flags;
1374 memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
1375 isakmp->len = htonl(tlen);
1376 p = (char *)(isakmp + 1);
1377
1378 /* create HASH payload */
1379 if (hash != NULL) {
1380 gen = (struct isakmp_gen *)p;
1381 gen->np = np & 0xff;
1382 gen->len = htons(sizeof(*gen) + hash->l);
1383 p += sizeof(*gen);
1384 memcpy(p, hash->v, hash->l);
1385 p += hash->l;
1386 }
1387
1388 /* add payload */
1389 memcpy(p, payload->v, payload->l);
1390 p += payload->l;
1391
1392 #ifdef HAVE_PRINT_ISAKMP_C
1393 isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
1394 #endif
1395
1396 plog(LLV_DEBUG, LOCATION, NULL, "MODE_CFG packet to send\n");
1397 plogdump(LLV_DEBUG, iph2->sendbuf->v, iph2->sendbuf->l);
1398
1399 /* encoding */
1400 if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
1401 vchar_t *tmp;
1402
1403 tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf,
1404 ics->ivm->ive, ics->ivm->iv);
1405 VPTRINIT(iph2->sendbuf);
1406 if (tmp == NULL) {
1407 plog(LLV_ERROR, LOCATION, NULL,
1408 "failed to encrypt packet");
1409 goto err;
1410 }
1411 iph2->sendbuf = tmp;
1412 }
1413
1414 /* HDR*, HASH(1), ATTR */
1415
1416 if (retry_count > 0) {
1417 iph2->retry_counter = retry_count;
1418 if (isakmp_ph2resend(iph2) < 0) {
1419 plog(LLV_ERROR, LOCATION, NULL,
1420 "failed to resend packet");
1421 VPTRINIT(iph2->sendbuf);
1422 goto err;
1423 }
1424 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1425 IPSECSESSIONEVENTCODE_IKEV1_CFG_RETRANSMIT,
1426 CONSTSTR("Mode-Config retransmit"),
1427 CONSTSTR(NULL));
1428 error = 0;
1429 goto end;
1430 }
1431
1432 if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
1433 plog(LLV_ERROR, LOCATION, NULL,
1434 "failed to send packet");
1435 VPTRINIT(iph2->sendbuf);
1436 goto err;
1437 }
1438 if (msg) {
1439 /* the sending message is added to the received-list. */
1440 if (add_recvdpkt(iph1->remote, iph1->local, iph2->sendbuf, msg,
1441 PH2_NON_ESP_EXTRA_LEN(iph2), PH1_FRAG_FLAGS(iph1)) == -1) {
1442 plog(LLV_ERROR , LOCATION, NULL,
1443 "failed to add a response packet to the tree.\n");
1444 }
1445 }
1446
1447 plog(LLV_DEBUG, LOCATION, NULL,
1448 "sendto mode config %s.\n", s_isakmp_nptype(np));
1449
1450 /*
1451 * XXX We might need to resend the message...
1452 */
1453
1454 error = 0;
1455 VPTRINIT(iph2->sendbuf);
1456
1457 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1458 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_SUCC,
1459 CONSTSTR("Mode-Config message"),
1460 CONSTSTR(NULL));
1461
1462 err:
1463 if (error) {
1464 IPSECSESSIONTRACEREVENT(iph1->parent_session,
1465 IPSECSESSIONEVENTCODE_IKE_PACKET_TX_FAIL,
1466 CONSTSTR("Mode-Config message"),
1467 CONSTSTR("Failed to transmit Mode-Config message"));
1468 }
1469 unbindph12(iph2);
1470 remph2(iph2);
1471 delph2(iph2);
1472 end:
1473 if (hash)
1474 vfree(hash);
1475 return error;
1476 }
1477
1478
1479 void
1480 isakmp_cfg_rmstate(iph1)
1481 struct ph1handle *iph1;
1482 {
1483 struct isakmp_cfg_state *state = iph1->mode_cfg;
1484
1485 if (isakmp_cfg_accounting(iph1, ISAKMP_CFG_LOGOUT) != 0)
1486 plog(LLV_ERROR, LOCATION, NULL, "Accounting failed\n");
1487
1488 if (state->flags & ISAKMP_CFG_PORT_ALLOCATED)
1489 isakmp_cfg_putport(iph1, state->port);
1490
1491 /* Delete the IV if it's still there */
1492 if(iph1->mode_cfg->ivm) {
1493 oakley_delivm(iph1->mode_cfg->ivm);
1494 iph1->mode_cfg->ivm = NULL;
1495 }
1496
1497 /* Free any allocated splitnet lists */
1498 if(iph1->mode_cfg->split_include != NULL)
1499 splitnet_list_free(iph1->mode_cfg->split_include,
1500 &iph1->mode_cfg->include_count);
1501 if(iph1->mode_cfg->split_local != NULL)
1502 splitnet_list_free(iph1->mode_cfg->split_local,
1503 &iph1->mode_cfg->local_count);
1504
1505 xauth_rmstate(&state->xauth);
1506
1507 if (state->attr_list)
1508 vfree(state->attr_list);
1509
1510 racoon_free(state);
1511 iph1->mode_cfg = NULL;
1512
1513 return;
1514 }
1515
1516 struct isakmp_cfg_state *
1517 isakmp_cfg_mkstate(void)
1518 {
1519 struct isakmp_cfg_state *state;
1520
1521 if ((state = racoon_malloc(sizeof(*state))) == NULL) {
1522 plog(LLV_ERROR, LOCATION, NULL,
1523 "Cannot allocate memory for mode config state\n");
1524 return NULL;
1525 }
1526 memset(state, 0, sizeof(*state));
1527
1528 return state;
1529 }
1530
1531 int
1532 isakmp_cfg_getport(iph1)
1533 struct ph1handle *iph1;
1534 {
1535 unsigned int i;
1536 size_t size = isakmp_cfg_config.pool_size;
1537
1538 if (iph1->mode_cfg->flags & ISAKMP_CFG_PORT_ALLOCATED)
1539 return iph1->mode_cfg->port;
1540
1541 if (isakmp_cfg_config.port_pool == NULL) {
1542 plog(LLV_ERROR, LOCATION, NULL,
1543 "isakmp_cfg_config.port_pool == NULL\n");
1544 return -1;
1545 }
1546
1547 for (i = 0; i < size; i++) {
1548 if (isakmp_cfg_config.port_pool[i].used == 0)
1549 break;
1550 }
1551
1552 if (i == size) {
1553 plog(LLV_ERROR, LOCATION, NULL,
1554 "No more addresses available\n");
1555 return -1;
1556 }
1557
1558 isakmp_cfg_config.port_pool[i].used = 1;
1559
1560 plog(LLV_INFO, LOCATION, NULL, "Using port %d\n", i);
1561
1562 iph1->mode_cfg->flags |= ISAKMP_CFG_PORT_ALLOCATED;
1563 iph1->mode_cfg->port = i;
1564
1565 return i;
1566 }
1567
1568 int
1569 isakmp_cfg_putport(iph1, index)
1570 struct ph1handle *iph1;
1571 unsigned int index;
1572 {
1573 if (isakmp_cfg_config.port_pool == NULL) {
1574 plog(LLV_ERROR, LOCATION, NULL,
1575 "isakmp_cfg_config.port_pool == NULL\n");
1576 return -1;
1577 }
1578
1579 if (isakmp_cfg_config.port_pool[index].used == 0) {
1580 plog(LLV_ERROR, LOCATION, NULL,
1581 "Attempt to release an unallocated address (port %d)\n",
1582 index);
1583 return -1;
1584 }
1585
1586 #ifdef HAVE_LIBPAM
1587 /* Cleanup PAM status associated with the port */
1588 if (isakmp_cfg_config.authsource == ISAKMP_CFG_AUTH_PAM)
1589 privsep_cleanup_pam(index);
1590 #endif
1591 isakmp_cfg_config.port_pool[index].used = 0;
1592 iph1->mode_cfg->flags &= ISAKMP_CFG_PORT_ALLOCATED;
1593
1594 plog(LLV_INFO, LOCATION, NULL, "Released port %d\n", index);
1595
1596 return 0;
1597 }
1598
1599 #ifdef HAVE_LIBPAM
1600 void
1601 cleanup_pam(port)
1602 int port;
1603 {
1604 if (isakmp_cfg_config.port_pool[port].pam != NULL) {
1605 pam_end(isakmp_cfg_config.port_pool[port].pam, PAM_SUCCESS);
1606 isakmp_cfg_config.port_pool[port].pam = NULL;
1607 }
1608
1609 return;
1610 }
1611 #endif
1612
1613 /* Accounting, only for RADIUS or PAM */
1614 static int
1615 isakmp_cfg_accounting(iph1, inout)
1616 struct ph1handle *iph1;
1617 int inout;
1618 {
1619 #ifdef HAVE_LIBPAM
1620 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_PAM)
1621 return privsep_accounting_pam(iph1->mode_cfg->port,
1622 inout);
1623 #endif
1624 #ifdef HAVE_LIBRADIUS
1625 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_RADIUS)
1626 return isakmp_cfg_accounting_radius(iph1, inout);
1627 #endif
1628 #ifdef HAVE_OPENSSL
1629 if (isakmp_cfg_config.accounting == ISAKMP_CFG_ACCT_SYSTEM)
1630 return privsep_accounting_system(iph1->mode_cfg->port,
1631 iph1->remote, iph1->mode_cfg->login, inout);
1632 #endif
1633 return 0;
1634 }
1635
1636 #ifdef HAVE_LIBPAM
1637 int
1638 isakmp_cfg_accounting_pam(port, inout)
1639 int port;
1640 int inout;
1641 {
1642 int error = 0;
1643 pam_handle_t *pam;
1644
1645 if (isakmp_cfg_config.port_pool == NULL) {
1646 plog(LLV_ERROR, LOCATION, NULL,
1647 "isakmp_cfg_config.port_pool == NULL\n");
1648 return -1;
1649 }
1650
1651 pam = isakmp_cfg_config.port_pool[port].pam;
1652 if (pam == NULL) {
1653 plog(LLV_ERROR, LOCATION, NULL, "pam handle is NULL\n");
1654 return -1;
1655 }
1656
1657 switch (inout) {
1658 case ISAKMP_CFG_LOGIN:
1659 error = pam_open_session(pam, 0);
1660 break;
1661 case ISAKMP_CFG_LOGOUT:
1662 error = pam_close_session(pam, 0);
1663 pam_end(pam, error);
1664 isakmp_cfg_config.port_pool[port].pam = NULL;
1665 break;
1666 default:
1667 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1668 break;
1669 }
1670
1671 if (error != 0) {
1672 plog(LLV_ERROR, LOCATION, NULL,
1673 "pam_open_session/pam_close_session failed: %s\n",
1674 pam_strerror(pam, error));
1675 return -1;
1676 }
1677
1678 return 0;
1679 }
1680 #endif /* HAVE_LIBPAM */
1681
1682 #ifdef HAVE_LIBRADIUS
1683 static int
1684 isakmp_cfg_accounting_radius(iph1, inout)
1685 struct ph1handle *iph1;
1686 int inout;
1687 {
1688 /* For first time use, initialize Radius */
1689 if (radius_acct_state == NULL) {
1690 if ((radius_acct_state = rad_acct_open()) == NULL) {
1691 plog(LLV_ERROR, LOCATION, NULL,
1692 "Cannot init librradius\n");
1693 return -1;
1694 }
1695
1696 if (rad_config(radius_acct_state, NULL) != 0) {
1697 plog(LLV_ERROR, LOCATION, NULL,
1698 "Cannot open librarius config file: %s\n",
1699 rad_strerror(radius_acct_state));
1700 rad_close(radius_acct_state);
1701 radius_acct_state = NULL;
1702 return -1;
1703 }
1704 }
1705
1706 if (rad_create_request(radius_acct_state,
1707 RAD_ACCOUNTING_REQUEST) != 0) {
1708 plog(LLV_ERROR, LOCATION, NULL,
1709 "rad_create_request failed: %s\n",
1710 rad_strerror(radius_acct_state));
1711 return -1;
1712 }
1713
1714 if (rad_put_string(radius_acct_state, RAD_USER_NAME,
1715 iph1->mode_cfg->login) != 0) {
1716 plog(LLV_ERROR, LOCATION, NULL,
1717 "rad_put_string failed: %s\n",
1718 rad_strerror(radius_acct_state));
1719 return -1;
1720 }
1721
1722 switch (inout) {
1723 case ISAKMP_CFG_LOGIN:
1724 inout = RAD_START;
1725 break;
1726 case ISAKMP_CFG_LOGOUT:
1727 inout = RAD_STOP;
1728 break;
1729 default:
1730 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1731 break;
1732 }
1733
1734 if (rad_put_addr(radius_acct_state,
1735 RAD_FRAMED_IP_ADDRESS, iph1->mode_cfg->addr4) != 0) {
1736 plog(LLV_ERROR, LOCATION, NULL,
1737 "rad_put_addr failed: %s\n",
1738 rad_strerror(radius_acct_state));
1739 return -1;
1740 }
1741
1742 if (rad_put_addr(radius_acct_state,
1743 RAD_LOGIN_IP_HOST, iph1->mode_cfg->addr4) != 0) {
1744 plog(LLV_ERROR, LOCATION, NULL,
1745 "rad_put_addr failed: %s\n",
1746 rad_strerror(radius_acct_state));
1747 return -1;
1748 }
1749
1750 if (rad_put_int(radius_acct_state, RAD_ACCT_STATUS_TYPE, inout) != 0) {
1751 plog(LLV_ERROR, LOCATION, NULL,
1752 "rad_put_int failed: %s\n",
1753 rad_strerror(radius_acct_state));
1754 return -1;
1755 }
1756
1757 if (isakmp_cfg_radius_common(radius_acct_state,
1758 iph1->mode_cfg->port) != 0)
1759 return -1;
1760
1761 if (rad_send_request(radius_acct_state) != RAD_ACCOUNTING_RESPONSE) {
1762 plog(LLV_ERROR, LOCATION, NULL,
1763 "rad_send_request failed: %s\n",
1764 rad_strerror(radius_acct_state));
1765 return -1;
1766 }
1767
1768 return 0;
1769 }
1770 #endif /* HAVE_LIBRADIUS */
1771
1772 /*
1773 * Attributes common to all RADIUS requests
1774 */
1775 #ifdef HAVE_LIBRADIUS
1776 int
1777 isakmp_cfg_radius_common(radius_state, port)
1778 struct rad_handle *radius_state;
1779 int port;
1780 {
1781 struct utsname name;
1782 static struct hostent *host = NULL;
1783 struct in_addr nas_addr;
1784
1785 /*
1786 * Find our own IP by resolving our nodename
1787 */
1788 if (host == NULL) {
1789 if (uname(&name) != 0) {
1790 plog(LLV_ERROR, LOCATION, NULL,
1791 "uname failed: %s\n", strerror(errno));
1792 return -1;
1793 }
1794
1795 if ((host = gethostbyname(name.nodename)) == NULL) {
1796 plog(LLV_ERROR, LOCATION, NULL,
1797 "gethostbyname failed: %s\n", strerror(errno));
1798 return -1;
1799 }
1800 }
1801
1802 memcpy(&nas_addr, host->h_addr, sizeof(nas_addr));
1803 if (rad_put_addr(radius_state, RAD_NAS_IP_ADDRESS, nas_addr) != 0) {
1804 plog(LLV_ERROR, LOCATION, NULL,
1805 "rad_put_addr failed: %s\n",
1806 rad_strerror(radius_state));
1807 return -1;
1808 }
1809
1810 if (rad_put_int(radius_state, RAD_NAS_PORT, port) != 0) {
1811 plog(LLV_ERROR, LOCATION, NULL,
1812 "rad_put_int failed: %s\n",
1813 rad_strerror(radius_state));
1814 return -1;
1815 }
1816
1817 if (rad_put_int(radius_state, RAD_NAS_PORT_TYPE, RAD_VIRTUAL) != 0) {
1818 plog(LLV_ERROR, LOCATION, NULL,
1819 "rad_put_int failed: %s\n",
1820 rad_strerror(radius_state));
1821 return -1;
1822 }
1823
1824 if (rad_put_int(radius_state, RAD_SERVICE_TYPE, RAD_FRAMED) != 0) {
1825 plog(LLV_ERROR, LOCATION, NULL,
1826 "rad_put_int failed: %s\n",
1827 rad_strerror(radius_state));
1828 return -1;
1829 }
1830
1831 return 0;
1832 }
1833 #endif
1834
1835 /*
1836 Logs the user into the utmp system files.
1837 */
1838
1839 int
1840 isakmp_cfg_accounting_system(port, raddr, usr, inout)
1841 int port;
1842 struct sockaddr_storage *raddr;
1843 char *usr;
1844 int inout;
1845 {
1846 struct utmpx ut;
1847 char term[_UTX_LINESIZE];
1848 char addr[NI_MAXHOST];
1849
1850 if (usr == NULL || usr[0]=='\0') {
1851 plog(LLV_ERROR, LOCATION, NULL,
1852 "system accounting : no login found\n");
1853 return -1;
1854 }
1855
1856 snprintf(term, sizeof(term), TERMSPEC, port);
1857
1858 switch (inout) {
1859 case ISAKMP_CFG_LOGIN:
1860 strlcpy(ut.ut_user, usr, sizeof(ut.ut_user));
1861
1862 strlcpy(ut.ut_line, term, sizeof(ut.ut_line));
1863
1864 GETNAMEINFO_NULL((struct sockaddr *)raddr, addr);
1865 strlcpy(ut.ut_host, addr, sizeof(ut.ut_host));
1866
1867 ut.ut_pid = getpid();
1868
1869 ut.ut_type = UTMPX_AUTOFILL_MASK | USER_PROCESS;
1870
1871 gettimeofday(&ut.ut_tv, NULL);
1872
1873 plog(LLV_INFO, LOCATION, NULL,
1874 "Accounting : '%s' logging on '%s' from %s.\n",
1875 ut.ut_user, ut.ut_line, ut.ut_host);
1876
1877 if (pututxline(&ut) == NULL)
1878 return -1;
1879
1880 break;
1881 case ISAKMP_CFG_LOGOUT:
1882
1883 plog(LLV_INFO, LOCATION, NULL,
1884 "Accounting : '%s' unlogging from '%s'.\n",
1885 usr, term);
1886
1887 ut.ut_type = UTMPX_AUTOFILL_MASK | DEAD_PROCESS;
1888
1889 gettimeofday(&ut.ut_tv, NULL);
1890
1891 if (pututxline(&ut) == NULL)
1892 return -1;
1893
1894 break;
1895 default:
1896 plog(LLV_ERROR, LOCATION, NULL, "Unepected inout\n");
1897 break;
1898 }
1899
1900 return 0;
1901 }
1902
1903 int
1904 isakmp_cfg_getconfig(iph1)
1905 struct ph1handle *iph1;
1906 {
1907 vchar_t *buffer;
1908 struct isakmp_pl_attr *attrpl;
1909 struct isakmp_data *attr;
1910 size_t len;
1911 vchar_t *version = NULL;
1912 int error;
1913 int attrcount;
1914 int i;
1915 int attrlist[] = {
1916 INTERNAL_IP4_ADDRESS,
1917 INTERNAL_IP4_NETMASK,
1918 INTERNAL_IP4_DNS,
1919 INTERNAL_IP4_NBNS,
1920 INTERNAL_ADDRESS_EXPIRY,
1921 APPLICATION_VERSION,
1922 UNITY_BANNER,
1923 UNITY_DEF_DOMAIN,
1924 UNITY_SPLITDNS_NAME,
1925 UNITY_SPLIT_INCLUDE,
1926 UNITY_LOCAL_LAN,
1927 };
1928
1929 attrcount = sizeof(attrlist) / sizeof(*attrlist);
1930 len = sizeof(*attrpl) + sizeof(*attr) * attrcount;
1931
1932 if (iph1->started_by_api) {
1933 if (iph1->remote->ss_family == AF_INET) {
1934 struct vpnctl_socket_elem *sock_elem;
1935 struct bound_addr *bound_addr;
1936 u_int32_t address;
1937
1938 address = ((struct sockaddr_in *)iph1->remote)->sin_addr.s_addr;
1939 LIST_FOREACH(sock_elem, &lcconf->vpnctl_comm_socks, chain) {
1940 LIST_FOREACH(bound_addr, &sock_elem->bound_addresses, chain) {
1941 if (bound_addr->address == address) {
1942 if (version = bound_addr->version)
1943 len += bound_addr->version->l;
1944 break;
1945 }
1946 }
1947 }
1948 }
1949 }
1950
1951 if ((buffer = vmalloc(len)) == NULL) {
1952 plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
1953 return -1;
1954 }
1955
1956 attrpl = (struct isakmp_pl_attr *)buffer->v;
1957 attrpl->h.len = htons(len);
1958 attrpl->type = ISAKMP_CFG_REQUEST;
1959 attrpl->id = htons((u_int16_t)(eay_random() & 0xffff));
1960
1961 attr = (struct isakmp_data *)(attrpl + 1);
1962
1963 for (i = 0; i < attrcount; i++) {
1964 switch (attrlist[i]) {
1965 case APPLICATION_VERSION:
1966 if (version) {
1967 attr->type = htons(attrlist[i]);
1968 attr->lorv = htons(version->l);
1969 memcpy(attr + 1, version->v, version->l);
1970 attr = (struct isakmp_data *)(((char *)(attr + 1)) + version->l);
1971 break;
1972 } else /* fall thru */;
1973 default:
1974 attr->type = htons(attrlist[i]);
1975 attr->lorv = htons(0);
1976 attr++;
1977 break;
1978 }
1979 }
1980
1981 plog(LLV_DEBUG, LOCATION, NULL,
1982 "Sending MODE_CFG REQUEST\n");
1983
1984 error = isakmp_cfg_send(iph1, buffer,
1985 ISAKMP_NPTYPE_ATTR, ISAKMP_FLAG_E, 1, iph1->rmconf->retry_counter, NULL);
1986
1987 vfree(buffer);
1988
1989 IPSECLOGASLMSG("IPSec Network Configuration requested.\n");
1990
1991 return error;
1992 }
1993
1994 static void
1995 isakmp_cfg_getaddr4(attr, ip)
1996 struct isakmp_data *attr;
1997 struct in_addr *ip;
1998 {
1999 size_t alen = ntohs(attr->lorv);
2000 in_addr_t *addr;
2001
2002 if (alen != sizeof(*ip)) {
2003 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2004 return;
2005 }
2006
2007 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
2008 ip->s_addr = *addr;
2009
2010 return;
2011 }
2012
2013 static void
2014 isakmp_cfg_appendaddr4(attr, ip, num, max)
2015 struct isakmp_data *attr;
2016 struct in_addr *ip;
2017 int *num;
2018 int max;
2019 {
2020 size_t alen = ntohs(attr->lorv);
2021 in_addr_t *addr;
2022
2023 if (alen != sizeof(*ip)) {
2024 plog(LLV_ERROR, LOCATION, NULL, "Bad IPv4 address len\n");
2025 return;
2026 }
2027 if (*num == max) {
2028 plog(LLV_ERROR, LOCATION, NULL, "Too many addresses given\n");
2029 return;
2030 }
2031
2032 addr = ALIGNED_CAST(in_addr_t *)(attr + 1); // Wcast-align fix (void*) - attr comes from packet data in a vchar_t
2033 ip->s_addr = *addr;
2034 (*num)++;
2035
2036 return;
2037 }
2038
2039 static void
2040 isakmp_cfg_getstring(attr, str)
2041 struct isakmp_data *attr;
2042 char *str;
2043 {
2044 size_t alen = ntohs(attr->lorv);
2045 char *src;
2046 src = (char *)(attr + 1);
2047
2048 memcpy(str, src, (alen > MAXPATHLEN ? MAXPATHLEN : alen));
2049
2050 return;
2051 }
2052
2053 #define IP_MAX 40
2054
2055 void
2056 isakmp_cfg_iplist_to_str(dest, count, addr, withmask)
2057 char *dest;
2058 int count;
2059 void *addr;
2060 int withmask;
2061 {
2062 int i;
2063 int p;
2064 int l;
2065 struct unity_network tmp;
2066 for(i = 0, p = 0; i < count; i++) {
2067 if(withmask == 1)
2068 l = sizeof(struct unity_network);
2069 else
2070 l = sizeof(struct in_addr);
2071 memcpy(&tmp, addr, l);
2072 addr += l;
2073 if((uint32_t)tmp.addr4.s_addr == 0)
2074 break;
2075
2076 inet_ntop(AF_INET, &tmp.addr4, dest + p, IP_MAX);
2077 p += strlen(dest + p);
2078 if(withmask == 1) {
2079 dest[p] = '/';
2080 p++;
2081 inet_ntop(AF_INET, &tmp.mask4, dest + p, IP_MAX);
2082 p += strlen(dest + p);
2083 }
2084 dest[p] = ' ';
2085 p++;
2086 }
2087 if(p > 0)
2088 dest[p-1] = '\0';
2089 else
2090 dest[0] = '\0';
2091 }
2092
2093 int
2094 isakmp_cfg_setenv(iph1, envp, envc)
2095 struct ph1handle *iph1;
2096 char ***envp;
2097 int *envc;
2098 {
2099 char addrstr[IP_MAX];
2100 char addrlist[IP_MAX * MAXNS + MAXNS];
2101 char *splitlist = addrlist;
2102 char defdom[MAXPATHLEN + 1];
2103 int cidr, tmp;
2104 char cidrstr[4];
2105
2106 plog(LLV_DEBUG, LOCATION, NULL, "Starting a script.\n");
2107
2108 /*
2109 * Internal IPv4 address, either if
2110 * we are a client or a server.
2111 */
2112 if ((iph1->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) ||
2113 #ifdef HAVE_LIBLDAP
2114 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2115 #endif
2116 #ifdef HAVE_LIBRADIUS
2117 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_EXTERN) ||
2118 #endif
2119 (iph1->mode_cfg->flags & ISAKMP_CFG_ADDR4_LOCAL)) {
2120 inet_ntop(AF_INET, &iph1->mode_cfg->addr4,
2121 addrstr, IP_MAX);
2122 } else
2123 addrstr[0] = '\0';
2124
2125 if (script_env_append(envp, envc, "INTERNAL_ADDR4", addrstr) != 0) {
2126 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_ADDR4\n");
2127 return -1;
2128 }
2129
2130 if (iph1->mode_cfg->xauth.authdata.generic.usr != NULL) {
2131 if (script_env_append(envp, envc, "XAUTH_USER",
2132 iph1->mode_cfg->xauth.authdata.generic.usr) != 0) {
2133 plog(LLV_ERROR, LOCATION, NULL,
2134 "Cannot set XAUTH_USER\n");
2135 return -1;
2136 }
2137 }
2138
2139 /* Internal IPv4 mask */
2140 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_MASK4)
2141 inet_ntop(AF_INET, &iph1->mode_cfg->mask4,
2142 addrstr, IP_MAX);
2143 else
2144 addrstr[0] = '\0';
2145
2146 /*
2147 * During several releases, documentation adverised INTERNAL_NETMASK4
2148 * while code was using INTERNAL_MASK4. We now do both.
2149 */
2150
2151 if (script_env_append(envp, envc, "INTERNAL_MASK4", addrstr) != 0) {
2152 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_MASK4\n");
2153 return -1;
2154 }
2155
2156 if (script_env_append(envp, envc, "INTERNAL_NETMASK4", addrstr) != 0) {
2157 plog(LLV_ERROR, LOCATION, NULL,
2158 "Cannot set INTERNAL_NETMASK4\n");
2159 return -1;
2160 }
2161
2162 tmp = ntohl(iph1->mode_cfg->mask4.s_addr);
2163 for (cidr = 0; tmp != 0; cidr++)
2164 tmp <<= 1;
2165 snprintf(cidrstr, 3, "%d", cidr);
2166
2167 if (script_env_append(envp, envc, "INTERNAL_CIDR4", cidrstr) != 0) {
2168 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_CIDR4\n");
2169 return -1;
2170 }
2171
2172 /* Internal IPv4 DNS */
2173 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DNS4) {
2174 /* First Internal IPv4 DNS (for compatibilty with older code */
2175 inet_ntop(AF_INET, &iph1->mode_cfg->dns4[0],
2176 addrstr, IP_MAX);
2177
2178 /* Internal IPv4 DNS - all */
2179 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->dns4_index,
2180 (void *)iph1->mode_cfg->dns4, 0);
2181 } else {
2182 addrstr[0] = '\0';
2183 addrlist[0] = '\0';
2184 }
2185
2186 if (script_env_append(envp, envc, "INTERNAL_DNS4", addrstr) != 0) {
2187 plog(LLV_ERROR, LOCATION, NULL, "Cannot set INTERNAL_DNS4\n");
2188 return -1;
2189 }
2190 if (script_env_append(envp, envc, "INTERNAL_DNS4_LIST", addrlist) != 0) {
2191 plog(LLV_ERROR, LOCATION, NULL,
2192 "Cannot set INTERNAL_DNS4_LIST\n");
2193 return -1;
2194 }
2195
2196 /* Internal IPv4 WINS */
2197 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_WINS4) {
2198 /*
2199 * First Internal IPv4 WINS
2200 * (for compatibilty with older code
2201 */
2202 inet_ntop(AF_INET, &iph1->mode_cfg->wins4[0],
2203 addrstr, IP_MAX);
2204
2205 /* Internal IPv4 WINS - all */
2206 isakmp_cfg_iplist_to_str(addrlist, iph1->mode_cfg->wins4_index,
2207 (void *)iph1->mode_cfg->wins4, 0);
2208 } else {
2209 addrstr[0] = '\0';
2210 addrlist[0] = '\0';
2211 }
2212
2213 if (script_env_append(envp, envc, "INTERNAL_WINS4", addrstr) != 0) {
2214 plog(LLV_ERROR, LOCATION, NULL,
2215 "Cannot set INTERNAL_WINS4\n");
2216 return -1;
2217 }
2218 if (script_env_append(envp, envc,
2219 "INTERNAL_WINS4_LIST", addrlist) != 0) {
2220 plog(LLV_ERROR, LOCATION, NULL,
2221 "Cannot set INTERNAL_WINS4_LIST\n");
2222 return -1;
2223 }
2224
2225 /* Deault domain */
2226 if(iph1->mode_cfg->flags & ISAKMP_CFG_GOT_DEFAULT_DOMAIN)
2227 strlcpy(defdom,
2228 iph1->mode_cfg->default_domain,
2229 sizeof(defdom));
2230 else
2231 defdom[0] = '\0';
2232
2233 if (script_env_append(envp, envc, "DEFAULT_DOMAIN", defdom) != 0) {
2234 plog(LLV_ERROR, LOCATION, NULL,
2235 "Cannot set DEFAULT_DOMAIN\n");
2236 return -1;
2237 }
2238
2239 /* Split networks */
2240 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_INCLUDE)
2241 splitlist = splitnet_list_2str(iph1->mode_cfg->split_include);
2242 else {
2243 splitlist = addrlist;
2244 addrlist[0] = '\0';
2245 }
2246
2247 if (script_env_append(envp, envc, "SPLIT_INCLUDE", splitlist) != 0) {
2248 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_INCLUDE\n");
2249 return -1;
2250 }
2251 if (splitlist != addrlist)
2252 racoon_free(splitlist);
2253
2254 if (iph1->mode_cfg->flags & ISAKMP_CFG_GOT_SPLIT_LOCAL)
2255 splitlist = splitnet_list_2str(iph1->mode_cfg->split_local);
2256 else {
2257 splitlist = addrlist;
2258 addrlist[0] = '\0';
2259 }
2260
2261 if (script_env_append(envp, envc, "SPLIT_LOCAL", splitlist) != 0) {
2262 plog(LLV_ERROR, LOCATION, NULL, "Cannot set SPLIT_LOCAL\n");
2263 return -1;
2264 }
2265 if (splitlist != addrlist)
2266 racoon_free(splitlist);
2267
2268 return 0;
2269 }
2270
2271 int
2272 isakmp_cfg_resize_pool(size)
2273 int size;
2274 {
2275 struct isakmp_cfg_port *new_pool;
2276 size_t len;
2277 int i;
2278
2279 if (size == isakmp_cfg_config.pool_size)
2280 return 0;
2281
2282 plog(LLV_INFO, LOCATION, NULL,
2283 "Resize address pool from %zu to %d\n",
2284 isakmp_cfg_config.pool_size, size);
2285
2286 /* If a pool already exists, check if we can shrink it */
2287 if ((isakmp_cfg_config.port_pool != NULL) &&
2288 (size < isakmp_cfg_config.pool_size)) {
2289 for (i = isakmp_cfg_config.pool_size-1; i >= size; --i) {
2290 if (isakmp_cfg_config.port_pool[i].used) {
2291 plog(LLV_ERROR, LOCATION, NULL,
2292 "resize pool from %zu to %d impossible "
2293 "port %d is in use\n",
2294 isakmp_cfg_config.pool_size, size, i);
2295 size = i;
2296 break;
2297 }
2298 }
2299 }
2300
2301 len = size * sizeof(*isakmp_cfg_config.port_pool);
2302 new_pool = racoon_realloc(isakmp_cfg_config.port_pool, len);
2303 if (new_pool == NULL) {
2304 plog(LLV_ERROR, LOCATION, NULL,
2305 "resize pool from %zu to %d impossible: %s",
2306 isakmp_cfg_config.pool_size, size, strerror(errno));
2307 return -1;
2308 }
2309
2310 /* If size increase, intialize correctly the new records */
2311 if (size > isakmp_cfg_config.pool_size) {
2312 size_t unit;
2313 size_t old_size;
2314
2315 unit = sizeof(*isakmp_cfg_config.port_pool);
2316 old_size = isakmp_cfg_config.pool_size;
2317
2318 bzero((char *)new_pool + (old_size * unit),
2319 (size - old_size) * unit);
2320 }
2321
2322 isakmp_cfg_config.port_pool = new_pool;
2323 isakmp_cfg_config.pool_size = size;
2324
2325 return 0;
2326 }
2327
2328 int
2329 isakmp_cfg_init(cold)
2330 int cold;
2331 {
2332 int i;
2333 #if 0
2334 int error;
2335 #endif
2336
2337 isakmp_cfg_config.network4 = (in_addr_t)0x00000000;
2338 isakmp_cfg_config.netmask4 = (in_addr_t)0x00000000;
2339 for (i = 0; i < MAXNS; i++)
2340 isakmp_cfg_config.dns4[i] = (in_addr_t)0x00000000;
2341 isakmp_cfg_config.dns4_index = 0;
2342 for (i = 0; i < MAXWINS; i++)
2343 isakmp_cfg_config.nbns4[i] = (in_addr_t)0x00000000;
2344 isakmp_cfg_config.nbns4_index = 0;
2345 if (cold != ISAKMP_CFG_INIT_COLD) {
2346 if (isakmp_cfg_config.port_pool) {
2347 racoon_free(isakmp_cfg_config.port_pool);
2348 }
2349 }
2350 isakmp_cfg_config.port_pool = NULL;
2351 isakmp_cfg_config.pool_size = 0;
2352 isakmp_cfg_config.authsource = ISAKMP_CFG_AUTH_SYSTEM;
2353 isakmp_cfg_config.groupsource = ISAKMP_CFG_GROUP_SYSTEM;
2354 if (cold != ISAKMP_CFG_INIT_COLD) {
2355 if (isakmp_cfg_config.grouplist != NULL) {
2356 for (i = 0; i < isakmp_cfg_config.groupcount; i++)
2357 racoon_free(isakmp_cfg_config.grouplist[i]);
2358 racoon_free(isakmp_cfg_config.grouplist);
2359 }
2360 }
2361 isakmp_cfg_config.grouplist = NULL;
2362 isakmp_cfg_config.groupcount = 0;
2363 isakmp_cfg_config.confsource = ISAKMP_CFG_CONF_LOCAL;
2364 isakmp_cfg_config.accounting = ISAKMP_CFG_ACCT_NONE;
2365 isakmp_cfg_config.auth_throttle = THROTTLE_PENALTY;
2366 strlcpy(isakmp_cfg_config.default_domain, ISAKMP_CFG_DEFAULT_DOMAIN,
2367 sizeof(isakmp_cfg_config.default_domain));
2368 strlcpy(isakmp_cfg_config.motd, ISAKMP_CFG_MOTD, sizeof(isakmp_cfg_config.motd));
2369
2370 if (cold != ISAKMP_CFG_INIT_COLD )
2371 if (isakmp_cfg_config.splitnet_list != NULL)
2372 splitnet_list_free(isakmp_cfg_config.splitnet_list,
2373 &isakmp_cfg_config.splitnet_count);
2374 isakmp_cfg_config.splitnet_list = NULL;
2375 isakmp_cfg_config.splitnet_count = 0;
2376 isakmp_cfg_config.splitnet_type = 0;
2377
2378 isakmp_cfg_config.pfs_group = 0;
2379 isakmp_cfg_config.save_passwd = 0;
2380
2381 if (cold != ISAKMP_CFG_INIT_COLD )
2382 if (isakmp_cfg_config.splitdns_list != NULL)
2383 racoon_free(isakmp_cfg_config.splitdns_list);
2384 isakmp_cfg_config.splitdns_list = NULL;
2385 isakmp_cfg_config.splitdns_len = 0;
2386
2387 #if 0
2388 if (cold == ISAKMP_CFG_INIT_COLD) {
2389 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
2390 return error;
2391 }
2392 #endif
2393
2394 return 0;
2395 }
2396