PageRenderTime 52ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/netbsd/src/crypto/dist/ipsec-tools/src/racoon/admin.c

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C | 763 lines | 606 code | 105 blank | 52 comment | 118 complexity | 39d5764eaec0dee2b3684c1338833294 MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /* $NetBSD: admin.c,v 1.38 2010/12/08 07:38:35 tteras Exp $ */
  2. /* Id: admin.c,v 1.25 2006/04/06 14:31:04 manubsd Exp */
  3. /*
  4. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  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.
  18. *
  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
  29. * SUCH DAMAGE.
  30. */
  31. #include "config.h"
  32. #include <sys/types.h>
  33. #include <sys/param.h>
  34. #include <sys/socket.h>
  35. #include <sys/signal.h>
  36. #include <sys/stat.h>
  37. #include <sys/un.h>
  38. #include <net/pfkeyv2.h>
  39. #include <netinet/in.h>
  40. #include PATH_IPSEC_H
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <errno.h>
  45. #include <netdb.h>
  46. #ifdef HAVE_UNISTD_H
  47. #include <unistd.h>
  48. #endif
  49. #ifdef ENABLE_HYBRID
  50. #include <resolv.h>
  51. #endif
  52. #include "var.h"
  53. #include "misc.h"
  54. #include "vmbuf.h"
  55. #include "plog.h"
  56. #include "sockmisc.h"
  57. #include "debug.h"
  58. #include "schedule.h"
  59. #include "localconf.h"
  60. #include "remoteconf.h"
  61. #include "grabmyaddr.h"
  62. #include "isakmp_var.h"
  63. #include "isakmp.h"
  64. #include "oakley.h"
  65. #include "handler.h"
  66. #include "evt.h"
  67. #include "pfkey.h"
  68. #include "ipsec_doi.h"
  69. #include "policy.h"
  70. #include "admin.h"
  71. #include "admin_var.h"
  72. #include "isakmp_inf.h"
  73. #ifdef ENABLE_HYBRID
  74. #include "isakmp_cfg.h"
  75. #endif
  76. #include "session.h"
  77. #include "gcmalloc.h"
  78. #ifdef ENABLE_ADMINPORT
  79. char *adminsock_path = ADMINSOCK_PATH;
  80. uid_t adminsock_owner = 0;
  81. gid_t adminsock_group = 0;
  82. mode_t adminsock_mode = 0600;
  83. static struct sockaddr_un sunaddr;
  84. static int admin_process __P((int, char *));
  85. static int admin_reply __P((int, struct admin_com *, int, vchar_t *));
  86. static int
  87. admin_handler(ctx, fd)
  88. void *ctx;
  89. int fd;
  90. {
  91. int so2;
  92. struct sockaddr_storage from;
  93. socklen_t fromlen = sizeof(from);
  94. struct admin_com com;
  95. char *combuf = NULL;
  96. int len, error = -1;
  97. so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen);
  98. if (so2 < 0) {
  99. plog(LLV_ERROR, LOCATION, NULL,
  100. "failed to accept admin command: %s\n",
  101. strerror(errno));
  102. return -1;
  103. }
  104. close_on_exec(so2);
  105. /* get buffer length */
  106. while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) {
  107. if (errno == EINTR)
  108. continue;
  109. plog(LLV_ERROR, LOCATION, NULL,
  110. "failed to recv admin command: %s\n",
  111. strerror(errno));
  112. goto end;
  113. }
  114. /* sanity check */
  115. if (len < sizeof(com)) {
  116. plog(LLV_ERROR, LOCATION, NULL,
  117. "invalid header length of admin command\n");
  118. goto end;
  119. }
  120. /* get buffer to receive */
  121. if ((combuf = racoon_malloc(com.ac_len)) == 0) {
  122. plog(LLV_ERROR, LOCATION, NULL,
  123. "failed to alloc buffer for admin command\n");
  124. goto end;
  125. }
  126. /* get real data */
  127. while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) {
  128. if (errno == EINTR)
  129. continue;
  130. plog(LLV_ERROR, LOCATION, NULL,
  131. "failed to recv admin command: %s\n",
  132. strerror(errno));
  133. goto end;
  134. }
  135. error = admin_process(so2, combuf);
  136. end:
  137. if (error == -2) {
  138. plog(LLV_DEBUG, LOCATION, NULL,
  139. "[%d] admin connection established\n", so2);
  140. } else {
  141. (void)close(so2);
  142. }
  143. if (combuf)
  144. racoon_free(combuf);
  145. return error;
  146. }
  147. static int admin_ph1_delete_sa(struct ph1handle *iph1, void *arg)
  148. {
  149. if (iph1->status >= PHASE1ST_ESTABLISHED)
  150. isakmp_info_send_d1(iph1);
  151. purge_remote(iph1);
  152. return 0;
  153. }
  154. /*
  155. * main child's process.
  156. */
  157. static int
  158. admin_process(so2, combuf)
  159. int so2;
  160. char *combuf;
  161. {
  162. struct admin_com *com = (struct admin_com *)combuf;
  163. vchar_t *buf = NULL;
  164. vchar_t *id = NULL;
  165. vchar_t *key = NULL;
  166. int idtype = 0;
  167. int error = 0, l_ac_errno = 0;
  168. struct evt_listener_list *event_list = NULL;
  169. if (com->ac_cmd & ADMIN_FLAG_VERSION)
  170. com->ac_cmd &= ~ADMIN_FLAG_VERSION;
  171. else
  172. com->ac_version = 0;
  173. switch (com->ac_cmd) {
  174. case ADMIN_RELOAD_CONF:
  175. signal_handler(SIGHUP);
  176. break;
  177. case ADMIN_SHOW_SCHED: {
  178. caddr_t p = NULL;
  179. int len;
  180. if (sched_dump(&p, &len) != -1) {
  181. buf = vmalloc(len);
  182. if (buf != NULL)
  183. memcpy(buf->v, p, len);
  184. else
  185. l_ac_errno = ENOMEM;
  186. racoon_free(p);
  187. } else
  188. l_ac_errno = ENOMEM;
  189. break;
  190. }
  191. case ADMIN_SHOW_EVT:
  192. if (com->ac_version == 0) {
  193. buf = evt_dump();
  194. l_ac_errno = 0;
  195. }
  196. break;
  197. case ADMIN_SHOW_SA:
  198. switch (com->ac_proto) {
  199. case ADMIN_PROTO_ISAKMP:
  200. buf = dumpph1();
  201. if (buf == NULL)
  202. l_ac_errno = ENOMEM;
  203. break;
  204. case ADMIN_PROTO_IPSEC:
  205. case ADMIN_PROTO_AH:
  206. case ADMIN_PROTO_ESP: {
  207. u_int p;
  208. p = admin2pfkey_proto(com->ac_proto);
  209. if (p != -1) {
  210. buf = pfkey_dump_sadb(p);
  211. if (buf == NULL)
  212. l_ac_errno = ENOMEM;
  213. } else
  214. l_ac_errno = EINVAL;
  215. break;
  216. }
  217. case ADMIN_PROTO_INTERNAL:
  218. default:
  219. l_ac_errno = ENOTSUP;
  220. break;
  221. }
  222. break;
  223. case ADMIN_GET_SA_CERT: {
  224. struct admin_com_indexes *ndx;
  225. struct sockaddr *src, *dst;
  226. struct ph1handle *iph1;
  227. ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com));
  228. src = (struct sockaddr *) &ndx->src;
  229. dst = (struct sockaddr *) &ndx->dst;
  230. if (com->ac_proto != ADMIN_PROTO_ISAKMP) {
  231. l_ac_errno = ENOTSUP;
  232. break;
  233. }
  234. iph1 = getph1byaddr(src, dst, 0);
  235. if (iph1 == NULL) {
  236. l_ac_errno = ENOENT;
  237. break;
  238. }
  239. if (iph1->cert_p != NULL) {
  240. vchar_t tmp;
  241. tmp.v = iph1->cert_p->v + 1;
  242. tmp.l = iph1->cert_p->l - 1;
  243. buf = vdup(&tmp);
  244. }
  245. break;
  246. }
  247. case ADMIN_FLUSH_SA:
  248. switch (com->ac_proto) {
  249. case ADMIN_PROTO_ISAKMP:
  250. flushph1();
  251. break;
  252. case ADMIN_PROTO_IPSEC:
  253. case ADMIN_PROTO_AH:
  254. case ADMIN_PROTO_ESP:
  255. pfkey_flush_sadb(com->ac_proto);
  256. break;
  257. case ADMIN_PROTO_INTERNAL:
  258. /*XXX flushph2();*/
  259. default:
  260. l_ac_errno = ENOTSUP;
  261. break;
  262. }
  263. break;
  264. case ADMIN_DELETE_SA: {
  265. char *loc, *rem;
  266. struct ph1selector sel;
  267. memset(&sel, 0, sizeof(sel));
  268. sel.local = (struct sockaddr *)
  269. &((struct admin_com_indexes *)
  270. ((caddr_t)com + sizeof(*com)))->src;
  271. sel.remote = (struct sockaddr *)
  272. &((struct admin_com_indexes *)
  273. ((caddr_t)com + sizeof(*com)))->dst;
  274. loc = racoon_strdup(saddr2str(sel.local));
  275. rem = racoon_strdup(saddr2str(sel.remote));
  276. STRDUP_FATAL(loc);
  277. STRDUP_FATAL(rem);
  278. plog(LLV_INFO, LOCATION, NULL,
  279. "admin delete-sa %s %s\n", loc, rem);
  280. enumph1(&sel, admin_ph1_delete_sa, NULL);
  281. remcontacted(sel.remote);
  282. racoon_free(loc);
  283. racoon_free(rem);
  284. break;
  285. }
  286. #ifdef ENABLE_HYBRID
  287. case ADMIN_LOGOUT_USER: {
  288. struct ph1handle *iph1;
  289. char user[LOGINLEN+1];
  290. int found = 0, len = com->ac_len - sizeof(*com);
  291. if (len > LOGINLEN) {
  292. plog(LLV_ERROR, LOCATION, NULL,
  293. "malformed message (login too long)\n");
  294. break;
  295. }
  296. memcpy(user, (char *)(com + 1), len);
  297. user[len] = 0;
  298. found = purgeph1bylogin(user);
  299. plog(LLV_INFO, LOCATION, NULL,
  300. "deleted %d SA for user \"%s\"\n", found, user);
  301. break;
  302. }
  303. #endif
  304. case ADMIN_DELETE_ALL_SA_DST: {
  305. struct ph1handle *iph1;
  306. struct sockaddr *dst;
  307. char *loc, *rem;
  308. dst = (struct sockaddr *)
  309. &((struct admin_com_indexes *)
  310. ((caddr_t)com + sizeof(*com)))->dst;
  311. rem = racoon_strdup(saddrwop2str(dst));
  312. STRDUP_FATAL(rem);
  313. plog(LLV_INFO, LOCATION, NULL,
  314. "Flushing all SAs for peer %s\n", rem);
  315. while ((iph1 = getph1bydstaddr(dst)) != NULL) {
  316. loc = racoon_strdup(saddrwop2str(iph1->local));
  317. STRDUP_FATAL(loc);
  318. if (iph1->status >= PHASE1ST_ESTABLISHED)
  319. isakmp_info_send_d1(iph1);
  320. purge_remote(iph1);
  321. racoon_free(loc);
  322. }
  323. racoon_free(rem);
  324. break;
  325. }
  326. case ADMIN_ESTABLISH_SA_PSK: {
  327. struct admin_com_psk *acp;
  328. char *data;
  329. acp = (struct admin_com_psk *)
  330. ((char *)com + sizeof(*com) +
  331. sizeof(struct admin_com_indexes));
  332. idtype = acp->id_type;
  333. if ((id = vmalloc(acp->id_len)) == NULL) {
  334. plog(LLV_ERROR, LOCATION, NULL,
  335. "cannot allocate memory: %s\n",
  336. strerror(errno));
  337. break;
  338. }
  339. data = (char *)(acp + 1);
  340. memcpy(id->v, data, id->l);
  341. if ((key = vmalloc(acp->key_len)) == NULL) {
  342. plog(LLV_ERROR, LOCATION, NULL,
  343. "cannot allocate memory: %s\n",
  344. strerror(errno));
  345. vfree(id);
  346. id = NULL;
  347. break;
  348. }
  349. data = (char *)(data + acp->id_len);
  350. memcpy(key->v, data, key->l);
  351. }
  352. /* FALLTHROUGH */
  353. case ADMIN_ESTABLISH_SA: {
  354. struct admin_com_indexes *ndx;
  355. struct sockaddr *dst;
  356. struct sockaddr *src;
  357. char *name = NULL;
  358. ndx = (struct admin_com_indexes *) ((caddr_t)com + sizeof(*com));
  359. src = (struct sockaddr *) &ndx->src;
  360. dst = (struct sockaddr *) &ndx->dst;
  361. if (com->ac_cmd == ADMIN_ESTABLISH_SA &&
  362. com->ac_len > sizeof(*com) + sizeof(*ndx))
  363. name = (char *) ((caddr_t) ndx + sizeof(*ndx));
  364. switch (com->ac_proto) {
  365. case ADMIN_PROTO_ISAKMP: {
  366. struct ph1handle *ph1;
  367. struct remoteconf *rmconf;
  368. u_int16_t port;
  369. l_ac_errno = -1;
  370. /* connected already? */
  371. ph1 = getph1byaddr(src, dst, 0);
  372. if (ph1 != NULL) {
  373. event_list = &ph1->evt_listeners;
  374. if (ph1->status == PHASE1ST_ESTABLISHED)
  375. l_ac_errno = EEXIST;
  376. else
  377. l_ac_errno = 0;
  378. break;
  379. }
  380. /* search appropreate configuration */
  381. if (name == NULL)
  382. rmconf = getrmconf(dst, 0);
  383. else
  384. rmconf = getrmconf_by_name(name);
  385. if (rmconf == NULL) {
  386. plog(LLV_ERROR, LOCATION, NULL,
  387. "no configuration found "
  388. "for %s\n", saddrwop2str(dst));
  389. break;
  390. }
  391. #ifdef ENABLE_HYBRID
  392. /* XXX This overwrites rmconf information globally. */
  393. /* Set the id and key */
  394. if (id && key) {
  395. if (xauth_rmconf_used(&rmconf->xauth) == -1)
  396. break;
  397. if (rmconf->xauth->login != NULL) {
  398. vfree(rmconf->xauth->login);
  399. rmconf->xauth->login = NULL;
  400. }
  401. if (rmconf->xauth->pass != NULL) {
  402. vfree(rmconf->xauth->pass);
  403. rmconf->xauth->pass = NULL;
  404. }
  405. rmconf->xauth->login = id;
  406. rmconf->xauth->pass = key;
  407. }
  408. #endif
  409. plog(LLV_INFO, LOCATION, NULL,
  410. "accept a request to establish IKE-SA: "
  411. "%s\n", saddrwop2str(dst));
  412. /* begin ident mode */
  413. ph1 = isakmp_ph1begin_i(rmconf, dst, src);
  414. if (ph1 == NULL)
  415. break;
  416. event_list = &ph1->evt_listeners;
  417. l_ac_errno = 0;
  418. break;
  419. }
  420. case ADMIN_PROTO_AH:
  421. case ADMIN_PROTO_ESP: {
  422. struct ph2handle *iph2;
  423. struct secpolicy *sp_out = NULL, *sp_in = NULL;
  424. struct policyindex spidx;
  425. l_ac_errno = -1;
  426. /* got outbound policy */
  427. memset(&spidx, 0, sizeof(spidx));
  428. spidx.dir = IPSEC_DIR_OUTBOUND;
  429. memcpy(&spidx.src, src, sizeof(spidx.src));
  430. memcpy(&spidx.dst, dst, sizeof(spidx.dst));
  431. spidx.prefs = ndx->prefs;
  432. spidx.prefd = ndx->prefd;
  433. spidx.ul_proto = ndx->ul_proto;
  434. sp_out = getsp_r(&spidx);
  435. if (sp_out) {
  436. plog(LLV_DEBUG, LOCATION, NULL,
  437. "suitable outbound SP found: %s.\n",
  438. spidx2str(&sp_out->spidx));
  439. } else {
  440. l_ac_errno = ENOENT;
  441. plog(LLV_NOTIFY, LOCATION, NULL,
  442. "no outbound policy found: %s\n",
  443. spidx2str(&spidx));
  444. break;
  445. }
  446. iph2 = getph2byid(src, dst, sp_out->id);
  447. if (iph2 != NULL) {
  448. event_list = &iph2->evt_listeners;
  449. if (iph2->status == PHASE2ST_ESTABLISHED)
  450. l_ac_errno = EEXIST;
  451. else
  452. l_ac_errno = 0;
  453. break;
  454. }
  455. /* get inbound policy */
  456. memset(&spidx, 0, sizeof(spidx));
  457. spidx.dir = IPSEC_DIR_INBOUND;
  458. memcpy(&spidx.src, dst, sizeof(spidx.src));
  459. memcpy(&spidx.dst, src, sizeof(spidx.dst));
  460. spidx.prefs = ndx->prefd;
  461. spidx.prefd = ndx->prefs;
  462. spidx.ul_proto = ndx->ul_proto;
  463. sp_in = getsp_r(&spidx);
  464. if (sp_in) {
  465. plog(LLV_DEBUG, LOCATION, NULL,
  466. "suitable inbound SP found: %s.\n",
  467. spidx2str(&sp_in->spidx));
  468. } else {
  469. l_ac_errno = ENOENT;
  470. plog(LLV_NOTIFY, LOCATION, NULL,
  471. "no inbound policy found: %s\n",
  472. spidx2str(&spidx));
  473. break;
  474. }
  475. /* allocate a phase 2 */
  476. iph2 = newph2();
  477. if (iph2 == NULL) {
  478. plog(LLV_ERROR, LOCATION, NULL,
  479. "failed to allocate phase2 entry.\n");
  480. break;
  481. }
  482. iph2->side = INITIATOR;
  483. iph2->satype = admin2pfkey_proto(com->ac_proto);
  484. iph2->spid = sp_out->id;
  485. iph2->seq = pk_getseq();
  486. iph2->status = PHASE2ST_STATUS2;
  487. /* set end addresses of SA */
  488. iph2->sa_dst = dupsaddr(dst);
  489. iph2->sa_src = dupsaddr(src);
  490. iph2->dst = dupsaddr(dst);
  491. iph2->src = dupsaddr(src);
  492. if (iph2->sa_src == NULL || iph2->sa_dst == NULL ||
  493. iph2->dst == NULL || iph2->src == NULL) {
  494. delph2(iph2);
  495. break;
  496. }
  497. set_port(iph2->dst, 0);
  498. set_port(iph2->src, 0);
  499. if (isakmp_get_sainfo(iph2, sp_out, sp_in) < 0) {
  500. delph2(iph2);
  501. break;
  502. }
  503. insph2(iph2);
  504. if (isakmp_post_acquire(iph2, NULL, FALSE) < 0) {
  505. remph2(iph2);
  506. delph2(iph2);
  507. break;
  508. }
  509. event_list = &iph2->evt_listeners;
  510. l_ac_errno = 0;
  511. break;
  512. }
  513. default:
  514. /* ignore */
  515. l_ac_errno = ENOTSUP;
  516. }
  517. break;
  518. }
  519. default:
  520. plog(LLV_ERROR, LOCATION, NULL,
  521. "invalid command: %d\n", com->ac_cmd);
  522. l_ac_errno = ENOTSUP;
  523. }
  524. if ((error = admin_reply(so2, com, l_ac_errno, buf)) != 0)
  525. goto out;
  526. /* start pushing events if so requested */
  527. if ((l_ac_errno == 0) &&
  528. (com->ac_version >= 1) &&
  529. (com->ac_cmd == ADMIN_SHOW_EVT || event_list != NULL))
  530. error = evt_subscribe(event_list, so2);
  531. out:
  532. if (buf != NULL)
  533. vfree(buf);
  534. return error;
  535. }
  536. static int
  537. admin_reply(so, req, l_ac_errno, buf)
  538. int so, l_ac_errno;
  539. struct admin_com *req;
  540. vchar_t *buf;
  541. {
  542. int tlen;
  543. struct admin_com *combuf;
  544. char *retbuf = NULL;
  545. if (buf != NULL)
  546. tlen = sizeof(*combuf) + buf->l;
  547. else
  548. tlen = sizeof(*combuf);
  549. retbuf = racoon_calloc(1, tlen);
  550. if (retbuf == NULL) {
  551. plog(LLV_ERROR, LOCATION, NULL,
  552. "failed to allocate admin buffer\n");
  553. return -1;
  554. }
  555. combuf = (struct admin_com *) retbuf;
  556. combuf->ac_len = (u_int16_t) tlen;
  557. combuf->ac_cmd = req->ac_cmd & ~ADMIN_FLAG_VERSION;
  558. if (tlen != (u_int32_t) combuf->ac_len &&
  559. l_ac_errno == 0) {
  560. combuf->ac_len_high = tlen >> 16;
  561. combuf->ac_cmd |= ADMIN_FLAG_LONG_REPLY;
  562. } else {
  563. combuf->ac_errno = l_ac_errno;
  564. }
  565. combuf->ac_proto = req->ac_proto;
  566. if (buf != NULL)
  567. memcpy(retbuf + sizeof(*combuf), buf->v, buf->l);
  568. tlen = send(so, retbuf, tlen, 0);
  569. racoon_free(retbuf);
  570. if (tlen < 0) {
  571. plog(LLV_ERROR, LOCATION, NULL,
  572. "failed to send admin command: %s\n",
  573. strerror(errno));
  574. return -1;
  575. }
  576. return 0;
  577. }
  578. /* ADMIN_PROTO -> SADB_SATYPE */
  579. int
  580. admin2pfkey_proto(proto)
  581. u_int proto;
  582. {
  583. switch (proto) {
  584. case ADMIN_PROTO_IPSEC:
  585. return SADB_SATYPE_UNSPEC;
  586. case ADMIN_PROTO_AH:
  587. return SADB_SATYPE_AH;
  588. case ADMIN_PROTO_ESP:
  589. return SADB_SATYPE_ESP;
  590. default:
  591. plog(LLV_ERROR, LOCATION, NULL,
  592. "unsupported proto for admin: %d\n", proto);
  593. return -1;
  594. }
  595. /*NOTREACHED*/
  596. }
  597. int
  598. admin_init()
  599. {
  600. if (adminsock_path == NULL) {
  601. lcconf->sock_admin = -1;
  602. return 0;
  603. }
  604. memset(&sunaddr, 0, sizeof(sunaddr));
  605. sunaddr.sun_family = AF_UNIX;
  606. snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path),
  607. "%s", adminsock_path);
  608. lcconf->sock_admin = socket(AF_UNIX, SOCK_STREAM, 0);
  609. if (lcconf->sock_admin == -1) {
  610. plog(LLV_ERROR, LOCATION, NULL,
  611. "socket: %s\n", strerror(errno));
  612. return -1;
  613. }
  614. close_on_exec(lcconf->sock_admin);
  615. unlink(sunaddr.sun_path);
  616. if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr,
  617. sizeof(sunaddr)) != 0) {
  618. plog(LLV_ERROR, LOCATION, NULL,
  619. "bind(sockname:%s): %s\n",
  620. sunaddr.sun_path, strerror(errno));
  621. (void)close(lcconf->sock_admin);
  622. return -1;
  623. }
  624. if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) {
  625. plog(LLV_ERROR, LOCATION, NULL,
  626. "chown(%s, %d, %d): %s\n",
  627. sunaddr.sun_path, adminsock_owner,
  628. adminsock_group, strerror(errno));
  629. (void)close(lcconf->sock_admin);
  630. return -1;
  631. }
  632. if (chmod(sunaddr.sun_path, adminsock_mode) != 0) {
  633. plog(LLV_ERROR, LOCATION, NULL,
  634. "chmod(%s, 0%03o): %s\n",
  635. sunaddr.sun_path, adminsock_mode, strerror(errno));
  636. (void)close(lcconf->sock_admin);
  637. return -1;
  638. }
  639. if (listen(lcconf->sock_admin, 5) != 0) {
  640. plog(LLV_ERROR, LOCATION, NULL,
  641. "listen(sockname:%s): %s\n",
  642. sunaddr.sun_path, strerror(errno));
  643. (void)close(lcconf->sock_admin);
  644. return -1;
  645. }
  646. monitor_fd(lcconf->sock_admin, admin_handler, NULL, 0);
  647. plog(LLV_DEBUG, LOCATION, NULL,
  648. "open %s as racoon management.\n", sunaddr.sun_path);
  649. return 0;
  650. }
  651. int
  652. admin_close()
  653. {
  654. unmonitor_fd(lcconf->sock_admin);
  655. close(lcconf->sock_admin);
  656. return 0;
  657. }
  658. #endif