Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_control.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2015-2017 Tobias Brunner
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * Copyright (C) 2014 Martin Willi
! 6: * Copyright (C) 2014 revosec AG
! 7: *
! 8: * This program is free software; you can redistribute it and/or modify it
! 9: * under the terms of the GNU General Public License as published by the
! 10: * Free Software Foundation; either version 2 of the License, or (at your
! 11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 12: *
! 13: * This program is distributed in the hope that it will be useful, but
! 14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 16: * for more details.
! 17: */
! 18:
! 19: #include "vici_control.h"
! 20: #include "vici_builder.h"
! 21:
! 22: #include <inttypes.h>
! 23:
! 24: #include <daemon.h>
! 25: #include <collections/array.h>
! 26: #include <processing/jobs/rekey_ike_sa_job.h>
! 27: #include <processing/jobs/rekey_child_sa_job.h>
! 28: #include <processing/jobs/redirect_job.h>
! 29:
! 30: typedef struct private_vici_control_t private_vici_control_t;
! 31:
! 32: /**
! 33: * Private data of an vici_control_t object.
! 34: */
! 35: struct private_vici_control_t {
! 36:
! 37: /**
! 38: * Public vici_control_t interface.
! 39: */
! 40: vici_control_t public;
! 41:
! 42: /**
! 43: * Dispatcher
! 44: */
! 45: vici_dispatcher_t *dispatcher;
! 46: };
! 47:
! 48: /**
! 49: * Log callback helper data
! 50: */
! 51: typedef struct {
! 52: /** dispatcher to send log messages over */
! 53: vici_dispatcher_t *dispatcher;
! 54: /** connection ID to send messages to */
! 55: u_int id;
! 56: /** loglevel */
! 57: level_t level;
! 58: /** prevent recursive log */
! 59: u_int recursive;
! 60: } log_info_t;
! 61:
! 62: /**
! 63: * Log using vici event messages
! 64: */
! 65: static bool log_vici(log_info_t *info, debug_t group, level_t level,
! 66: ike_sa_t *ike_sa, char *text)
! 67: {
! 68: if (level <= info->level)
! 69: {
! 70: if (info->recursive++ == 0)
! 71: {
! 72: vici_message_t *message;
! 73: vici_builder_t *builder;
! 74:
! 75: builder = vici_builder_create();
! 76: builder->add_kv(builder, "group", "%N", debug_names, group);
! 77: builder->add_kv(builder, "level", "%d", level);
! 78: if (ike_sa)
! 79: {
! 80: builder->add_kv(builder, "ikesa-name", "%s",
! 81: ike_sa->get_name(ike_sa));
! 82: builder->add_kv(builder, "ikesa-uniqueid", "%u",
! 83: ike_sa->get_unique_id(ike_sa));
! 84: }
! 85: builder->add_kv(builder, "msg", "%s", text);
! 86:
! 87: message = builder->finalize(builder);
! 88: if (message)
! 89: {
! 90: info->dispatcher->raise_event(info->dispatcher, "control-log",
! 91: info->id, message);
! 92: }
! 93: }
! 94: info->recursive--;
! 95: }
! 96: return TRUE;
! 97: }
! 98:
! 99: /**
! 100: * Send a (error) reply message
! 101: */
! 102: static vici_message_t* send_reply(private_vici_control_t *this, char *fmt, ...)
! 103: {
! 104: vici_builder_t *builder;
! 105: va_list args;
! 106:
! 107: builder = vici_builder_create();
! 108: builder->add_kv(builder, "success", fmt ? "no" : "yes");
! 109: if (fmt)
! 110: {
! 111: va_start(args, fmt);
! 112: builder->vadd_kv(builder, "errmsg", fmt, args);
! 113: va_end(args);
! 114: }
! 115: return builder->finalize(builder);
! 116: }
! 117:
! 118: /**
! 119: * Get the child_cfg having name from peer_cfg
! 120: */
! 121: static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
! 122: {
! 123: child_cfg_t *current, *found = NULL;
! 124: enumerator_t *enumerator;
! 125:
! 126: enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
! 127: while (enumerator->enumerate(enumerator, ¤t))
! 128: {
! 129: if (streq(current->get_name(current), name))
! 130: {
! 131: found = current;
! 132: found->get_ref(found);
! 133: break;
! 134: }
! 135: }
! 136: enumerator->destroy(enumerator);
! 137: return found;
! 138: }
! 139:
! 140: /**
! 141: * Find a peer/child config from a config name
! 142: */
! 143: static child_cfg_t* find_child_cfg(char *name, char *pname, peer_cfg_t **out)
! 144: {
! 145: enumerator_t *enumerator;
! 146: peer_cfg_t *peer_cfg;
! 147: child_cfg_t *child_cfg = NULL;
! 148:
! 149: enumerator = charon->backends->create_peer_cfg_enumerator(
! 150: charon->backends, NULL, NULL, NULL, NULL, IKE_ANY);
! 151: while (enumerator->enumerate(enumerator, &peer_cfg))
! 152: {
! 153: if (pname && !streq(pname, peer_cfg->get_name(peer_cfg)))
! 154: {
! 155: continue;
! 156: }
! 157: if (!name)
! 158: {
! 159: *out = peer_cfg->get_ref(peer_cfg);
! 160: break;
! 161: }
! 162: child_cfg = get_child_from_peer(peer_cfg, name);
! 163: if (child_cfg)
! 164: {
! 165: *out = peer_cfg->get_ref(peer_cfg);
! 166: break;
! 167: }
! 168: }
! 169: enumerator->destroy(enumerator);
! 170:
! 171: return child_cfg;
! 172: }
! 173:
! 174: CALLBACK(initiate, vici_message_t*,
! 175: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 176: {
! 177: peer_cfg_t *peer_cfg = NULL;
! 178: child_cfg_t *child_cfg;
! 179: char *child, *ike, *type, *sa;
! 180: int timeout;
! 181: bool limits;
! 182: controller_cb_t log_cb = NULL;
! 183: log_info_t log = {
! 184: .dispatcher = this->dispatcher,
! 185: .id = id,
! 186: };
! 187:
! 188: child = request->get_str(request, NULL, "child");
! 189: ike = request->get_str(request, NULL, "ike");
! 190: timeout = request->get_int(request, 0, "timeout");
! 191: limits = request->get_bool(request, FALSE, "init-limits");
! 192: log.level = request->get_int(request, 1, "loglevel");
! 193:
! 194: if (!child && !ike)
! 195: {
! 196: return send_reply(this, "missing configuration name");
! 197: }
! 198: if (timeout >= 0)
! 199: {
! 200: log_cb = (controller_cb_t)log_vici;
! 201: }
! 202:
! 203: type = child ? "CHILD_SA" : "IKE_SA";
! 204: sa = child ?: ike;
! 205:
! 206: child_cfg = find_child_cfg(child, ike, &peer_cfg);
! 207:
! 208: DBG1(DBG_CFG, "vici initiate %s '%s'", type, sa);
! 209: if (!peer_cfg)
! 210: {
! 211: return send_reply(this, "%s config '%s' not found", type, sa);
! 212: }
! 213: switch (charon->controller->initiate(charon->controller, peer_cfg,
! 214: child_cfg, log_cb, &log, timeout, limits))
! 215: {
! 216: case SUCCESS:
! 217: return send_reply(this, NULL);
! 218: case OUT_OF_RES:
! 219: return send_reply(this, "%s '%s' not established after %dms", type,
! 220: sa, timeout);
! 221: case INVALID_STATE:
! 222: return send_reply(this, "establishing %s '%s' not possible at the "
! 223: "moment due to limits", type, sa);
! 224: case FAILED:
! 225: default:
! 226: return send_reply(this, "establishing %s '%s' failed", type, sa);
! 227: }
! 228: }
! 229:
! 230: CALLBACK(terminate, vici_message_t*,
! 231: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 232: {
! 233: enumerator_t *enumerator, *isas, *csas;
! 234: char *child, *ike, *errmsg = NULL;
! 235: u_int child_id, ike_id, current, *del, done = 0;
! 236: bool force;
! 237: int timeout;
! 238: ike_sa_t *ike_sa;
! 239: child_sa_t *child_sa;
! 240: array_t *ids;
! 241: vici_builder_t *builder;
! 242: controller_cb_t log_cb = NULL;
! 243: log_info_t log = {
! 244: .dispatcher = this->dispatcher,
! 245: .id = id,
! 246: };
! 247:
! 248: child = request->get_str(request, NULL, "child");
! 249: ike = request->get_str(request, NULL, "ike");
! 250: child_id = request->get_int(request, 0, "child-id");
! 251: ike_id = request->get_int(request, 0, "ike-id");
! 252: force = request->get_bool(request, FALSE, "force");
! 253: timeout = request->get_int(request, 0, "timeout");
! 254: log.level = request->get_int(request, 1, "loglevel");
! 255:
! 256: if (!child && !ike && !ike_id && !child_id)
! 257: {
! 258: return send_reply(this, "missing terminate selector");
! 259: }
! 260:
! 261: if (ike_id)
! 262: {
! 263: DBG1(DBG_CFG, "vici terminate IKE_SA #%d", ike_id);
! 264: }
! 265: if (child_id)
! 266: {
! 267: DBG1(DBG_CFG, "vici terminate CHILD_SA #%d", child_id);
! 268: }
! 269: if (ike)
! 270: {
! 271: DBG1(DBG_CFG, "vici terminate IKE_SA '%s'", ike);
! 272: }
! 273: if (child)
! 274: {
! 275: DBG1(DBG_CFG, "vici terminate CHILD_SA '%s'", child);
! 276: }
! 277:
! 278: if (timeout >= 0)
! 279: {
! 280: log_cb = (controller_cb_t)log_vici;
! 281: }
! 282:
! 283: ids = array_create(sizeof(u_int), 0);
! 284:
! 285: isas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
! 286: while (isas->enumerate(isas, &ike_sa))
! 287: {
! 288: if (child || child_id)
! 289: {
! 290: if (ike && !streq(ike, ike_sa->get_name(ike_sa)))
! 291: {
! 292: continue;
! 293: }
! 294: if (ike_id && ike_id != ike_sa->get_unique_id(ike_sa))
! 295: {
! 296: continue;
! 297: }
! 298: csas = ike_sa->create_child_sa_enumerator(ike_sa);
! 299: while (csas->enumerate(csas, &child_sa))
! 300: {
! 301: if (child && !streq(child, child_sa->get_name(child_sa)))
! 302: {
! 303: continue;
! 304: }
! 305: if (child_id && child_sa->get_unique_id(child_sa) != child_id)
! 306: {
! 307: continue;
! 308: }
! 309: current = child_sa->get_unique_id(child_sa);
! 310: array_insert(ids, ARRAY_TAIL, ¤t);
! 311: }
! 312: csas->destroy(csas);
! 313: }
! 314: else if (ike && streq(ike, ike_sa->get_name(ike_sa)))
! 315: {
! 316: current = ike_sa->get_unique_id(ike_sa);
! 317: array_insert(ids, ARRAY_TAIL, ¤t);
! 318: }
! 319: else if (ike_id && ike_id == ike_sa->get_unique_id(ike_sa))
! 320: {
! 321: array_insert(ids, ARRAY_TAIL, &ike_id);
! 322: }
! 323: }
! 324: isas->destroy(isas);
! 325:
! 326: enumerator = array_create_enumerator(ids);
! 327: while (enumerator->enumerate(enumerator, &del))
! 328: {
! 329: if (child || child_id)
! 330: {
! 331: if (charon->controller->terminate_child(charon->controller, *del,
! 332: log_cb, &log, timeout) == SUCCESS)
! 333: {
! 334: done++;
! 335: }
! 336: }
! 337: else
! 338: {
! 339: if (charon->controller->terminate_ike(charon->controller, *del, force,
! 340: log_cb, &log, timeout) == SUCCESS)
! 341: {
! 342: done++;
! 343: }
! 344: }
! 345: }
! 346: enumerator->destroy(enumerator);
! 347:
! 348: builder = vici_builder_create();
! 349: if (array_count(ids) == 0)
! 350: {
! 351: errmsg = "no matching SAs to terminate found";
! 352: }
! 353: else if (done < array_count(ids))
! 354: {
! 355: if (array_count(ids) == 1)
! 356: {
! 357: errmsg = "terminating SA failed";
! 358: }
! 359: else
! 360: {
! 361: errmsg = "not all matching SAs could be terminated";
! 362: }
! 363: }
! 364: builder->add_kv(builder, "success", errmsg ? "no" : "yes");
! 365: builder->add_kv(builder, "matches", "%u", array_count(ids));
! 366: builder->add_kv(builder, "terminated", "%u", done);
! 367: if (errmsg)
! 368: {
! 369: builder->add_kv(builder, "errmsg", "%s", errmsg);
! 370: }
! 371: array_destroy(ids);
! 372: return builder->finalize(builder);
! 373: }
! 374:
! 375: CALLBACK(rekey, vici_message_t*,
! 376: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 377: {
! 378: enumerator_t *isas, *csas;
! 379: char *child, *ike, *errmsg = NULL;
! 380: u_int child_id, ike_id, found = 0;
! 381: ike_sa_t *ike_sa;
! 382: child_sa_t *child_sa;
! 383: vici_builder_t *builder;
! 384: bool reauth;
! 385:
! 386: child = request->get_str(request, NULL, "child");
! 387: ike = request->get_str(request, NULL, "ike");
! 388: child_id = request->get_int(request, 0, "child-id");
! 389: ike_id = request->get_int(request, 0, "ike-id");
! 390: reauth = request->get_bool(request, FALSE, "reauth");
! 391:
! 392: if (!child && !ike && !ike_id && !child_id)
! 393: {
! 394: return send_reply(this, "missing rekey selector");
! 395: }
! 396:
! 397: if (ike_id)
! 398: {
! 399: DBG1(DBG_CFG, "vici rekey IKE_SA #%d", ike_id);
! 400: }
! 401: if (child_id)
! 402: {
! 403: DBG1(DBG_CFG, "vici rekey CHILD_SA #%d", child_id);
! 404: }
! 405: if (ike)
! 406: {
! 407: DBG1(DBG_CFG, "vici rekey IKE_SA '%s'", ike);
! 408: }
! 409: if (child)
! 410: {
! 411: DBG1(DBG_CFG, "vici rekey CHILD_SA '%s'", child);
! 412: }
! 413:
! 414: isas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
! 415: while (isas->enumerate(isas, &ike_sa))
! 416: {
! 417: if (child || child_id)
! 418: {
! 419: if (ike && !streq(ike, ike_sa->get_name(ike_sa)))
! 420: {
! 421: continue;
! 422: }
! 423: if (ike_id && ike_id != ike_sa->get_unique_id(ike_sa))
! 424: {
! 425: continue;
! 426: }
! 427: csas = ike_sa->create_child_sa_enumerator(ike_sa);
! 428: while (csas->enumerate(csas, &child_sa))
! 429: {
! 430: if (child && !streq(child, child_sa->get_name(child_sa)))
! 431: {
! 432: continue;
! 433: }
! 434: if (child_id && child_sa->get_unique_id(child_sa) != child_id)
! 435: {
! 436: continue;
! 437: }
! 438: lib->processor->queue_job(lib->processor,
! 439: (job_t*)rekey_child_sa_job_create(
! 440: child_sa->get_protocol(child_sa),
! 441: child_sa->get_spi(child_sa, TRUE),
! 442: ike_sa->get_my_host(ike_sa)));
! 443: found++;
! 444: }
! 445: csas->destroy(csas);
! 446: }
! 447: else if ((ike && streq(ike, ike_sa->get_name(ike_sa))) ||
! 448: (ike_id && ike_id == ike_sa->get_unique_id(ike_sa)))
! 449: {
! 450: lib->processor->queue_job(lib->processor,
! 451: (job_t*)rekey_ike_sa_job_create(ike_sa->get_id(ike_sa), reauth));
! 452: found++;
! 453: }
! 454: }
! 455: isas->destroy(isas);
! 456:
! 457: builder = vici_builder_create();
! 458: if (!found)
! 459: {
! 460: errmsg = "no matching SAs to rekey found";
! 461: }
! 462: builder->add_kv(builder, "success", errmsg ? "no" : "yes");
! 463: builder->add_kv(builder, "matches", "%u", found);
! 464: if (errmsg)
! 465: {
! 466: builder->add_kv(builder, "errmsg", "%s", errmsg);
! 467: }
! 468: return builder->finalize(builder);
! 469: }
! 470:
! 471: /**
! 472: * Parse a peer-ip specified, which can be a subnet in CIDR notation, a range
! 473: * or a single IP address.
! 474: */
! 475: static traffic_selector_t *parse_peer_ip(char *ip)
! 476: {
! 477: traffic_selector_t *ts;
! 478: host_t *from, *to;
! 479: ts_type_t type;
! 480:
! 481: if (host_create_from_range(ip, &from, &to))
! 482: {
! 483: if (to->get_family(to) == AF_INET)
! 484: {
! 485: type = TS_IPV4_ADDR_RANGE;
! 486: }
! 487: else
! 488: {
! 489: type = TS_IPV6_ADDR_RANGE;
! 490: }
! 491: ts = traffic_selector_create_from_bytes(0, type,
! 492: from->get_address(from), 0,
! 493: to->get_address(to), 0xFFFF);
! 494: from->destroy(from);
! 495: to->destroy(to);
! 496: return ts;
! 497: }
! 498: return traffic_selector_create_from_cidr(ip, 0, 0, 0xFFFF);
! 499: }
! 500:
! 501: CALLBACK(redirect, vici_message_t*,
! 502: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 503: {
! 504: enumerator_t *sas;
! 505: char *ike, *peer_ip, *peer_id, *gw, *errmsg = NULL;
! 506: u_int ike_id, current, found = 0;
! 507: identification_t *gateway, *identity = NULL, *other_id;
! 508: traffic_selector_t *ts = NULL;
! 509: ike_sa_t *ike_sa;
! 510: vici_builder_t *builder;
! 511:
! 512: ike = request->get_str(request, NULL, "ike");
! 513: ike_id = request->get_int(request, 0, "ike-id");
! 514: peer_ip = request->get_str(request, NULL, "peer-ip");
! 515: peer_id = request->get_str(request, NULL, "peer-id");
! 516: gw = request->get_str(request, NULL, "gateway");
! 517:
! 518: if (!gw || !(gateway = identification_create_from_string(gw)))
! 519: {
! 520: return send_reply(this, "missing target gateway");
! 521: }
! 522: switch (gateway->get_type(gateway))
! 523: {
! 524: case ID_IPV4_ADDR:
! 525: case ID_IPV6_ADDR:
! 526: case ID_FQDN:
! 527: break;
! 528: default:
! 529: return send_reply(this, "unsupported gateway identity");
! 530: }
! 531: if (peer_ip)
! 532: {
! 533: ts = parse_peer_ip(peer_ip);
! 534: if (!ts)
! 535: {
! 536: return send_reply(this, "invalid peer IP selector");
! 537: }
! 538: DBG1(DBG_CFG, "vici redirect IKE_SAs with src %R to %Y", ts,
! 539: gateway);
! 540: }
! 541: if (peer_id)
! 542: {
! 543: identity = identification_create_from_string(peer_id);
! 544: if (!identity)
! 545: {
! 546: DESTROY_IF(ts);
! 547: return send_reply(this, "invalid peer identity selector");
! 548: }
! 549: DBG1(DBG_CFG, "vici redirect IKE_SAs with ID '%Y' to %Y", identity,
! 550: gateway);
! 551: }
! 552: if (ike_id)
! 553: {
! 554: DBG1(DBG_CFG, "vici redirect IKE_SA #%d to '%Y'", ike_id, gateway);
! 555: }
! 556: if (ike)
! 557: {
! 558: DBG1(DBG_CFG, "vici redirect IKE_SA '%s' to '%Y'", ike, gateway);
! 559: }
! 560: if (!peer_ip && !peer_id && !ike && !ike_id)
! 561: {
! 562: return send_reply(this, "missing redirect selector");
! 563: }
! 564:
! 565: sas = charon->controller->create_ike_sa_enumerator(charon->controller, TRUE);
! 566: while (sas->enumerate(sas, &ike_sa))
! 567: {
! 568: if (ike_sa->get_version(ike_sa) != IKEV2)
! 569: {
! 570: continue;
! 571: }
! 572: current = ike_sa->get_unique_id(ike_sa);
! 573: if (ike_id && ike_id != current)
! 574: {
! 575: continue;
! 576: }
! 577: if (ike && !streq(ike, ike_sa->get_name(ike_sa)))
! 578: {
! 579: continue;
! 580: }
! 581: if (ts && !ts->includes(ts, ike_sa->get_other_host(ike_sa)))
! 582: {
! 583: continue;
! 584: }
! 585: if (identity)
! 586: {
! 587: other_id = ike_sa->get_other_eap_id(ike_sa);
! 588: if (!other_id->matches(other_id, identity))
! 589: {
! 590: continue;
! 591: }
! 592: }
! 593: lib->processor->queue_job(lib->processor,
! 594: (job_t*)redirect_job_create(ike_sa->get_id(ike_sa), gateway));
! 595: found++;
! 596: }
! 597: sas->destroy(sas);
! 598:
! 599: builder = vici_builder_create();
! 600: if (!found)
! 601: {
! 602: errmsg = "no matching SAs to redirect found";
! 603: }
! 604: builder->add_kv(builder, "success", errmsg ? "no" : "yes");
! 605: builder->add_kv(builder, "matches", "%u", found);
! 606: if (errmsg)
! 607: {
! 608: builder->add_kv(builder, "errmsg", "%s", errmsg);
! 609: }
! 610: gateway->destroy(gateway);
! 611: DESTROY_IF(identity);
! 612: DESTROY_IF(ts);
! 613: return builder->finalize(builder);
! 614: }
! 615:
! 616: CALLBACK(install, vici_message_t*,
! 617: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 618: {
! 619: child_cfg_t *child_cfg = NULL;
! 620: peer_cfg_t *peer_cfg;
! 621: char *child, *ike;
! 622: bool ok;
! 623:
! 624: child = request->get_str(request, NULL, "child");
! 625: ike = request->get_str(request, NULL, "ike");
! 626: if (!child)
! 627: {
! 628: return send_reply(this, "missing configuration name");
! 629: }
! 630:
! 631: DBG1(DBG_CFG, "vici install '%s'", child);
! 632:
! 633: child_cfg = find_child_cfg(child, ike, &peer_cfg);
! 634: if (!child_cfg)
! 635: {
! 636: return send_reply(this, "configuration name not found");
! 637: }
! 638: switch (child_cfg->get_mode(child_cfg))
! 639: {
! 640: case MODE_PASS:
! 641: case MODE_DROP:
! 642: ok = charon->shunts->install(charon->shunts,
! 643: peer_cfg->get_name(peer_cfg), child_cfg);
! 644: break;
! 645: default:
! 646: ok = charon->traps->install(charon->traps, peer_cfg, child_cfg);
! 647: break;
! 648: }
! 649: peer_cfg->destroy(peer_cfg);
! 650: child_cfg->destroy(child_cfg);
! 651:
! 652: return send_reply(this, ok ? NULL : "installing policy '%s' failed", child);
! 653: }
! 654:
! 655: CALLBACK(uninstall, vici_message_t*,
! 656: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 657: {
! 658: char *child, *ike;
! 659:
! 660: child = request->get_str(request, NULL, "child");
! 661: ike = request->get_str(request, NULL, "ike");
! 662: if (!child)
! 663: {
! 664: return send_reply(this, "missing configuration name");
! 665: }
! 666:
! 667: DBG1(DBG_CFG, "vici uninstall '%s'", child);
! 668:
! 669: if (charon->shunts->uninstall(charon->shunts, ike, child))
! 670: {
! 671: return send_reply(this, NULL);
! 672: }
! 673: else if (charon->traps->uninstall(charon->traps, ike, child))
! 674: {
! 675: return send_reply(this, NULL);
! 676: }
! 677: return send_reply(this, "policy '%s' not found", child);
! 678: }
! 679:
! 680: CALLBACK(reload_settings, vici_message_t*,
! 681: private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
! 682: {
! 683: if (lib->settings->load_files(lib->settings, lib->conf, FALSE))
! 684: {
! 685: charon->load_loggers(charon);
! 686: lib->plugins->reload(lib->plugins, NULL);
! 687: return send_reply(this, NULL);
! 688: }
! 689: return send_reply(this, "reloading '%s' failed", lib->conf);
! 690: }
! 691:
! 692: static void manage_command(private_vici_control_t *this,
! 693: char *name, vici_command_cb_t cb, bool reg)
! 694: {
! 695: this->dispatcher->manage_command(this->dispatcher, name,
! 696: reg ? cb : NULL, this);
! 697: }
! 698:
! 699: /**
! 700: * (Un-)register dispatcher functions
! 701: */
! 702: static void manage_commands(private_vici_control_t *this, bool reg)
! 703: {
! 704: manage_command(this, "initiate", initiate, reg);
! 705: manage_command(this, "terminate", terminate, reg);
! 706: manage_command(this, "rekey", rekey, reg);
! 707: manage_command(this, "redirect", redirect, reg);
! 708: manage_command(this, "install", install, reg);
! 709: manage_command(this, "uninstall", uninstall, reg);
! 710: manage_command(this, "reload-settings", reload_settings, reg);
! 711: this->dispatcher->manage_event(this->dispatcher, "control-log", reg);
! 712: }
! 713:
! 714: METHOD(vici_control_t, destroy, void,
! 715: private_vici_control_t *this)
! 716: {
! 717: manage_commands(this, FALSE);
! 718: free(this);
! 719: }
! 720:
! 721: /**
! 722: * See header
! 723: */
! 724: vici_control_t *vici_control_create(vici_dispatcher_t *dispatcher)
! 725: {
! 726: private_vici_control_t *this;
! 727:
! 728: INIT(this,
! 729: .public = {
! 730: .destroy = _destroy,
! 731: },
! 732: .dispatcher = dispatcher,
! 733: );
! 734:
! 735: manage_commands(this, TRUE);
! 736:
! 737: return &this->public;
! 738: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>