1 /* $Id: isakmp_cfg.c,v 1.26.2.7 2006/01/07 23:50:42 manubsd Exp $ */
4 * Copyright (C) 2004-2006 Emmanuel Dreyfus
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37 #include <sys/queue.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
51 # include <sys/time.h>
63 #include <sys/utsname.h>
75 #include "isakmp_var.h"
80 #include "remoteconf.h"
81 #include "crypto_openssl.h"
82 #include "isakmp_inf.h"
83 #include "isakmp_xauth.h"
84 #include "isakmp_unity.h"
85 #include "isakmp_cfg.h"
90 struct isakmp_cfg_config isakmp_cfg_config
= {
91 0x00000000, /* network4 */
92 0x00000000, /* netmask4 */
93 0x00000000, /* dns4 */
94 0x00000000, /* nbns4 */
96 ISAKMP_CFG_AUTH_SYSTEM
, /* authsource */
97 ISAKMP_CFG_CONF_LOCAL
, /* confsource */
98 ISAKMP_CFG_ACCT_NONE
, /* accounting */
99 ISAKMP_CFG_MAX_CNX
, /* pool_size */
100 THROTTLE_PENALTY
, /* auth_throttle */
101 ISAKMP_CFG_MOTD
, /* motd */
106 static vchar_t
*buffer_cat(vchar_t
*s
, vchar_t
*append
);
107 static vchar_t
*isakmp_cfg_net(struct ph1handle
*, struct isakmp_data
*);
109 static vchar_t
*isakmp_cfg_void(struct ph1handle
*, struct isakmp_data
*);
111 static vchar_t
*isakmp_cfg_addr4(struct ph1handle
*,
112 struct isakmp_data
*, in_addr_t
*);
113 static void isakmp_cfg_getaddr4(struct isakmp_data
*, struct in_addr
*);
115 #define ISAKMP_CFG_LOGIN 1
116 #define ISAKMP_CFG_LOGOUT 2
117 static int isakmp_cfg_accounting(struct ph1handle
*, int);
118 #ifdef HAVE_LIBRADIUS
119 static int isakmp_cfg_accounting_radius(struct ph1handle
*, int);
123 * Handle an ISAKMP config mode packet
124 * We expect HDR, HASH, ATTR
127 isakmp_cfg_r(iph1
, msg
)
128 struct ph1handle
*iph1
;
131 struct isakmp
*packet
;
132 struct isakmp_gen
*ph
;
137 struct isakmp_ivm
*ivm
;
139 /* Check that the packet is long enough to have a header */
140 if (msg
->l
< sizeof(*packet
)) {
141 plog(LLV_ERROR
, LOCATION
, NULL
, "Unexpected short packet\n");
145 packet
= (struct isakmp
*)msg
->v
;
147 /* Is it encrypted? It should be encrypted */
148 if ((packet
->flags
& ISAKMP_FLAG_E
) == 0) {
149 plog(LLV_ERROR
, LOCATION
, NULL
,
150 "User credentials sent in cleartext!\n");
155 * Decrypt the packet. If this is the beginning of a new
156 * exchange, reinitialize the IV
158 if (iph1
->mode_cfg
->ivm
== NULL
)
159 iph1
->mode_cfg
->ivm
=
160 isakmp_cfg_newiv(iph1
, packet
->msgid
);
161 ivm
= iph1
->mode_cfg
->ivm
;
163 dmsg
= oakley_do_decrypt(iph1
, msg
, ivm
->iv
, ivm
->ive
);
165 plog(LLV_ERROR
, LOCATION
, NULL
,
166 "failed to decrypt message\n");
170 plog(LLV_DEBUG
, LOCATION
, NULL
, "MODE_CFG packet\n");
171 plogdump(LLV_DEBUG
, dmsg
->v
, dmsg
->l
);
173 /* Now work with the decrypted packet */
174 packet
= (struct isakmp
*)dmsg
->v
;
175 tlen
= dmsg
->l
- sizeof(*packet
);
176 ph
= (struct isakmp_gen
*)(packet
+ 1);
179 while ((tlen
> 0) && (np
!= ISAKMP_NPTYPE_NONE
)) {
180 /* Check that the payload header fits in the packet */
181 if (tlen
< sizeof(*ph
)) {
182 plog(LLV_WARNING
, LOCATION
, NULL
,
183 "Short payload header\n");
187 /* Check that the payload fits in the packet */
188 if (tlen
< ntohs(ph
->len
)) {
189 plog(LLV_WARNING
, LOCATION
, NULL
,
194 plog(LLV_DEBUG
, LOCATION
, NULL
, "Seen payload %d\n", np
);
195 plogdump(LLV_DEBUG
, ph
, ntohs(ph
->len
));
198 case ISAKMP_NPTYPE_HASH
: {
202 struct isakmp_gen
*nph
;
204 plen
= ntohs(ph
->len
);
205 nph
= (struct isakmp_gen
*)((char *)ph
+ plen
);
206 plen
= ntohs(nph
->len
);
208 if ((payload
= vmalloc(plen
)) == NULL
) {
209 plog(LLV_ERROR
, LOCATION
, NULL
,
210 "Cannot allocate memory\n");
213 memcpy(payload
->v
, nph
, plen
);
215 if ((check
= oakley_compute_hash1(iph1
,
216 packet
->msgid
, payload
)) == NULL
) {
217 plog(LLV_ERROR
, LOCATION
, NULL
,
218 "Cannot compute hash\n");
223 if (memcmp(ph
+ 1, check
->v
, check
->l
) != 0) {
224 plog(LLV_ERROR
, LOCATION
, NULL
,
225 "Hash verification failed\n");
234 case ISAKMP_NPTYPE_ATTR
: {
235 struct isakmp_pl_attr
*attrpl
;
237 attrpl
= (struct isakmp_pl_attr
*)ph
;
238 isakmp_cfg_attr_r(iph1
, packet
->msgid
, attrpl
);
243 plog(LLV_WARNING
, LOCATION
, NULL
,
244 "Unexpected next payload %d\n", np
);
245 /* Skip to the next payload */
249 /* Move to the next payload */
251 tlen
-= ntohs(ph
->len
);
253 ph
= (struct isakmp_gen
*)(npp
+ ntohs(ph
->len
));
261 isakmp_cfg_attr_r(iph1
, msgid
, attrpl
)
262 struct ph1handle
*iph1
;
264 struct isakmp_pl_attr
*attrpl
;
266 int type
= attrpl
->type
;
270 /* ignore, but this is the time to reinit the IV */
271 oakley_delivm(iph1
->mode_cfg
->ivm
);
272 iph1
->mode_cfg
->ivm
= NULL
;
276 case ISAKMP_CFG_REPLY
:
277 return isakmp_cfg_reply(iph1
, attrpl
);
280 case ISAKMP_CFG_REQUEST
:
282 return isakmp_cfg_request(iph1
, attrpl
);
287 return isakmp_cfg_set(iph1
, attrpl
);
291 plog(LLV_WARNING
, LOCATION
, NULL
,
292 "Unepected configuration exchange type %d\n", type
);
301 isakmp_cfg_reply(iph1
, attrpl
)
302 struct ph1handle
*iph1
;
303 struct isakmp_pl_attr
*attrpl
;
305 struct isakmp_data
*attr
;
310 struct sockaddr_in
*sin
;
312 tlen
= ntohs(attrpl
->h
.len
);
313 attr
= (struct isakmp_data
*)(attrpl
+ 1);
314 tlen
-= sizeof(*attrpl
);
317 type
= ntohs(attr
->type
);
319 /* Handle short attributes */
320 if ((type
& ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
321 type
&= ~ISAKMP_GEN_MASK
;
323 plog(LLV_DEBUG
, LOCATION
, NULL
,
324 "Short attribute %d = %d\n",
325 type
, ntohs(attr
->lorv
));
329 xauth_attr_reply(iph1
, attr
, ntohs(attrpl
->id
));
333 plog(LLV_WARNING
, LOCATION
, NULL
,
334 "Ignored short attribute %d\n", type
);
338 tlen
-= sizeof(*attr
);
343 type
= ntohs(attr
->type
);
344 alen
= ntohs(attr
->lorv
);
346 /* Check that the attribute fit in the packet */
348 plog(LLV_ERROR
, LOCATION
, NULL
,
349 "Short attribute %d\n", type
);
353 plog(LLV_DEBUG
, LOCATION
, NULL
,
354 "Attribute %d, len %zu\n", type
, alen
);
358 case XAUTH_USER_NAME
:
359 case XAUTH_USER_PASSWORD
:
362 case XAUTH_CHALLENGE
:
367 xauth_attr_reply(iph1
, attr
, ntohs(attrpl
->id
));
369 case INTERNAL_IP4_ADDRESS
:
370 isakmp_cfg_getaddr4(attr
, &iph1
->mode_cfg
->addr4
);
371 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_ADDR4
;
373 case INTERNAL_IP4_NETMASK
:
374 isakmp_cfg_getaddr4(attr
, &iph1
->mode_cfg
->mask4
);
375 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_MASK4
;
377 case INTERNAL_IP4_DNS
:
378 isakmp_cfg_getaddr4(attr
, &iph1
->mode_cfg
->dns4
);
379 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_DNS4
;
381 case INTERNAL_IP4_NBNS
:
382 isakmp_cfg_getaddr4(attr
, &iph1
->mode_cfg
->wins4
);
383 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_GOT_WINS4
;
385 case INTERNAL_IP4_SUBNET
:
386 case INTERNAL_ADDRESS_EXPIRY
:
388 case UNITY_SAVE_PASSWD
:
389 case UNITY_DEF_DOMAIN
:
390 case UNITY_SPLITDNS_NAME
:
391 case UNITY_SPLIT_INCLUDE
:
392 case UNITY_NATT_PORT
:
395 case UNITY_BACKUP_SERVERS
:
396 case UNITY_DDNS_HOSTNAME
:
398 plog(LLV_WARNING
, LOCATION
, NULL
,
399 "Ignored attribute %d\n", type
);
404 attr
= (struct isakmp_data
*)(npp
+ sizeof(*attr
) + alen
);
405 tlen
-= (sizeof(*attr
) + alen
);
409 * Call the SA up script hook now that we have the configuration
410 * It is done at the end of phase 1 if ISAKMP mode config is not
413 if ((iph1
->status
== PHASE1ST_ESTABLISHED
) &&
414 iph1
->rmconf
->mode_cfg
)
415 script_hook(iph1
, SCRIPT_PHASE1_UP
);
417 #ifdef ENABLE_ADMINPORT
421 alen
= ntohs(attrpl
->h
.len
) - sizeof(*attrpl
);
422 if ((buf
= vmalloc(alen
)) == NULL
) {
423 plog(LLV_WARNING
, LOCATION
, NULL
,
424 "Cannot allocate memory: %s\n", strerror(errno
));
426 memcpy(buf
->v
, attrpl
+ 1, buf
->l
);
427 EVT_PUSH(iph1
->local
, iph1
->remote
,
428 EVTT_ISAKMP_CFG_DONE
, buf
);
438 isakmp_cfg_request(iph1
, attrpl
)
439 struct ph1handle
*iph1
;
440 struct isakmp_pl_attr
*attrpl
;
442 struct isakmp_data
*attr
;
447 struct isakmp_pl_attr
*reply
;
452 if ((payload
= vmalloc(sizeof(*reply
))) == NULL
) {
453 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
456 memset(payload
->v
, 0, sizeof(*reply
));
458 tlen
= ntohs(attrpl
->h
.len
);
459 attr
= (struct isakmp_data
*)(attrpl
+ 1);
460 tlen
-= sizeof(*attrpl
);
464 type
= ntohs(attr
->type
);
466 /* Handle short attributes */
467 if ((type
& ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
468 type
&= ~ISAKMP_GEN_MASK
;
470 plog(LLV_DEBUG
, LOCATION
, NULL
,
471 "Short attribute %d = %d\n",
472 type
, ntohs(attr
->lorv
));
476 reply_attr
= isakmp_xauth_req(iph1
, attr
);
479 plog(LLV_WARNING
, LOCATION
, NULL
,
480 "Ignored short attribute %d\n", type
);
484 tlen
-= sizeof(*attr
);
487 if (reply_attr
!= NULL
) {
488 payload
= buffer_cat(payload
, reply_attr
);
495 type
= ntohs(attr
->type
);
496 alen
= ntohs(attr
->lorv
);
498 /* Check that the attribute fit in the packet */
500 plog(LLV_ERROR
, LOCATION
, NULL
,
501 "Short attribute %d\n", type
);
505 plog(LLV_DEBUG
, LOCATION
, NULL
,
506 "Attribute %d, len %zu\n", type
, alen
);
509 case INTERNAL_IP4_ADDRESS
:
510 case INTERNAL_IP4_NETMASK
:
511 case INTERNAL_IP4_DNS
:
512 case INTERNAL_IP4_NBNS
:
513 case INTERNAL_IP4_SUBNET
:
514 reply_attr
= isakmp_cfg_net(iph1
, attr
);
518 case XAUTH_USER_NAME
:
519 case XAUTH_USER_PASSWORD
:
522 case XAUTH_CHALLENGE
:
527 reply_attr
= isakmp_xauth_req(iph1
, attr
);
530 case APPLICATION_VERSION
:
531 reply_attr
= isakmp_cfg_string(iph1
,
532 attr
, ISAKMP_CFG_RACOON_VERSION
);
537 case UNITY_SAVE_PASSWD
:
538 case UNITY_DEF_DOMAIN
:
539 case UNITY_DDNS_HOSTNAME
:
541 case UNITY_SPLITDNS_NAME
:
542 case UNITY_SPLIT_INCLUDE
:
543 case UNITY_NATT_PORT
:
544 case UNITY_BACKUP_SERVERS
:
545 reply_attr
= isakmp_unity_req(iph1
, attr
);
548 case INTERNAL_ADDRESS_EXPIRY
:
550 plog(LLV_WARNING
, LOCATION
, NULL
,
551 "Ignored attribute %d\n", type
);
556 attr
= (struct isakmp_data
*)(npp
+ sizeof(*attr
) + alen
);
557 tlen
-= (sizeof(*attr
) + alen
);
559 if (reply_attr
!= NULL
) {
560 payload
= buffer_cat(payload
, reply_attr
);
566 reply
= (struct isakmp_pl_attr
*)payload
->v
;
567 reply
->h
.len
= htons(payload
->l
);
568 reply
->type
= ISAKMP_CFG_REPLY
;
569 reply
->id
= attrpl
->id
;
571 error
= isakmp_cfg_send(iph1
, payload
,
572 ISAKMP_NPTYPE_ATTR
, ISAKMP_FLAG_E
, 0);
575 oakley_delivm(iph1
->mode_cfg
->ivm
);
576 iph1
->mode_cfg
->ivm
= NULL
;
584 isakmp_cfg_set(iph1
, attrpl
)
585 struct ph1handle
*iph1
;
586 struct isakmp_pl_attr
*attrpl
;
588 struct isakmp_data
*attr
;
593 struct isakmp_pl_attr
*reply
;
598 if ((payload
= vmalloc(sizeof(*reply
))) == NULL
) {
599 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
602 memset(payload
->v
, 0, sizeof(*reply
));
604 tlen
= ntohs(attrpl
->h
.len
);
605 attr
= (struct isakmp_data
*)(attrpl
+ 1);
606 tlen
-= sizeof(*attrpl
);
609 * We should send ack for the attributes we accepted
613 type
= ntohs(attr
->type
);
615 switch (type
& ~ISAKMP_GEN_MASK
) {
617 reply_attr
= isakmp_xauth_set(iph1
, attr
);
620 plog(LLV_DEBUG
, LOCATION
, NULL
,
621 "Unexpected SET attribute %d\n",
622 type
& ~ISAKMP_GEN_MASK
);
626 if ((reply_attr
= vmalloc(sizeof(*reply_attr
))) != NULL
) {
627 payload
= buffer_cat(payload
, reply_attr
);
632 * Move to next attribute. If we run out of the packet,
633 * tlen becomes negative and we exit.
635 if ((type
& ISAKMP_GEN_MASK
) == ISAKMP_GEN_TV
) {
636 tlen
-= sizeof(*attr
);
639 alen
= ntohs(attr
->lorv
);
640 tlen
-= (sizeof(*attr
) + alen
);
642 attr
= (struct isakmp_data
*)
643 (npp
+ sizeof(*attr
) + alen
);
647 reply
= (struct isakmp_pl_attr
*)payload
->v
;
648 reply
->h
.len
= htons(payload
->l
);
649 reply
->type
= ISAKMP_CFG_ACK
;
650 reply
->id
= attrpl
->id
;
652 error
= isakmp_cfg_send(iph1
, payload
,
653 ISAKMP_NPTYPE_ATTR
, ISAKMP_FLAG_E
, 0);
655 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_DELETE_PH1
) {
656 if (iph1
->status
== PHASE1ST_ESTABLISHED
)
657 isakmp_info_send_d1(iph1
);
665 * If required, request ISAKMP mode config information
667 if ((iph1
->rmconf
->mode_cfg
) && (error
== 0))
668 error
= isakmp_cfg_getconfig(iph1
);
675 buffer_cat(s
, append
)
681 new = vmalloc(s
->l
+ append
->l
);
683 plog(LLV_ERROR
, LOCATION
, NULL
,
684 "Cannot allocate memory\n");
688 memcpy(new->v
, s
->v
, s
->l
);
689 memcpy(new->v
+ s
->l
, append
->v
, append
->l
);
696 isakmp_cfg_net(iph1
, attr
)
697 struct ph1handle
*iph1
;
698 struct isakmp_data
*attr
;
703 type
= ntohs(attr
->type
);
706 * Don't give an address to a peer that did not succeed Xauth
708 if (xauth_check(iph1
) != 0) {
709 plog(LLV_ERROR
, LOCATION
, NULL
,
710 "Attempt to start phase config whereas Xauth failed\n");
715 case INTERNAL_IP4_ADDRESS
:
716 switch(isakmp_cfg_config
.confsource
) {
717 #ifdef HAVE_LIBRADIUS
718 case ISAKMP_CFG_CONF_RADIUS
:
719 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_ADDR4_RADIUS
)
720 && (iph1
->mode_cfg
->addr4
.s_addr
!= htonl(-2)))
722 * -2 is 255.255.255.254, RADIUS uses that
723 * to instruct the NAS to use a local pool
726 plog(LLV_INFO
, LOCATION
, NULL
,
727 "No IP from RADIUS, using local pool\n");
730 case ISAKMP_CFG_CONF_LOCAL
:
731 if (isakmp_cfg_getport(iph1
) == -1) {
732 plog(LLV_ERROR
, LOCATION
, NULL
,
733 "Port pool depleted\n");
737 iph1
->mode_cfg
->addr4
.s_addr
=
738 htonl(ntohl(isakmp_cfg_config
.network4
)
739 + iph1
->mode_cfg
->port
);
740 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_ADDR4_LOCAL
;
744 plog(LLV_ERROR
, LOCATION
, NULL
,
745 "Unexpected confsource\n");
748 if (isakmp_cfg_accounting(iph1
, ISAKMP_CFG_LOGIN
) != 0)
749 plog(LLV_ERROR
, LOCATION
, NULL
, "Accounting failed\n");
751 return isakmp_cfg_addr4(iph1
,
752 attr
, &iph1
->mode_cfg
->addr4
.s_addr
);
755 case INTERNAL_IP4_NETMASK
:
756 switch(isakmp_cfg_config
.confsource
) {
757 #ifdef HAVE_LIBRADIUS
758 case ISAKMP_CFG_CONF_RADIUS
:
759 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_MASK4_RADIUS
)
761 plog(LLV_INFO
, LOCATION
, NULL
,
762 "No mask from RADIUS, using local pool\n");
765 case ISAKMP_CFG_CONF_LOCAL
:
766 iph1
->mode_cfg
->mask4
.s_addr
767 = isakmp_cfg_config
.netmask4
;
768 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_MASK4_LOCAL
;
772 plog(LLV_ERROR
, LOCATION
, NULL
,
773 "Unexpected confsource\n");
775 return isakmp_cfg_addr4(iph1
, attr
,
776 &iph1
->mode_cfg
->mask4
.s_addr
);
779 case INTERNAL_IP4_DNS
:
780 return isakmp_cfg_addr4(iph1
,
781 attr
, &isakmp_cfg_config
.dns4
);
784 case INTERNAL_IP4_NBNS
:
785 return isakmp_cfg_addr4(iph1
,
786 attr
, &isakmp_cfg_config
.nbns4
);
789 case INTERNAL_IP4_SUBNET
:
790 return isakmp_cfg_addr4(iph1
,
791 attr
, &isakmp_cfg_config
.network4
);
795 plog(LLV_ERROR
, LOCATION
, NULL
, "Unexpected type %d\n", type
);
804 isakmp_cfg_void(iph1
, attr
)
805 struct ph1handle
*iph1
;
806 struct isakmp_data
*attr
;
809 struct isakmp_data
*new;
811 if ((buffer
= vmalloc(sizeof(*attr
))) == NULL
) {
812 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
816 new = (struct isakmp_data
*)buffer
->v
;
818 new->type
= attr
->type
;
819 new->lorv
= htons(0);
826 isakmp_cfg_copy(iph1
, attr
)
827 struct ph1handle
*iph1
;
828 struct isakmp_data
*attr
;
833 if ((ntohs(attr
->type
) & ISAKMP_GEN_MASK
) == ISAKMP_GEN_TLV
)
834 len
= ntohs(attr
->lorv
);
836 if ((buffer
= vmalloc(sizeof(*attr
) + len
)) == NULL
) {
837 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
841 memcpy(buffer
->v
, attr
, sizeof(*attr
) + ntohs(attr
->lorv
));
847 isakmp_cfg_short(iph1
, attr
, value
)
848 struct ph1handle
*iph1
;
849 struct isakmp_data
*attr
;
853 struct isakmp_data
*new;
856 if ((buffer
= vmalloc(sizeof(*attr
))) == NULL
) {
857 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
861 new = (struct isakmp_data
*)buffer
->v
;
862 type
= ntohs(attr
->type
) & ~ISAKMP_GEN_MASK
;
864 new->type
= htons(type
| ISAKMP_GEN_TV
);
865 new->lorv
= htons(value
);
871 isakmp_cfg_string(iph1
, attr
, string
)
872 struct ph1handle
*iph1
;
873 struct isakmp_data
*attr
;
877 struct isakmp_data
*new;
881 len
= strlen(string
);
882 if ((buffer
= vmalloc(sizeof(*attr
) + len
)) == NULL
) {
883 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
887 new = (struct isakmp_data
*)buffer
->v
;
889 new->type
= attr
->type
;
890 new->lorv
= htons(len
);
891 data
= (char *)(new + 1);
893 memcpy(data
, string
, len
);
899 isakmp_cfg_addr4(iph1
, attr
, addr
)
900 struct ph1handle
*iph1
;
901 struct isakmp_data
*attr
;
905 struct isakmp_data
*new;
909 if ((buffer
= vmalloc(sizeof(*attr
) + len
)) == NULL
) {
910 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
914 new = (struct isakmp_data
*)buffer
->v
;
916 new->type
= attr
->type
;
917 new->lorv
= htons(len
);
918 memcpy(new + 1, addr
, len
);
924 isakmp_cfg_newiv(iph1
, msgid
)
925 struct ph1handle
*iph1
;
928 struct isakmp_cfg_state
*ics
= iph1
->mode_cfg
;
931 plog(LLV_ERROR
, LOCATION
, NULL
,
932 "isakmp_cfg_newiv called without mode config state\n");
936 if (ics
->ivm
!= NULL
)
937 oakley_delivm(ics
->ivm
);
939 ics
->ivm
= oakley_newiv2(iph1
, msgid
);
944 /* Derived from isakmp_info_send_common */
946 isakmp_cfg_send(iph1
, payload
, np
, flags
, new_exchange
)
947 struct ph1handle
*iph1
;
953 struct ph2handle
*iph2
= NULL
;
954 vchar_t
*hash
= NULL
;
955 struct isakmp
*isakmp
;
956 struct isakmp_gen
*gen
;
960 struct isakmp_cfg_state
*ics
= iph1
->mode_cfg
;
962 /* Check if phase 1 is established */
963 if ((iph1
->status
!= PHASE1ST_ESTABLISHED
) ||
964 (iph1
->local
== NULL
) ||
965 (iph1
->remote
== NULL
)) {
966 plog(LLV_ERROR
, LOCATION
, NULL
,
967 "ISAKMP mode config exchange with immature phase 1\n");
971 /* add new entry to isakmp status table */
976 iph2
->dst
= dupsaddr(iph1
->remote
);
977 iph2
->src
= dupsaddr(iph1
->local
);
978 switch (iph1
->remote
->sa_family
) {
981 ((struct sockaddr_in
*)iph2
->dst
)->sin_port
= 0;
982 ((struct sockaddr_in
*)iph2
->src
)->sin_port
= 0;
987 ((struct sockaddr_in6
*)iph2
->dst
)->sin6_port
= 0;
988 ((struct sockaddr_in6
*)iph2
->src
)->sin6_port
= 0;
992 plog(LLV_ERROR
, LOCATION
, NULL
,
993 "invalid family: %d\n", iph1
->remote
->sa_family
);
998 iph2
->side
= INITIATOR
;
999 iph2
->status
= PHASE2ST_START
;
1002 iph2
->msgid
= isakmp_newmsgid2(iph1
);
1004 iph2
->msgid
= iph1
->msgid
;
1006 /* get IV and HASH(1) if skeyid_a was generated. */
1007 if (iph1
->skeyid_a
!= NULL
) {
1009 if (isakmp_cfg_newiv(iph1
, iph2
->msgid
) == NULL
) {
1015 /* generate HASH(1) */
1016 hash
= oakley_compute_hash1(iph2
->ph1
, iph2
->msgid
, payload
);
1022 /* initialized total buffer length */
1024 tlen
+= sizeof(*gen
);
1026 /* IKE-SA is not established */
1029 /* initialized total buffer length */
1032 if ((flags
& ISAKMP_FLAG_A
) == 0)
1033 iph2
->flags
= (hash
== NULL
? 0 : ISAKMP_FLAG_E
);
1035 iph2
->flags
= (hash
== NULL
? 0 : ISAKMP_FLAG_A
);
1038 bindph12(iph1
, iph2
);
1040 tlen
+= sizeof(*isakmp
) + payload
->l
;
1042 /* create buffer for isakmp payload */
1043 iph2
->sendbuf
= vmalloc(tlen
);
1044 if (iph2
->sendbuf
== NULL
) {
1045 plog(LLV_ERROR
, LOCATION
, NULL
,
1046 "failed to get buffer to send.\n");
1050 /* create isakmp header */
1051 isakmp
= (struct isakmp
*)iph2
->sendbuf
->v
;
1052 memcpy(&isakmp
->i_ck
, &iph1
->index
.i_ck
, sizeof(cookie_t
));
1053 memcpy(&isakmp
->r_ck
, &iph1
->index
.r_ck
, sizeof(cookie_t
));
1054 isakmp
->np
= hash
== NULL
? (np
& 0xff) : ISAKMP_NPTYPE_HASH
;
1055 isakmp
->v
= iph1
->version
;
1056 isakmp
->etype
= ISAKMP_ETYPE_CFG
;
1057 isakmp
->flags
= iph2
->flags
;
1058 memcpy(&isakmp
->msgid
, &iph2
->msgid
, sizeof(isakmp
->msgid
));
1059 isakmp
->len
= htonl(tlen
);
1060 p
= (char *)(isakmp
+ 1);
1062 /* create HASH payload */
1064 gen
= (struct isakmp_gen
*)p
;
1065 gen
->np
= np
& 0xff;
1066 gen
->len
= htons(sizeof(*gen
) + hash
->l
);
1068 memcpy(p
, hash
->v
, hash
->l
);
1073 memcpy(p
, payload
->v
, payload
->l
);
1076 #ifdef HAVE_PRINT_ISAKMP_C
1077 isakmp_printpacket(iph2
->sendbuf
, iph1
->local
, iph1
->remote
, 1);
1081 if (ISSET(isakmp
->flags
, ISAKMP_FLAG_E
)) {
1084 tmp
= oakley_do_encrypt(iph2
->ph1
, iph2
->sendbuf
,
1085 ics
->ivm
->ive
, ics
->ivm
->iv
);
1086 VPTRINIT(iph2
->sendbuf
);
1089 iph2
->sendbuf
= tmp
;
1092 /* HDR*, HASH(1), ATTR */
1093 if (isakmp_send(iph2
->ph1
, iph2
->sendbuf
) < 0) {
1094 VPTRINIT(iph2
->sendbuf
);
1098 plog(LLV_DEBUG
, LOCATION
, NULL
,
1099 "sendto mode config %s.\n", s_isakmp_nptype(np
));
1102 * XXX We might need to resend the message...
1106 VPTRINIT(iph2
->sendbuf
);
1109 if (iph2
->sendbuf
!= NULL
)
1110 vfree(iph2
->sendbuf
);
1123 isakmp_cfg_rmstate(iph1
)
1124 struct ph1handle
*iph1
;
1126 struct isakmp_cfg_state
*state
= iph1
->mode_cfg
;
1128 if (isakmp_cfg_accounting(iph1
, ISAKMP_CFG_LOGOUT
) != 0)
1129 plog(LLV_ERROR
, LOCATION
, NULL
, "Accounting failed\n");
1131 if (state
->flags
& ISAKMP_CFG_PORT_ALLOCATED
)
1132 isakmp_cfg_putport(iph1
, state
->port
);
1134 xauth_rmstate(&state
->xauth
);
1137 iph1
->mode_cfg
= NULL
;
1142 struct isakmp_cfg_state
*
1143 isakmp_cfg_mkstate(void)
1145 struct isakmp_cfg_state
*state
;
1147 if ((state
= racoon_malloc(sizeof(*state
))) == NULL
) {
1148 plog(LLV_ERROR
, LOCATION
, NULL
,
1149 "Cannot allocate memory for mode config state\n");
1152 memset(state
, 0, sizeof(*state
));
1158 isakmp_cfg_getport(iph1
)
1159 struct ph1handle
*iph1
;
1162 size_t size
= isakmp_cfg_config
.pool_size
;
1164 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_PORT_ALLOCATED
)
1165 return iph1
->mode_cfg
->port
;
1167 if (isakmp_cfg_config
.port_pool
== NULL
) {
1168 plog(LLV_ERROR
, LOCATION
, NULL
,
1169 "isakmp_cfg_config.port_pool == NULL\n");
1173 for (i
= 0; i
< size
; i
++) {
1174 if (isakmp_cfg_config
.port_pool
[i
].used
== 0)
1179 plog(LLV_ERROR
, LOCATION
, NULL
,
1180 "No more addresses available\n");
1184 isakmp_cfg_config
.port_pool
[i
].used
= 1;
1186 plog(LLV_INFO
, LOCATION
, NULL
, "Using port %d\n", i
);
1188 iph1
->mode_cfg
->flags
|= ISAKMP_CFG_PORT_ALLOCATED
;
1189 iph1
->mode_cfg
->port
= i
;
1195 isakmp_cfg_putport(iph1
, index
)
1196 struct ph1handle
*iph1
;
1199 if (isakmp_cfg_config
.port_pool
== NULL
) {
1200 plog(LLV_ERROR
, LOCATION
, NULL
,
1201 "isakmp_cfg_config.port_pool == NULL\n");
1205 if (isakmp_cfg_config
.port_pool
[index
].used
== 0) {
1206 plog(LLV_ERROR
, LOCATION
, NULL
,
1207 "Attempt to release an unallocated address (port %d)\n",
1213 /* Cleanup PAM status associated with the port */
1214 if (isakmp_cfg_config
.authsource
== ISAKMP_CFG_AUTH_PAM
)
1215 privsep_cleanup_pam(index
);
1217 isakmp_cfg_config
.port_pool
[index
].used
= 0;
1218 iph1
->mode_cfg
->flags
&= ISAKMP_CFG_PORT_ALLOCATED
;
1220 plog(LLV_INFO
, LOCATION
, NULL
, "Released port %d\n", index
);
1230 if (isakmp_cfg_config
.port_pool
[port
].pam
!= NULL
) {
1231 pam_end(isakmp_cfg_config
.port_pool
[port
].pam
, PAM_SUCCESS
);
1232 isakmp_cfg_config
.port_pool
[port
].pam
= NULL
;
1239 /* Accounting, only for RADIUS or PAM */
1241 isakmp_cfg_accounting(iph1
, inout
)
1242 struct ph1handle
*iph1
;
1246 if (isakmp_cfg_config
.accounting
== ISAKMP_CFG_ACCT_PAM
)
1247 return privsep_accounting_pam(iph1
->mode_cfg
->port
,
1250 #ifdef HAVE_LIBRADIUS
1251 if (isakmp_cfg_config
.accounting
== ISAKMP_CFG_ACCT_RADIUS
)
1252 return isakmp_cfg_accounting_radius(iph1
, inout
);
1259 isakmp_cfg_accounting_pam(port
, inout
)
1266 if (isakmp_cfg_config
.port_pool
== NULL
) {
1267 plog(LLV_ERROR
, LOCATION
, NULL
,
1268 "isakmp_cfg_config.port_pool == NULL\n");
1272 pam
= isakmp_cfg_config
.port_pool
[port
].pam
;
1274 plog(LLV_ERROR
, LOCATION
, NULL
, "pam handle is NULL\n");
1279 case ISAKMP_CFG_LOGIN
:
1280 error
= pam_open_session(pam
, 0);
1282 case ISAKMP_CFG_LOGOUT
:
1283 error
= pam_close_session(pam
, 0);
1284 pam_end(pam
, error
);
1285 isakmp_cfg_config
.port_pool
[port
].pam
= NULL
;
1288 plog(LLV_ERROR
, LOCATION
, NULL
, "Unepected inout\n");
1293 plog(LLV_ERROR
, LOCATION
, NULL
,
1294 "pam_open_session/pam_close_session failed: %s\n",
1295 pam_strerror(pam
, error
));
1301 #endif /* HAVE_LIBPAM */
1303 #ifdef HAVE_LIBRADIUS
1305 isakmp_cfg_accounting_radius(iph1
, inout
)
1306 struct ph1handle
*iph1
;
1309 /* For first time use, initialize Radius */
1310 if (radius_acct_state
== NULL
) {
1311 if ((radius_acct_state
= rad_acct_open()) == NULL
) {
1312 plog(LLV_ERROR
, LOCATION
, NULL
,
1313 "Cannot init librradius\n");
1317 if (rad_config(radius_acct_state
, NULL
) != 0) {
1318 plog(LLV_ERROR
, LOCATION
, NULL
,
1319 "Cannot open librarius config file: %s\n",
1320 rad_strerror(radius_acct_state
));
1321 rad_close(radius_acct_state
);
1322 radius_acct_state
= NULL
;
1327 if (rad_create_request(radius_acct_state
,
1328 RAD_ACCOUNTING_REQUEST
) != 0) {
1329 plog(LLV_ERROR
, LOCATION
, NULL
,
1330 "rad_create_request failed: %s\n",
1331 rad_strerror(radius_acct_state
));
1335 if (rad_put_string(radius_acct_state
, RAD_USER_NAME
,
1336 iph1
->mode_cfg
->login
) != 0) {
1337 plog(LLV_ERROR
, LOCATION
, NULL
,
1338 "rad_put_string failed: %s\n",
1339 rad_strerror(radius_acct_state
));
1344 case ISAKMP_CFG_LOGIN
:
1347 case ISAKMP_CFG_LOGOUT
:
1351 plog(LLV_ERROR
, LOCATION
, NULL
, "Unepected inout\n");
1355 if (rad_put_addr(radius_acct_state
,
1356 RAD_FRAMED_IP_ADDRESS
, iph1
->mode_cfg
->addr4
) != 0) {
1357 plog(LLV_ERROR
, LOCATION
, NULL
,
1358 "rad_put_addr failed: %s\n",
1359 rad_strerror(radius_acct_state
));
1363 if (rad_put_addr(radius_acct_state
,
1364 RAD_LOGIN_IP_HOST
, iph1
->mode_cfg
->addr4
) != 0) {
1365 plog(LLV_ERROR
, LOCATION
, NULL
,
1366 "rad_put_addr failed: %s\n",
1367 rad_strerror(radius_acct_state
));
1371 if (rad_put_int(radius_acct_state
, RAD_ACCT_STATUS_TYPE
, inout
) != 0) {
1372 plog(LLV_ERROR
, LOCATION
, NULL
,
1373 "rad_put_int failed: %s\n",
1374 rad_strerror(radius_acct_state
));
1378 if (isakmp_cfg_radius_common(radius_acct_state
,
1379 iph1
->mode_cfg
->port
) != 0)
1382 if (rad_send_request(radius_acct_state
) != RAD_ACCOUNTING_RESPONSE
) {
1383 plog(LLV_ERROR
, LOCATION
, NULL
,
1384 "rad_send_request failed: %s\n",
1385 rad_strerror(radius_acct_state
));
1391 #endif /* HAVE_LIBRADIUS */
1394 * Attributes common to all RADIUS requests
1396 #ifdef HAVE_LIBRADIUS
1398 isakmp_cfg_radius_common(radius_state
, port
)
1399 struct rad_handle
*radius_state
;
1402 struct utsname name
;
1403 static struct hostent
*host
= NULL
;
1404 struct in_addr nas_addr
;
1407 * Find our own IP by resolving our nodename
1410 if (uname(&name
) != 0) {
1411 plog(LLV_ERROR
, LOCATION
, NULL
,
1412 "uname failed: %s\n", strerror(errno
));
1416 if ((host
= gethostbyname(name
.nodename
)) == NULL
) {
1417 plog(LLV_ERROR
, LOCATION
, NULL
,
1418 "gethostbyname failed: %s\n", strerror(errno
));
1423 memcpy(&nas_addr
, host
->h_addr
, sizeof(nas_addr
));
1424 if (rad_put_addr(radius_state
, RAD_NAS_IP_ADDRESS
, nas_addr
) != 0) {
1425 plog(LLV_ERROR
, LOCATION
, NULL
,
1426 "rad_put_addr failed: %s\n",
1427 rad_strerror(radius_state
));
1431 if (rad_put_int(radius_state
, RAD_NAS_PORT
, port
) != 0) {
1432 plog(LLV_ERROR
, LOCATION
, NULL
,
1433 "rad_put_int failed: %s\n",
1434 rad_strerror(radius_state
));
1438 if (rad_put_int(radius_state
, RAD_NAS_PORT_TYPE
, RAD_VIRTUAL
) != 0) {
1439 plog(LLV_ERROR
, LOCATION
, NULL
,
1440 "rad_put_int failed: %s\n",
1441 rad_strerror(radius_state
));
1445 if (rad_put_int(radius_state
, RAD_SERVICE_TYPE
, RAD_FRAMED
) != 0) {
1446 plog(LLV_ERROR
, LOCATION
, NULL
,
1447 "rad_put_int failed: %s\n",
1448 rad_strerror(radius_state
));
1457 isakmp_cfg_getconfig(iph1
)
1458 struct ph1handle
*iph1
;
1461 struct isakmp_pl_attr
*attrpl
;
1462 struct isakmp_data
*attr
;
1468 INTERNAL_IP4_ADDRESS
,
1469 INTERNAL_IP4_NETMASK
,
1473 APPLICATION_VERSION
,
1476 attrcount
= sizeof(attrlist
) / sizeof(*attrlist
);
1477 len
= sizeof(*attrpl
) + sizeof(*attr
) * attrcount
;
1479 if ((buffer
= vmalloc(len
)) == NULL
) {
1480 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot allocate memory\n");
1484 attrpl
= (struct isakmp_pl_attr
*)buffer
->v
;
1485 attrpl
->h
.len
= htons(len
);
1486 attrpl
->type
= ISAKMP_CFG_REQUEST
;
1487 attrpl
->id
= htons((u_int16_t
)(eay_random() & 0xffff));
1489 attr
= (struct isakmp_data
*)(attrpl
+ 1);
1491 for (i
= 0; i
< attrcount
; i
++) {
1492 attr
->type
= htons(attrlist
[i
]);
1493 attr
->lorv
= htons(0);
1497 error
= isakmp_cfg_send(iph1
, buffer
,
1498 ISAKMP_NPTYPE_ATTR
, ISAKMP_FLAG_E
, 1);
1506 isakmp_cfg_getaddr4(attr
, ip
)
1507 struct isakmp_data
*attr
;
1510 size_t alen
= ntohs(attr
->lorv
);
1513 if (alen
!= sizeof(*ip
)) {
1514 plog(LLV_ERROR
, LOCATION
, NULL
, "Bad IPv4 address len\n");
1518 addr
= (in_addr_t
*)(attr
+ 1);
1525 isakmp_cfg_setenv(iph1
, envp
, envc
)
1526 struct ph1handle
*iph1
;
1531 char addrstr
[IP_MAX
];
1534 * Internal IPv4 address, either if
1535 * we are a client or a server.
1537 if ((iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_ADDR4
) ||
1538 #ifdef HAVE_LIBRADIUS
1539 (iph1
->mode_cfg
->flags
& ISAKMP_CFG_ADDR4_RADIUS
) ||
1541 (iph1
->mode_cfg
->flags
& ISAKMP_CFG_ADDR4_LOCAL
)) {
1542 inet_ntop(AF_INET
, &iph1
->mode_cfg
->addr4
,
1547 if (script_env_append(envp
, envc
, "INTERNAL_ADDR4", addrstr
) != 0) {
1548 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot set INTERNAL_ADDR4\n");
1552 /* Internal IPv4 mask */
1553 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_MASK4
)
1554 inet_ntop(AF_INET
, &iph1
->mode_cfg
->mask4
,
1560 * During several releases, documentation adverised INTERNAL_NETMASK4
1561 * while code was using INTERNAL_MASK4. We now do both.
1563 if (script_env_append(envp
, envc
, "INTERNAL_MASK4", addrstr
) != 0) {
1564 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot set INTERNAL_MASK4\n");
1568 if (script_env_append(envp
, envc
, "INTERNAL_NETMASK4", addrstr
) != 0) {
1569 plog(LLV_ERROR
, LOCATION
, NULL
,
1570 "Cannot set INTERNAL_NETMASK4\n");
1575 /* Internal IPv4 DNS */
1576 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_DNS4
)
1577 inet_ntop(AF_INET
, &iph1
->mode_cfg
->dns4
,
1582 if (script_env_append(envp
, envc
, "INTERNAL_DNS4", addrstr
) != 0) {
1583 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot set INTERNAL_DNS4\n");
1587 /* Internal IPv4 WINS */
1588 if (iph1
->mode_cfg
->flags
& ISAKMP_CFG_GOT_WINS4
)
1589 inet_ntop(AF_INET
, &iph1
->mode_cfg
->wins4
,
1594 if (script_env_append(envp
, envc
, "INTERNAL_WINS4", addrstr
) != 0) {
1595 plog(LLV_ERROR
, LOCATION
, NULL
, "Cannot set INTERNAL_WINS4\n");