]>
git.saurik.com Git - apple/network_cmds.git/blob - racoon.tproj/admin.c
1 /* $KAME: admin.c,v 1.23 2001/06/01 10:12:55 sakane Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
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
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
35 #include <sys/signal.h>
38 #include <net/pfkeyv2.h>
39 #include <netkey/key_var.h>
41 #include <netinet/in.h>
60 #include "localconf.h"
61 #include "remoteconf.h"
62 #include "grabmyaddr.h"
63 #include "isakmp_var.h"
69 #include "admin_var.h"
73 static struct sockaddr_un sunaddr
;
74 static int admin_process
__P((int, char *));
75 static int admin_reply
__P((int, struct admin_com
*, vchar_t
*));
81 struct sockaddr_storage from
;
82 int fromlen
= sizeof(from
);
88 so2
= accept(lcconf
->sock_admin
, (struct sockaddr
*)&from
, &fromlen
);
90 plog(LLV_ERROR
, LOCATION
, NULL
,
91 "failed to accept admin command: %s\n",
96 /* get buffer length */
97 while ((len
= recv(so2
, (char *)&com
, sizeof(com
), MSG_PEEK
)) < 0) {
100 plog(LLV_ERROR
, LOCATION
, NULL
,
101 "failed to recv admin command: %s\n",
107 if (len
< sizeof(com
)) {
108 plog(LLV_ERROR
, LOCATION
, NULL
,
109 "invalid header length of admin command\n");
113 /* get buffer to receive */
114 if ((combuf
= racoon_malloc(com
.ac_len
)) == 0) {
115 plog(LLV_ERROR
, LOCATION
, NULL
,
116 "failed to alloc buffer for admin command\n");
121 while ((len
= recv(so2
, combuf
, com
.ac_len
, 0)) < 0) {
124 plog(LLV_ERROR
, LOCATION
, NULL
,
125 "failed to recv admin command: %s\n",
130 /* don't fork() because of reloading config. */
131 if (com
.ac_cmd
== ADMIN_RELOAD_CONF
) {
132 /* reload does not work at all! */
133 signal_handler(SIGHUP
);
137 /* fork for processing */
139 if ((pid
= fork()) < 0) {
140 plog(LLV_ERROR
, LOCATION
, NULL
,
141 "failed to fork for admin processing: %s\n",
146 /* parant's process. */
152 /* child's process */
156 /* exit in this function. */
157 error
= admin_process(so2
, combuf
);
164 /* exit if child's process. */
165 if (pid
== 0 && !f_foreground
)
172 * main child's process.
175 admin_process(so2
, combuf
)
179 struct admin_com
*com
= (struct admin_com
*)combuf
;
185 switch (com
->ac_cmd
) {
186 case ADMIN_RELOAD_CONF
:
187 /* don't entered because of proccessing it in other place. */
188 plog(LLV_ERROR
, LOCATION
, NULL
, "should never reach here\n");
191 case ADMIN_SHOW_SCHED
:
195 if (sched_dump(&p
, &len
) == -1)
200 memcpy(buf
->v
, p
, len
);
206 switch (com
->ac_proto
) {
207 case ADMIN_PROTO_ISAKMP
:
208 switch (com
->ac_cmd
) {
219 case ADMIN_PROTO_IPSEC
:
221 case ADMIN_PROTO_ESP
:
222 switch (com
->ac_cmd
) {
226 p
= admin2pfkey_proto(com
->ac_proto
);
229 buf
= pfkey_dump_sadb(p
);
235 pfkey_flush_sadb(com
->ac_proto
);
240 case ADMIN_PROTO_INTERNAL
:
241 switch (com
->ac_cmd
) {
243 buf
= NULL
; /*XXX dumpph2(&error);*/
245 com
->ac_errno
= error
;
261 case ADMIN_DELETE_SA
:
264 case ADMIN_ESTABLISH_SA
:
266 struct sockaddr
*dst
;
267 struct sockaddr
*src
;
268 src
= (struct sockaddr
*)
269 &((struct admin_com_indexes
*)
270 ((caddr_t
)com
+ sizeof(*com
)))->src
;
271 dst
= (struct sockaddr
*)
272 &((struct admin_com_indexes
*)
273 ((caddr_t
)com
+ sizeof(*com
)))->dst
;
275 switch (com
->ac_proto
) {
276 case ADMIN_PROTO_ISAKMP
:
278 struct remoteconf
*rmconf
;
279 struct sockaddr
*remote
;
280 struct sockaddr
*local
;
282 /* search appropreate configuration */
283 rmconf
= getrmconf(dst
);
284 if (rmconf
== NULL
) {
285 plog(LLV_ERROR
, LOCATION
, NULL
,
286 "no configuration found "
287 "for %s\n", saddrwop2str(dst
));
292 /* get remote IP address and port number. */
293 remote
= dupsaddr(dst
);
294 if (remote
== NULL
) {
298 switch (remote
->sa_family
) {
300 ((struct sockaddr_in
*)remote
)->sin_port
=
301 ((struct sockaddr_in
*)rmconf
->remote
)->sin_port
;
305 ((struct sockaddr_in6
*)remote
)->sin6_port
=
306 ((struct sockaddr_in6
*)rmconf
->remote
)->sin6_port
;
310 plog(LLV_ERROR
, LOCATION
, NULL
,
311 "invalid family: %d\n",
317 /* get local address */
318 local
= dupsaddr(src
);
323 switch (local
->sa_family
) {
325 ((struct sockaddr_in
*)local
)->sin_port
=
326 getmyaddrsport(local
);
330 ((struct sockaddr_in6
*)local
)->sin6_port
=
331 getmyaddrsport(local
);
335 plog(LLV_ERROR
, LOCATION
, NULL
,
336 "invalid family: %d\n",
343 plog(LLV_INFO
, LOCATION
, NULL
,
344 "accept a request to establish IKE-SA: "
345 "%s\n", saddrwop2str(remote
));
347 /* begin ident mode */
348 if (isakmp_ph1begin_i(rmconf
, remote
) < 0) {
355 case ADMIN_PROTO_ESP
:
365 plog(LLV_ERROR
, LOCATION
, NULL
,
366 "invalid command: %d\n", com
->ac_cmd
);
370 if (admin_reply(so2
, com
, buf
) < 0)
385 admin_reply(so
, combuf
, buf
)
387 struct admin_com
*combuf
;
394 tlen
= sizeof(*combuf
) + buf
->l
;
396 tlen
= sizeof(*combuf
);
398 retbuf
= racoon_calloc(1, tlen
);
399 if (retbuf
== NULL
) {
400 plog(LLV_ERROR
, LOCATION
, NULL
,
401 "failed to allocate admin buffer\n");
405 memcpy(retbuf
, combuf
, sizeof(*combuf
));
406 ((struct admin_com
*)retbuf
)->ac_len
= tlen
;
409 memcpy(retbuf
+ sizeof(*combuf
), buf
->v
, buf
->l
);
411 tlen
= send(so
, retbuf
, tlen
, 0);
414 plog(LLV_ERROR
, LOCATION
, NULL
,
415 "failed to send admin command: %s\n",
423 /* ADMIN_PROTO -> SADB_SATYPE */
425 admin2pfkey_proto(proto
)
429 case ADMIN_PROTO_IPSEC
:
430 return SADB_SATYPE_UNSPEC
;
432 return SADB_SATYPE_AH
;
433 case ADMIN_PROTO_ESP
:
434 return SADB_SATYPE_ESP
;
436 plog(LLV_ERROR
, LOCATION
, NULL
,
437 "unsupported proto for admin: %d\n", proto
);
446 memset(&sunaddr
, 0, sizeof(sunaddr
));
447 sunaddr
.sun_family
= AF_UNIX
;
448 snprintf(sunaddr
.sun_path
, sizeof(sunaddr
.sun_path
),
451 lcconf
->sock_admin
= socket(AF_UNIX
, SOCK_STREAM
, 0);
452 if (lcconf
->sock_admin
< 0) {
453 plog(LLV_ERROR
, LOCATION
, NULL
,
454 "socket: %s\n", strerror(errno
));
458 if (bind(lcconf
->sock_admin
, (struct sockaddr
*)&sunaddr
,
459 sizeof(sunaddr
)) < 0) {
460 plog(LLV_ERROR
, LOCATION
, NULL
,
461 "bind(sockname:%s): %s\n",
462 sunaddr
.sun_path
, strerror(errno
));
463 (void)close(lcconf
->sock_admin
);
467 if (listen(lcconf
->sock_admin
, 5) < 0) {
468 plog(LLV_ERROR
, LOCATION
, NULL
,
469 "listen(sockname:%s): %s\n",
470 sunaddr
.sun_path
, strerror(errno
));
471 (void)close(lcconf
->sock_admin
);
474 plog(LLV_DEBUG
, LOCATION
, NULL
,
475 "open %s as racoon management.\n", sunaddr
.sun_path
);
483 close(lcconf
->sock_admin
);
484 unlink(sunaddr
.sun_path
);