1 /* $NetBSD: admin.c,v 1.17.6.1 2007/08/01 11:52:19 vanhu Exp $ */
3 /* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/signal.h>
44 #include <System/net/pfkeyv2.h>
46 #include <net/pfkeyv2.h>
49 #include <netinet/in.h>
50 #ifndef HAVE_NETINET6_IPSEC
51 #include <netinet/ipsec.h>
53 #include <netinet6/ipsec.h>
77 #include "localconf.h"
78 #include "remoteconf.h"
79 #include "grabmyaddr.h"
80 #include "isakmp_var.h"
86 #include "ipsec_doi.h"
88 #include "admin_var.h"
89 #include "isakmp_inf.h"
91 #include "isakmp_cfg.h"
97 #ifdef ENABLE_ADMINPORT
98 char *adminsock_path
= ADMINSOCK_PATH
;
99 uid_t adminsock_owner
= 0;
100 gid_t adminsock_group
= 0;
101 mode_t adminsock_mode
= 0600;
103 static struct sockaddr_un sunaddr
;
104 static int admin_process
__P((int, char *));
105 static int admin_reply
__P((int, struct admin_com
*, vchar_t
*));
111 struct sockaddr_storage from
;
112 socklen_t fromlen
= sizeof(from
);
113 struct admin_com com
;
117 so2
= accept(lcconf
->sock_admin
, (struct sockaddr
*)&from
, &fromlen
);
119 plog(LLV_ERROR
, LOCATION
, NULL
,
120 "failed to accept admin command: %s\n",
125 /* get buffer length */
126 while ((len
= recv(so2
, (char *)&com
, sizeof(com
), MSG_PEEK
)) < 0) {
129 plog(LLV_ERROR
, LOCATION
, NULL
,
130 "failed to recv admin command: %s\n",
136 if (len
< sizeof(com
)) {
137 plog(LLV_ERROR
, LOCATION
, NULL
,
138 "invalid header length of admin command\n");
142 /* get buffer to receive */
143 if ((combuf
= racoon_malloc(com
.ac_len
)) == 0) {
144 plog(LLV_ERROR
, LOCATION
, NULL
,
145 "failed to alloc buffer for admin command\n");
150 while ((len
= recv(so2
, combuf
, com
.ac_len
, 0)) < 0) {
153 plog(LLV_ERROR
, LOCATION
, NULL
,
154 "failed to recv admin command: %s\n",
159 if (com
.ac_cmd
== ADMIN_RELOAD_CONF
) {
160 /* reload does not work at all! */
161 signal_handler(SIGUSR1
);
165 error
= admin_process(so2
, combuf
);
176 * main child's process.
179 admin_process(so2
, combuf
)
183 struct admin_com
*com
= (struct admin_com
*)combuf
;
192 switch (com
->ac_cmd
) {
193 case ADMIN_RELOAD_CONF
:
194 /* don't entered because of proccessing it in other place. */
195 plog(LLV_ERROR
, LOCATION
, NULL
, "should never reach here\n");
198 case ADMIN_SHOW_SCHED
:
205 if (sched_dump(&p
, &len
) == -1)
208 if ((buf
= vmalloc(len
)) == NULL
)
211 memcpy(buf
->v
, p
, len
);
220 /* It's not really an error, don't force racoonctl to quit */
221 if ((buf
= evt_dump()) == NULL
)
228 switch (com
->ac_proto
) {
229 case ADMIN_PROTO_ISAKMP
:
230 switch (com
->ac_cmd
) {
241 case ADMIN_PROTO_IPSEC
:
243 case ADMIN_PROTO_ESP
:
244 switch (com
->ac_cmd
) {
248 p
= admin2pfkey_proto(com
->ac_proto
);
251 buf
= pfkey_dump_sadb(p
);
257 pfkey_flush_sadb(com
->ac_proto
);
262 case ADMIN_PROTO_INTERNAL
:
263 switch (com
->ac_cmd
) {
265 buf
= NULL
; /*XXX dumpph2(&error);*/
267 com
->ac_errno
= error
;
270 /*XXX flushph2(false);*/
283 case ADMIN_DELETE_SA
: {
284 struct ph1handle
*iph1
;
285 struct sockaddr
*dst
;
286 struct sockaddr
*src
;
289 src
= (struct sockaddr
*)
290 &((struct admin_com_indexes
*)
291 ((caddr_t
)com
+ sizeof(*com
)))->src
;
292 dst
= (struct sockaddr
*)
293 &((struct admin_com_indexes
*)
294 ((caddr_t
)com
+ sizeof(*com
)))->dst
;
296 loc
= racoon_strdup(saddrwop2str(src
));
297 rem
= racoon_strdup(saddrwop2str(dst
));
301 if ((iph1
= getph1byaddrwop(src
, dst
)) == NULL
) {
302 plog(LLV_ERROR
, LOCATION
, NULL
,
303 "phase 1 for %s -> %s not found\n", loc
, rem
);
305 if (iph1
->status
== PHASE1ST_ESTABLISHED
)
306 isakmp_info_send_d1(iph1
);
317 case ADMIN_LOGOUT_USER
: {
318 struct ph1handle
*iph1
;
322 if (com
->ac_len
> sizeof(com
) + LOGINLEN
+ 1) {
323 plog(LLV_ERROR
, LOCATION
, NULL
,
324 "malformed message (login too long)\n");
328 user
= (char *)(com
+ 1);
329 found
= purgeph1bylogin(user
);
330 plog(LLV_INFO
, LOCATION
, NULL
,
331 "deleted %d SA for user \"%s\"\n", found
, user
);
337 case ADMIN_DELETE_ALL_SA_DST
: {
338 struct ph1handle
*iph1
;
339 struct sockaddr
*dst
;
342 dst
= (struct sockaddr
*)
343 &((struct admin_com_indexes
*)
344 ((caddr_t
)com
+ sizeof(*com
)))->dst
;
346 rem
= racoon_strdup(saddrwop2str(dst
));
349 plog(LLV_INFO
, LOCATION
, NULL
,
350 "Flushing all SAs for peer %s\n", rem
);
352 while ((iph1
= getph1bydstaddrwop(dst
)) != NULL
) {
353 loc
= racoon_strdup(saddrwop2str(iph1
->local
));
356 if (iph1
->status
== PHASE1ST_ESTABLISHED
)
357 isakmp_info_send_d1(iph1
);
369 case ADMIN_ESTABLISH_SA_VPNCONTROL
:
371 struct admin_com_psk
*acp
;
373 struct sockaddr
*dst
;
374 struct bound_addr
*target
;
378 acp
= (struct admin_com_psk
*)
379 ((char *)com
+ sizeof(*com
) +
380 sizeof(struct admin_com_indexes
));
382 target
= (struct bound_addr
*)racoon_malloc(sizeof(struct bound_addr
));
383 if (target
== NULL
) {
384 plog(LLV_ERROR
, LOCATION
, NULL
,
385 "cannot allocate memory: %s\n",
390 if ((id
= vmalloc(acp
->id_len
)) == NULL
) {
391 plog(LLV_ERROR
, LOCATION
, NULL
,
392 "cannot allocate memory: %s\n",
396 data
= (char *)(acp
+ 1);
397 memcpy(id
->v
, data
, id
->l
);
399 if ((key
= vmalloc(acp
->key_len
)) == NULL
) {
400 plog(LLV_ERROR
, LOCATION
, NULL
,
401 "cannot allocate memory: %s\n",
407 data
= (char *)(data
+ acp
->id_len
);
408 memcpy(key
->v
, data
, key
->l
);
410 dst
= (struct sockaddr
*)
411 &((struct admin_com_indexes
*)
412 ((caddr_t
)com
+ sizeof(*com
)))->dst
;
415 target
->address
= ((struct sockaddr_in
*)dst
)->sin_addr
.s_addr
;
418 /* Set the id and key */
421 target
->user_id
= id
;
422 target
->user_pw
= key
;
428 if (target
->user_id
!= NULL
)
429 vfree(target
->user_id
);
430 if (target
->user_pw
!= NULL
)
431 vfree(target
->user_pw
);
437 case ADMIN_ESTABLISH_SA_PSK
: {
438 struct admin_com_psk
*acp
;
441 com
->ac_cmd
= ADMIN_ESTABLISH_SA
;
443 acp
= (struct admin_com_psk
*)
444 ((char *)com
+ sizeof(*com
) +
445 sizeof(struct admin_com_indexes
));
447 idtype
= acp
->id_type
;
449 if ((id
= vmalloc(acp
->id_len
)) == NULL
) {
450 plog(LLV_ERROR
, LOCATION
, NULL
,
451 "cannot allocate memory: %s\n",
455 data
= (char *)(acp
+ 1);
456 memcpy(id
->v
, data
, id
->l
);
458 if ((key
= vmalloc(acp
->key_len
)) == NULL
) {
459 plog(LLV_ERROR
, LOCATION
, NULL
,
460 "cannot allocate memory: %s\n",
466 data
= (char *)(data
+ acp
->id_len
);
467 memcpy(key
->v
, data
, key
->l
);
470 case ADMIN_ESTABLISH_SA
:
472 struct sockaddr
*dst
;
473 struct sockaddr
*src
;
474 src
= (struct sockaddr
*)
475 &((struct admin_com_indexes
*)
476 ((caddr_t
)com
+ sizeof(*com
)))->src
;
477 dst
= (struct sockaddr
*)
478 &((struct admin_com_indexes
*)
479 ((caddr_t
)com
+ sizeof(*com
)))->dst
;
481 switch (com
->ac_proto
) {
482 case ADMIN_PROTO_ISAKMP
: {
483 struct remoteconf
*rmconf
;
484 struct sockaddr
*remote
= NULL
;
485 struct sockaddr
*local
= NULL
;
490 /* search appropreate configuration */
491 rmconf
= getrmconf(dst
);
492 if (rmconf
== NULL
) {
493 plog(LLV_ERROR
, LOCATION
, NULL
,
494 "no configuration found "
495 "for %s\n", saddrwop2str(dst
));
499 /* get remote IP address and port number. */
500 if ((remote
= dupsaddr(dst
)) == NULL
)
503 switch (remote
->sa_family
) {
505 ((struct sockaddr_in
*)remote
)->sin_port
=
506 ((struct sockaddr_in
*)rmconf
->remote
)->sin_port
;
510 ((struct sockaddr_in6
*)remote
)->sin6_port
=
511 ((struct sockaddr_in6
*)rmconf
->remote
)->sin6_port
;
515 plog(LLV_ERROR
, LOCATION
, NULL
,
516 "invalid family: %d\n",
522 // port = extract_port(rmconf->remote);
523 // if (set_port(remote, port) == NULL)
526 /* get local address */
527 if ((local
= dupsaddr(src
)) == NULL
)
530 port
= ntohs(getmyaddrsport(local
));
531 if (set_port(local
, port
) == NULL
)
535 /* Set the id and key */
537 if (xauth_rmconf_used(&rmconf
->xauth
) == -1)
540 if (rmconf
->xauth
->login
!= NULL
) {
541 vfree(rmconf
->xauth
->login
);
542 rmconf
->xauth
->login
= NULL
;
544 if (rmconf
->xauth
->pass
!= NULL
) {
545 vfree(rmconf
->xauth
->pass
);
546 rmconf
->xauth
->pass
= NULL
;
549 rmconf
->xauth
->login
= id
;
550 rmconf
->xauth
->pass
= key
;
554 plog(LLV_INFO
, LOCATION
, NULL
,
555 "accept a request to establish IKE-SA: "
556 "%s\n", saddrwop2str(remote
));
558 /* begin ident mode */
559 if (isakmp_ph1begin_i(rmconf
, remote
, local
, 0) < 0)
571 case ADMIN_PROTO_ESP
:
581 plog(LLV_ERROR
, LOCATION
, NULL
,
582 "invalid command: %d\n", com
->ac_cmd
);
586 if ((error
= admin_reply(so2
, com
, buf
)) != 0)
598 admin_reply(so
, combuf
, buf
)
600 struct admin_com
*combuf
;
607 tlen
= sizeof(*combuf
) + buf
->l
;
609 tlen
= sizeof(*combuf
);
611 retbuf
= racoon_calloc(1, tlen
);
612 if (retbuf
== NULL
) {
613 plog(LLV_ERROR
, LOCATION
, NULL
,
614 "failed to allocate admin buffer\n");
618 memcpy(retbuf
, combuf
, sizeof(*combuf
));
619 ((struct admin_com
*)retbuf
)->ac_len
= tlen
;
622 memcpy(retbuf
+ sizeof(*combuf
), buf
->v
, buf
->l
);
624 tlen
= send(so
, retbuf
, tlen
, 0);
627 plog(LLV_ERROR
, LOCATION
, NULL
,
628 "failed to send admin command: %s\n",
636 /* ADMIN_PROTO -> SADB_SATYPE */
638 admin2pfkey_proto(proto
)
642 case ADMIN_PROTO_IPSEC
:
643 return SADB_SATYPE_UNSPEC
;
645 return SADB_SATYPE_AH
;
646 case ADMIN_PROTO_ESP
:
647 return SADB_SATYPE_ESP
;
649 plog(LLV_ERROR
, LOCATION
, NULL
,
650 "unsupported proto for admin: %d\n", proto
);
659 if (adminsock_path
== NULL
) {
660 lcconf
->sock_admin
= -1;
664 memset(&sunaddr
, 0, sizeof(sunaddr
));
665 sunaddr
.sun_family
= AF_UNIX
;
666 snprintf(sunaddr
.sun_path
, sizeof(sunaddr
.sun_path
),
667 "%s", adminsock_path
);
669 lcconf
->sock_admin
= socket(AF_UNIX
, SOCK_STREAM
, 0);
670 if (lcconf
->sock_admin
== -1) {
671 plog(LLV_ERROR
, LOCATION
, NULL
,
672 "socket: %s\n", strerror(errno
));
676 unlink(sunaddr
.sun_path
);
677 if (bind(lcconf
->sock_admin
, (struct sockaddr
*)&sunaddr
,
678 sizeof(sunaddr
)) != 0) {
679 plog(LLV_ERROR
, LOCATION
, NULL
,
680 "bind(sockname:%s): %s\n",
681 sunaddr
.sun_path
, strerror(errno
));
682 (void)close(lcconf
->sock_admin
);
686 if (chown(sunaddr
.sun_path
, adminsock_owner
, adminsock_group
) != 0) {
687 plog(LLV_ERROR
, LOCATION
, NULL
,
688 "chown(%s, %d, %d): %s\n",
689 sunaddr
.sun_path
, adminsock_owner
,
690 adminsock_group
, strerror(errno
));
691 (void)close(lcconf
->sock_admin
);
695 if (chmod(sunaddr
.sun_path
, adminsock_mode
) != 0) {
696 plog(LLV_ERROR
, LOCATION
, NULL
,
697 "chmod(%s, 0%03o): %s\n",
698 sunaddr
.sun_path
, adminsock_mode
, strerror(errno
));
699 (void)close(lcconf
->sock_admin
);
703 if (listen(lcconf
->sock_admin
, 5) != 0) {
704 plog(LLV_ERROR
, LOCATION
, NULL
,
705 "listen(sockname:%s): %s\n",
706 sunaddr
.sun_path
, strerror(errno
));
707 (void)close(lcconf
->sock_admin
);
710 plog(LLV_DEBUG
, LOCATION
, NULL
,
711 "open %s as racoon management.\n", sunaddr
.sun_path
);
719 close(lcconf
->sock_admin
);