Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/vici_query.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2015-2017 Tobias Brunner
! 3: * Copyright (C) 2015-2018 Andreas Steffen
! 4: * HSR Hochschule fuer Technik Rapperswil
! 5: *
! 6: * Copyright (C) 2014 Martin Willi
! 7: * Copyright (C) 2014 revosec AG
! 8: *
! 9: * This program is free software; you can redistribute it and/or modify it
! 10: * under the terms of the GNU General Public License as published by the
! 11: * Free Software Foundation; either version 2 of the License, or (at your
! 12: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 13: *
! 14: * This program is distributed in the hope that it will be useful, but
! 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 17: * for more details.
! 18: */
! 19:
! 20: /*
! 21: * Copyright (C) 2014 Timo Teräs <timo.teras@iki.fi>
! 22: *
! 23: * Permission is hereby granted, free of charge, to any person obtaining a copy
! 24: * of this software and associated documentation files (the "Software"), to deal
! 25: * in the Software without restriction, including without limitation the rights
! 26: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! 27: * copies of the Software, and to permit persons to whom the Software is
! 28: * furnished to do so, subject to the following conditions:
! 29: *
! 30: * The above copyright notice and this permission notice shall be included in
! 31: * all copies or substantial portions of the Software.
! 32: *
! 33: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
! 34: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
! 35: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
! 36: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! 37: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
! 38: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
! 39: * THE SOFTWARE.
! 40: */
! 41:
! 42: #include "vici_query.h"
! 43: #include "vici_builder.h"
! 44: #include "vici_cert_info.h"
! 45:
! 46: #include <inttypes.h>
! 47: #include <time.h>
! 48: #ifndef WIN32
! 49: #include <sys/utsname.h>
! 50: #endif
! 51: #ifdef HAVE_MALLINFO
! 52: #include <malloc.h>
! 53: #endif
! 54:
! 55: #include <daemon.h>
! 56: #include <asn1/asn1.h>
! 57: #include <credentials/certificates/certificate.h>
! 58: #include <credentials/certificates/x509.h>
! 59: #include <counters_query.h>
! 60:
! 61: ENUM(vici_counter_type_names,
! 62: COUNTER_INIT_IKE_SA_REKEY, COUNTER_OUT_INFORMATIONAL_RSP,
! 63: "ike-rekey-init",
! 64: "ike-rekey-resp",
! 65: "child-rekey",
! 66: "invalid",
! 67: "invalid-spi",
! 68: "ike-init-in-req",
! 69: "ike-init-in-resp",
! 70: "ike-init-out-req",
! 71: "ike-init-out-resp",
! 72: "ike-auth-in-req",
! 73: "ike-auth-in-resp",
! 74: "ike-auth-out-req",
! 75: "ike-auth-out-resp",
! 76: "create-child-in-req",
! 77: "create-child-in-resp",
! 78: "create-child-out-req",
! 79: "create-child-out-resp",
! 80: "info-in-req",
! 81: "info-in-resp",
! 82: "info-out-req",
! 83: "info-out-resp",
! 84: );
! 85:
! 86: typedef struct private_vici_query_t private_vici_query_t;
! 87:
! 88: /**
! 89: * Private data of an vici_query_t object.
! 90: */
! 91: struct private_vici_query_t {
! 92:
! 93: /**
! 94: * Public vici_query_t interface.
! 95: */
! 96: vici_query_t public;
! 97:
! 98: /**
! 99: * Dispatcher
! 100: */
! 101: vici_dispatcher_t *dispatcher;
! 102:
! 103: /**
! 104: * Query interface for counters
! 105: */
! 106: counters_query_t *counters;
! 107:
! 108: /**
! 109: * Daemon startup timestamp
! 110: */
! 111: time_t uptime;
! 112: };
! 113:
! 114: /**
! 115: * Add the given mark/mask to the message using the provided labels
! 116: */
! 117: static void add_mark(vici_builder_t *b, mark_t mark,
! 118: char *label, char *mask_label)
! 119: {
! 120: if (mark.value | mark.mask)
! 121: {
! 122: b->add_kv(b, label, "%.8x", mark.value);
! 123: if (~mark.mask)
! 124: {
! 125: b->add_kv(b, mask_label, "%.8x", mark.mask);
! 126: }
! 127: }
! 128: }
! 129:
! 130: /**
! 131: * List the mode of a CHILD_SA or config
! 132: */
! 133: static void list_mode(vici_builder_t *b, child_sa_t *child, child_cfg_t *cfg)
! 134: {
! 135: ipsec_mode_t mode;
! 136: char *sub_mode = "";
! 137:
! 138: if (child || cfg)
! 139: {
! 140: if (!cfg)
! 141: {
! 142: cfg = child->get_config(child);
! 143: }
! 144: mode = child ? child->get_mode(child) : cfg->get_mode(cfg);
! 145: if (mode == MODE_TRANSPORT && cfg->has_option(cfg, OPT_PROXY_MODE))
! 146: { /* only report this if the negotiated mode is actually TRANSPORT */
! 147: sub_mode = "_PROXY";
! 148: }
! 149: b->add_kv(b, "mode", "%N%s", ipsec_mode_names, mode, sub_mode);
! 150: }
! 151: }
! 152:
! 153: /**
! 154: * List IPsec-related details about a CHILD_SA
! 155: */
! 156: static void list_child_ipsec(vici_builder_t *b, child_sa_t *child)
! 157: {
! 158: proposal_t *proposal;
! 159: uint16_t alg, ks;
! 160: uint32_t if_id;
! 161:
! 162: b->add_kv(b, "protocol", "%N", protocol_id_names,
! 163: child->get_protocol(child));
! 164: if (child->has_encap(child))
! 165: {
! 166: b->add_kv(b, "encap", "yes");
! 167: }
! 168: b->add_kv(b, "spi-in", "%.8x", ntohl(child->get_spi(child, TRUE)));
! 169: b->add_kv(b, "spi-out", "%.8x", ntohl(child->get_spi(child, FALSE)));
! 170:
! 171: if (child->get_ipcomp(child) != IPCOMP_NONE)
! 172: {
! 173: b->add_kv(b, "cpi-in", "%.4x", ntohs(child->get_cpi(child, TRUE)));
! 174: b->add_kv(b, "cpi-out", "%.4x", ntohs(child->get_cpi(child, FALSE)));
! 175: }
! 176: add_mark(b, child->get_mark(child, TRUE), "mark-in", "mark-mask-in");
! 177: add_mark(b, child->get_mark(child, FALSE), "mark-out", "mark-mask-out");
! 178:
! 179: if_id = child->get_if_id(child, TRUE);
! 180: if (if_id)
! 181: {
! 182: b->add_kv(b, "if-id-in", "%.8x", if_id);
! 183: }
! 184: if_id = child->get_if_id(child, FALSE);
! 185: if (if_id)
! 186: {
! 187: b->add_kv(b, "if-id-out", "%.8x", if_id);
! 188: }
! 189:
! 190: proposal = child->get_proposal(child);
! 191: if (proposal)
! 192: {
! 193: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
! 194: &alg, &ks) && alg != ENCR_UNDEFINED)
! 195: {
! 196: b->add_kv(b, "encr-alg", "%N", encryption_algorithm_names, alg);
! 197: if (ks)
! 198: {
! 199: b->add_kv(b, "encr-keysize", "%u", ks);
! 200: }
! 201: }
! 202: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
! 203: &alg, &ks) && alg != AUTH_UNDEFINED)
! 204: {
! 205: b->add_kv(b, "integ-alg", "%N", integrity_algorithm_names, alg);
! 206: if (ks)
! 207: {
! 208: b->add_kv(b, "integ-keysize", "%u", ks);
! 209: }
! 210: }
! 211: if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
! 212: &alg, NULL))
! 213: {
! 214: b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg);
! 215: }
! 216: if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS,
! 217: &alg, NULL) && alg == EXT_SEQ_NUMBERS)
! 218: {
! 219: b->add_kv(b, "esn", "1");
! 220: }
! 221: }
! 222: }
! 223:
! 224: /**
! 225: * List usage and lifetime stats of a CHILD_SA
! 226: */
! 227: static void list_child_stats(vici_builder_t *b, child_sa_t *child, time_t now)
! 228: {
! 229: uint64_t bytes, packets;
! 230: time_t t;
! 231:
! 232: child->get_usestats(child, TRUE, &t, &bytes, &packets);
! 233: b->add_kv(b, "bytes-in", "%" PRIu64, bytes);
! 234: b->add_kv(b, "packets-in", "%" PRIu64, packets);
! 235: if (t)
! 236: {
! 237: b->add_kv(b, "use-in", "%"PRIu64, (uint64_t)(now - t));
! 238: }
! 239:
! 240: child->get_usestats(child, FALSE, &t, &bytes, &packets);
! 241: b->add_kv(b, "bytes-out", "%"PRIu64, bytes);
! 242: b->add_kv(b, "packets-out", "%"PRIu64, packets);
! 243: if (t)
! 244: {
! 245: b->add_kv(b, "use-out", "%"PRIu64, (uint64_t)(now - t));
! 246: }
! 247:
! 248: t = child->get_lifetime(child, FALSE);
! 249: if (t)
! 250: {
! 251: b->add_kv(b, "rekey-time", "%"PRId64, (int64_t)(t - now));
! 252: }
! 253: t = child->get_lifetime(child, TRUE);
! 254: if (t)
! 255: {
! 256: b->add_kv(b, "life-time", "%"PRId64, (int64_t)(t - now));
! 257: }
! 258: t = child->get_installtime(child);
! 259: b->add_kv(b, "install-time", "%"PRId64, (int64_t)(now - t));
! 260: }
! 261:
! 262: /**
! 263: * List details of a CHILD_SA
! 264: */
! 265: static void list_child(private_vici_query_t *this, vici_builder_t *b,
! 266: child_sa_t *child, time_t now)
! 267: {
! 268: enumerator_t *enumerator;
! 269: traffic_selector_t *ts;
! 270: child_sa_state_t state;
! 271:
! 272: b->add_kv(b, "name", "%s", child->get_name(child));
! 273: b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child));
! 274: b->add_kv(b, "reqid", "%u", child->get_reqid(child));
! 275: state = child->get_state(child);
! 276: b->add_kv(b, "state", "%N", child_sa_state_names, state);
! 277: list_mode(b, child, NULL);
! 278:
! 279: switch (state)
! 280: {
! 281: case CHILD_INSTALLED:
! 282: case CHILD_REKEYING:
! 283: case CHILD_REKEYED:
! 284: case CHILD_DELETING:
! 285: case CHILD_DELETED:
! 286: list_child_ipsec(b, child);
! 287: list_child_stats(b, child, now);
! 288: break;
! 289: default:
! 290: break;
! 291: }
! 292:
! 293: b->begin_list(b, "local-ts");
! 294: enumerator = child->create_ts_enumerator(child, TRUE);
! 295: while (enumerator->enumerate(enumerator, &ts))
! 296: {
! 297: b->add_li(b, "%R", ts);
! 298: }
! 299: enumerator->destroy(enumerator);
! 300: b->end_list(b /* local-ts */);
! 301:
! 302: b->begin_list(b, "remote-ts");
! 303: enumerator = child->create_ts_enumerator(child, FALSE);
! 304: while (enumerator->enumerate(enumerator, &ts))
! 305: {
! 306: b->add_li(b, "%R", ts);
! 307: }
! 308: enumerator->destroy(enumerator);
! 309: b->end_list(b /* remote-ts */);
! 310: }
! 311:
! 312: /**
! 313: * List tasks in a specific queue
! 314: */
! 315: static void list_task_queue(private_vici_query_t *this, vici_builder_t *b,
! 316: ike_sa_t *ike_sa, task_queue_t q, char *name)
! 317: {
! 318: enumerator_t *enumerator;
! 319: bool has = FALSE;
! 320: task_t *task;
! 321:
! 322: enumerator = ike_sa->create_task_enumerator(ike_sa, q);
! 323: while (enumerator->enumerate(enumerator, &task))
! 324: {
! 325: if (!has)
! 326: {
! 327: b->begin_list(b, name);
! 328: has = TRUE;
! 329: }
! 330: b->add_li(b, "%N", task_type_names, task->get_type(task));
! 331: }
! 332: enumerator->destroy(enumerator);
! 333: if (has)
! 334: {
! 335: b->end_list(b);
! 336: }
! 337: }
! 338:
! 339: /**
! 340: * Add an IKE_SA condition to the given builder
! 341: */
! 342: static void add_condition(vici_builder_t *b, ike_sa_t *ike_sa,
! 343: char *key, ike_condition_t cond)
! 344: {
! 345: if (ike_sa->has_condition(ike_sa, cond))
! 346: {
! 347: b->add_kv(b, key, "yes");
! 348: }
! 349: }
! 350:
! 351: /**
! 352: * List virtual IPs
! 353: */
! 354: static void list_vips(private_vici_query_t *this, vici_builder_t *b,
! 355: ike_sa_t *ike_sa, bool local, char *name)
! 356: {
! 357: enumerator_t *enumerator;
! 358: bool has = FALSE;
! 359: host_t *vip;
! 360:
! 361: enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
! 362: while (enumerator->enumerate(enumerator, &vip))
! 363: {
! 364: if (!has)
! 365: {
! 366: b->begin_list(b, name);
! 367: has = TRUE;
! 368: }
! 369: b->add_li(b, "%H", vip);
! 370: }
! 371: enumerator->destroy(enumerator);
! 372: if (has)
! 373: {
! 374: b->end_list(b);
! 375: }
! 376: }
! 377:
! 378: /**
! 379: * List details of an IKE_SA
! 380: */
! 381: static void list_ike(private_vici_query_t *this, vici_builder_t *b,
! 382: ike_sa_t *ike_sa, time_t now)
! 383: {
! 384: time_t t;
! 385: ike_sa_id_t *id;
! 386: identification_t *eap;
! 387: proposal_t *proposal;
! 388: uint32_t if_id;
! 389: uint16_t alg, ks;
! 390: host_t *host;
! 391:
! 392: b->add_kv(b, "uniqueid", "%u", ike_sa->get_unique_id(ike_sa));
! 393: b->add_kv(b, "version", "%u", ike_sa->get_version(ike_sa));
! 394: b->add_kv(b, "state", "%N", ike_sa_state_names, ike_sa->get_state(ike_sa));
! 395:
! 396: host = ike_sa->get_my_host(ike_sa);
! 397: b->add_kv(b, "local-host", "%H", host);
! 398: b->add_kv(b, "local-port", "%d", host->get_port(host));
! 399: b->add_kv(b, "local-id", "%Y", ike_sa->get_my_id(ike_sa));
! 400:
! 401: host = ike_sa->get_other_host(ike_sa);
! 402: b->add_kv(b, "remote-host", "%H", host);
! 403: b->add_kv(b, "remote-port", "%d", host->get_port(host));
! 404: b->add_kv(b, "remote-id", "%Y", ike_sa->get_other_id(ike_sa));
! 405:
! 406: eap = ike_sa->get_other_eap_id(ike_sa);
! 407:
! 408: if (!eap->equals(eap, ike_sa->get_other_id(ike_sa)))
! 409: {
! 410: if (ike_sa->get_version(ike_sa) == IKEV1)
! 411: {
! 412: b->add_kv(b, "remote-xauth-id", "%Y", eap);
! 413: }
! 414: else
! 415: {
! 416: b->add_kv(b, "remote-eap-id", "%Y", eap);
! 417: }
! 418: }
! 419:
! 420: id = ike_sa->get_id(ike_sa);
! 421: if (id->is_initiator(id))
! 422: {
! 423: b->add_kv(b, "initiator", "yes");
! 424: }
! 425: b->add_kv(b, "initiator-spi", "%.16"PRIx64,
! 426: be64toh(id->get_initiator_spi(id)));
! 427: b->add_kv(b, "responder-spi", "%.16"PRIx64,
! 428: be64toh(id->get_responder_spi(id)));
! 429:
! 430: add_condition(b, ike_sa, "nat-local", COND_NAT_HERE);
! 431: add_condition(b, ike_sa, "nat-remote", COND_NAT_THERE);
! 432: add_condition(b, ike_sa, "nat-fake", COND_NAT_FAKE);
! 433: add_condition(b, ike_sa, "nat-any", COND_NAT_ANY);
! 434:
! 435: if_id = ike_sa->get_if_id(ike_sa, TRUE);
! 436: if (if_id)
! 437: {
! 438: b->add_kv(b, "if-id-in", "%.8x", if_id);
! 439: }
! 440: if_id = ike_sa->get_if_id(ike_sa, FALSE);
! 441: if (if_id)
! 442: {
! 443: b->add_kv(b, "if-id-out", "%.8x", if_id);
! 444: }
! 445:
! 446: proposal = ike_sa->get_proposal(ike_sa);
! 447: if (proposal)
! 448: {
! 449: if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &ks))
! 450: {
! 451: b->add_kv(b, "encr-alg", "%N", encryption_algorithm_names, alg);
! 452: if (ks)
! 453: {
! 454: b->add_kv(b, "encr-keysize", "%u", ks);
! 455: }
! 456: }
! 457: if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, &ks))
! 458: {
! 459: b->add_kv(b, "integ-alg", "%N", integrity_algorithm_names, alg);
! 460: if (ks)
! 461: {
! 462: b->add_kv(b, "integ-keysize", "%u", ks);
! 463: }
! 464: }
! 465: if (proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
! 466: {
! 467: b->add_kv(b, "prf-alg", "%N", pseudo_random_function_names, alg);
! 468: }
! 469: if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &alg, NULL))
! 470: {
! 471: b->add_kv(b, "dh-group", "%N", diffie_hellman_group_names, alg);
! 472: }
! 473: }
! 474: add_condition(b, ike_sa, "ppk", COND_PPK);
! 475:
! 476: if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
! 477: {
! 478: t = ike_sa->get_statistic(ike_sa, STAT_ESTABLISHED);
! 479: b->add_kv(b, "established", "%"PRId64, (int64_t)(now - t));
! 480: t = ike_sa->get_statistic(ike_sa, STAT_REKEY);
! 481: if (t)
! 482: {
! 483: b->add_kv(b, "rekey-time", "%"PRId64, (int64_t)(t - now));
! 484: }
! 485: t = ike_sa->get_statistic(ike_sa, STAT_REAUTH);
! 486: if (t)
! 487: {
! 488: b->add_kv(b, "reauth-time", "%"PRId64, (int64_t)(t - now));
! 489: }
! 490: }
! 491:
! 492: list_vips(this, b, ike_sa, TRUE, "local-vips");
! 493: list_vips(this, b, ike_sa, FALSE, "remote-vips");
! 494:
! 495: list_task_queue(this, b, ike_sa, TASK_QUEUE_QUEUED, "tasks-queued");
! 496: list_task_queue(this, b, ike_sa, TASK_QUEUE_ACTIVE, "tasks-active");
! 497: list_task_queue(this, b, ike_sa, TASK_QUEUE_PASSIVE, "tasks-passive");
! 498: }
! 499:
! 500: CALLBACK(list_sas, vici_message_t*,
! 501: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 502: {
! 503: vici_builder_t *b;
! 504: enumerator_t *isas, *csas;
! 505: ike_sa_t *ike_sa;
! 506: child_sa_t *child_sa;
! 507: time_t now;
! 508: char *ike;
! 509: u_int ike_id;
! 510: bool bl;
! 511: char buf[BUF_LEN];
! 512:
! 513: bl = request->get_str(request, NULL, "noblock") == NULL;
! 514: ike = request->get_str(request, NULL, "ike");
! 515: ike_id = request->get_int(request, 0, "ike-id");
! 516:
! 517: isas = charon->controller->create_ike_sa_enumerator(charon->controller, bl);
! 518: while (isas->enumerate(isas, &ike_sa))
! 519: {
! 520: if (ike && !streq(ike, ike_sa->get_name(ike_sa)))
! 521: {
! 522: continue;
! 523: }
! 524: if (ike_id && ike_id != ike_sa->get_unique_id(ike_sa))
! 525: {
! 526: continue;
! 527: }
! 528:
! 529: now = time_monotonic(NULL);
! 530:
! 531: b = vici_builder_create();
! 532: b->begin_section(b, ike_sa->get_name(ike_sa));
! 533:
! 534: list_ike(this, b, ike_sa, now);
! 535:
! 536: b->begin_section(b, "child-sas");
! 537: csas = ike_sa->create_child_sa_enumerator(ike_sa);
! 538: while (csas->enumerate(csas, &child_sa))
! 539: {
! 540: snprintf(buf, sizeof(buf), "%s-%u", child_sa->get_name(child_sa),
! 541: child_sa->get_unique_id(child_sa));
! 542: b->begin_section(b, buf);
! 543: list_child(this, b, child_sa, now);
! 544: b->end_section(b);
! 545: }
! 546: csas->destroy(csas);
! 547: b->end_section(b /* child-sas */ );
! 548:
! 549: b->end_section(b);
! 550:
! 551: this->dispatcher->raise_event(this->dispatcher, "list-sa", id,
! 552: b->finalize(b));
! 553: }
! 554: isas->destroy(isas);
! 555:
! 556: b = vici_builder_create();
! 557: return b->finalize(b);
! 558: }
! 559:
! 560: /**
! 561: * Raise a list-policy event for given CHILD_SA
! 562: */
! 563: static void raise_policy(private_vici_query_t *this, u_int id, char *ike,
! 564: child_sa_t *child)
! 565: {
! 566: enumerator_t *enumerator;
! 567: traffic_selector_t *ts;
! 568: vici_builder_t *b;
! 569: char buf[BUF_LEN];
! 570:
! 571: b = vici_builder_create();
! 572: snprintf(buf, sizeof(buf), "%s/%s", ike, child->get_name(child));
! 573: b->begin_section(b, buf);
! 574: b->add_kv(b, "child", "%s", child->get_name(child));
! 575: b->add_kv(b, "ike", "%s", ike);
! 576:
! 577: list_mode(b, child, NULL);
! 578:
! 579: b->begin_list(b, "local-ts");
! 580: enumerator = child->create_ts_enumerator(child, TRUE);
! 581: while (enumerator->enumerate(enumerator, &ts))
! 582: {
! 583: b->add_li(b, "%R", ts);
! 584: }
! 585: enumerator->destroy(enumerator);
! 586: b->end_list(b /* local-ts */);
! 587:
! 588: b->begin_list(b, "remote-ts");
! 589: enumerator = child->create_ts_enumerator(child, FALSE);
! 590: while (enumerator->enumerate(enumerator, &ts))
! 591: {
! 592: b->add_li(b, "%R", ts);
! 593: }
! 594: enumerator->destroy(enumerator);
! 595: b->end_list(b /* remote-ts */);
! 596:
! 597: b->end_section(b);
! 598:
! 599: this->dispatcher->raise_event(this->dispatcher, "list-policy", id,
! 600: b->finalize(b));
! 601: }
! 602:
! 603: /**
! 604: * Raise a list-policy event for given CHILD_SA config
! 605: */
! 606: static void raise_policy_cfg(private_vici_query_t *this, u_int id, char *ike,
! 607: child_cfg_t *cfg)
! 608: {
! 609: enumerator_t *enumerator;
! 610: linked_list_t *list;
! 611: traffic_selector_t *ts;
! 612: vici_builder_t *b;
! 613: char buf[BUF_LEN];
! 614:
! 615: b = vici_builder_create();
! 616: snprintf(buf, sizeof(buf), "%s%s%s", ike ? ike : "", ike ? "/" : "",
! 617: cfg->get_name(cfg));
! 618: b->begin_section(b, buf);
! 619: b->add_kv(b, "child", "%s", cfg->get_name(cfg));
! 620: if (ike)
! 621: {
! 622: b->add_kv(b, "ike", "%s", ike);
! 623: }
! 624:
! 625: list_mode(b, NULL, cfg);
! 626:
! 627: b->begin_list(b, "local-ts");
! 628: list = cfg->get_traffic_selectors(cfg, TRUE, NULL, NULL, FALSE);
! 629: enumerator = list->create_enumerator(list);
! 630: while (enumerator->enumerate(enumerator, &ts))
! 631: {
! 632: b->add_li(b, "%R", ts);
! 633: }
! 634: enumerator->destroy(enumerator);
! 635: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
! 636: b->end_list(b /* local-ts */);
! 637:
! 638: b->begin_list(b, "remote-ts");
! 639: list = cfg->get_traffic_selectors(cfg, FALSE, NULL, NULL, FALSE);
! 640: enumerator = list->create_enumerator(list);
! 641: while (enumerator->enumerate(enumerator, &ts))
! 642: {
! 643: b->add_li(b, "%R", ts);
! 644: }
! 645: enumerator->destroy(enumerator);
! 646: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
! 647: b->end_list(b /* remote-ts */);
! 648:
! 649: b->end_section(b);
! 650:
! 651: this->dispatcher->raise_event(this->dispatcher, "list-policy", id,
! 652: b->finalize(b));
! 653: }
! 654:
! 655: CALLBACK(list_policies, vici_message_t*,
! 656: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 657: {
! 658: enumerator_t *enumerator;
! 659: vici_builder_t *b;
! 660: child_sa_t *child_sa;
! 661: peer_cfg_t *peer_cfg;
! 662: child_cfg_t *child_cfg;
! 663: bool drop, pass, trap;
! 664: char *child, *ike, *ns;
! 665:
! 666: drop = request->get_str(request, NULL, "drop") != NULL;
! 667: pass = request->get_str(request, NULL, "pass") != NULL;
! 668: trap = request->get_str(request, NULL, "trap") != NULL;
! 669: child = request->get_str(request, NULL, "child");
! 670: ike = request->get_str(request, NULL, "ike");
! 671:
! 672: if (trap)
! 673: {
! 674: enumerator = charon->traps->create_enumerator(charon->traps);
! 675: while (enumerator->enumerate(enumerator, &peer_cfg, &child_sa))
! 676: {
! 677: if ((ike && !streq(ike, peer_cfg->get_name(peer_cfg))) ||
! 678: (child && !streq(child, child_sa->get_name(child_sa))))
! 679: {
! 680: continue;
! 681: }
! 682: raise_policy(this, id, peer_cfg->get_name(peer_cfg), child_sa);
! 683: }
! 684: enumerator->destroy(enumerator);
! 685: }
! 686:
! 687: if (drop || pass)
! 688: {
! 689: enumerator = charon->shunts->create_enumerator(charon->shunts);
! 690: while (enumerator->enumerate(enumerator, &ns, &child_cfg))
! 691: {
! 692: if ((ike && !streq(ike, ns)) ||
! 693: (child && !streq(child, child_cfg->get_name(child_cfg))))
! 694: {
! 695: continue;
! 696: }
! 697: switch (child_cfg->get_mode(child_cfg))
! 698: {
! 699: case MODE_DROP:
! 700: if (drop)
! 701: {
! 702: raise_policy_cfg(this, id, ns, child_cfg);
! 703: }
! 704: break;
! 705: case MODE_PASS:
! 706: if (pass)
! 707: {
! 708: raise_policy_cfg(this, id, ns, child_cfg);
! 709: }
! 710: break;
! 711: default:
! 712: break;
! 713: }
! 714: }
! 715: enumerator->destroy(enumerator);
! 716: }
! 717:
! 718: b = vici_builder_create();
! 719: return b->finalize(b);
! 720: }
! 721:
! 722: /**
! 723: * Build sections for auth configs, local or remote
! 724: */
! 725: static void build_auth_cfgs(peer_cfg_t *peer_cfg, bool local, vici_builder_t *b)
! 726: {
! 727: enumerator_t *enumerator, *rules;
! 728: auth_rule_t rule;
! 729: auth_cfg_t *auth;
! 730: union {
! 731: uintptr_t u;
! 732: identification_t *id;
! 733: certificate_t *cert;
! 734: char *str;
! 735: } v;
! 736: char buf[32];
! 737: int i = 0;
! 738:
! 739: enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
! 740: while (enumerator->enumerate(enumerator, &auth))
! 741: {
! 742: snprintf(buf, sizeof(buf), "%s-%d", local ? "local" : "remote", ++i);
! 743: b->begin_section(b, buf);
! 744:
! 745: rules = auth->create_enumerator(auth);
! 746: while (rules->enumerate(rules, &rule, &v))
! 747: {
! 748: switch (rule)
! 749: {
! 750: case AUTH_RULE_AUTH_CLASS:
! 751: b->add_kv(b, "class", "%N", auth_class_names, v.u);
! 752: break;
! 753: case AUTH_RULE_EAP_TYPE:
! 754: b->add_kv(b, "eap-type", "%N", eap_type_names, v.u);
! 755: break;
! 756: case AUTH_RULE_EAP_VENDOR:
! 757: b->add_kv(b, "eap-vendor", "%u", v.u);
! 758: break;
! 759: case AUTH_RULE_XAUTH_BACKEND:
! 760: b->add_kv(b, "xauth", "%s", v.str);
! 761: break;
! 762: case AUTH_RULE_CRL_VALIDATION:
! 763: b->add_kv(b, "revocation", "%N", cert_validation_names, v.u);
! 764: break;
! 765: case AUTH_RULE_IDENTITY:
! 766: b->add_kv(b, "id", "%Y", v.id);
! 767: break;
! 768: case AUTH_RULE_CA_IDENTITY:
! 769: b->add_kv(b, "ca_id", "%Y", v.id);
! 770: break;
! 771: case AUTH_RULE_AAA_IDENTITY:
! 772: b->add_kv(b, "aaa_id", "%Y", v.id);
! 773: break;
! 774: case AUTH_RULE_EAP_IDENTITY:
! 775: b->add_kv(b, "eap_id", "%Y", v.id);
! 776: break;
! 777: case AUTH_RULE_XAUTH_IDENTITY:
! 778: b->add_kv(b, "xauth_id", "%Y", v.id);
! 779: break;
! 780: default:
! 781: break;
! 782: }
! 783: }
! 784: rules->destroy(rules);
! 785:
! 786: b->begin_list(b, "groups");
! 787: rules = auth->create_enumerator(auth);
! 788: while (rules->enumerate(rules, &rule, &v))
! 789: {
! 790: if (rule == AUTH_RULE_GROUP)
! 791: {
! 792: b->add_li(b, "%Y", v.id);
! 793: }
! 794: }
! 795: rules->destroy(rules);
! 796: b->end_list(b);
! 797:
! 798: b->begin_list(b, "cert_policy");
! 799: rules = auth->create_enumerator(auth);
! 800: while (rules->enumerate(rules, &rule, &v))
! 801: {
! 802: if (rule == AUTH_RULE_CERT_POLICY)
! 803: {
! 804: b->add_li(b, "%s", v.str);
! 805: }
! 806: }
! 807: rules->destroy(rules);
! 808: b->end_list(b);
! 809:
! 810: b->begin_list(b, "certs");
! 811: rules = auth->create_enumerator(auth);
! 812: while (rules->enumerate(rules, &rule, &v))
! 813: {
! 814: if (rule == AUTH_RULE_SUBJECT_CERT)
! 815: {
! 816: b->add_li(b, "%Y", v.cert->get_subject(v.cert));
! 817: }
! 818: }
! 819: rules->destroy(rules);
! 820: b->end_list(b);
! 821:
! 822: b->begin_list(b, "cacerts");
! 823: rules = auth->create_enumerator(auth);
! 824: while (rules->enumerate(rules, &rule, &v))
! 825: {
! 826: if (rule == AUTH_RULE_CA_CERT)
! 827: {
! 828: b->add_li(b, "%Y", v.cert->get_subject(v.cert));
! 829: }
! 830: }
! 831: rules->destroy(rules);
! 832: b->end_list(b);
! 833:
! 834: b->end_section(b);
! 835: }
! 836: enumerator->destroy(enumerator);
! 837: }
! 838:
! 839: CALLBACK(list_conns, vici_message_t*,
! 840: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 841: {
! 842: enumerator_t *enumerator, *tokens, *selectors, *children;
! 843: peer_cfg_t *peer_cfg;
! 844: ike_cfg_t *ike_cfg;
! 845: child_cfg_t *child_cfg;
! 846: char *ike, *str, *interface;
! 847: uint32_t manual_prio, dpd_delay, dpd_timeout;
! 848: identification_t *ppk_id;
! 849: linked_list_t *list;
! 850: traffic_selector_t *ts;
! 851: lifetime_cfg_t *lft;
! 852: vici_builder_t *b;
! 853:
! 854: ike = request->get_str(request, NULL, "ike");
! 855:
! 856: enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
! 857: NULL, NULL, NULL, NULL, IKE_ANY);
! 858: while (enumerator->enumerate(enumerator, &peer_cfg))
! 859: {
! 860: if (ike && !streq(ike, peer_cfg->get_name(peer_cfg)))
! 861: {
! 862: continue;
! 863: }
! 864:
! 865: b = vici_builder_create();
! 866: b->begin_section(b, peer_cfg->get_name(peer_cfg));
! 867:
! 868: ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
! 869:
! 870: b->begin_list(b, "local_addrs");
! 871: str = ike_cfg->get_my_addr(ike_cfg);
! 872: tokens = enumerator_create_token(str, ",", " ");
! 873: while (tokens->enumerate(tokens, &str))
! 874: {
! 875: b->add_li(b, "%s", str);
! 876: }
! 877: tokens->destroy(tokens);
! 878: b->end_list(b);
! 879:
! 880: b->begin_list(b, "remote_addrs");
! 881: str = ike_cfg->get_other_addr(ike_cfg);
! 882: tokens = enumerator_create_token(str, ",", " ");
! 883: while (tokens->enumerate(tokens, &str))
! 884: {
! 885: b->add_li(b, "%s", str);
! 886: }
! 887: tokens->destroy(tokens);
! 888: b->end_list(b);
! 889:
! 890: b->add_kv(b, "version", "%N", ike_version_names,
! 891: peer_cfg->get_ike_version(peer_cfg));
! 892: b->add_kv(b, "reauth_time", "%u",
! 893: peer_cfg->get_reauth_time(peer_cfg, FALSE));
! 894: b->add_kv(b, "rekey_time", "%u",
! 895: peer_cfg->get_rekey_time(peer_cfg, FALSE));
! 896: b->add_kv(b, "unique", "%N", unique_policy_names,
! 897: peer_cfg->get_unique_policy(peer_cfg));
! 898:
! 899: dpd_delay = peer_cfg->get_dpd(peer_cfg);
! 900: if (dpd_delay)
! 901: {
! 902: b->add_kv(b, "dpd_delay", "%u", dpd_delay);
! 903: }
! 904:
! 905: dpd_timeout = peer_cfg->get_dpd_timeout(peer_cfg);
! 906: if (dpd_timeout)
! 907: {
! 908: b->add_kv(b, "dpd_timeout", "%u", dpd_timeout);
! 909: }
! 910:
! 911: ppk_id = peer_cfg->get_ppk_id(peer_cfg);
! 912: if (ppk_id)
! 913: {
! 914: b->add_kv(b, "ppk_id", "%Y", ppk_id);
! 915: }
! 916: if (peer_cfg->ppk_required(peer_cfg))
! 917: {
! 918: b->add_kv(b, "ppk_required", "yes");
! 919: }
! 920:
! 921: build_auth_cfgs(peer_cfg, TRUE, b);
! 922: build_auth_cfgs(peer_cfg, FALSE, b);
! 923:
! 924: b->begin_section(b, "children");
! 925:
! 926: children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
! 927: while (children->enumerate(children, &child_cfg))
! 928: {
! 929: b->begin_section(b, child_cfg->get_name(child_cfg));
! 930:
! 931: list_mode(b, NULL, child_cfg);
! 932:
! 933: lft = child_cfg->get_lifetime(child_cfg, FALSE);
! 934: b->add_kv(b, "rekey_time", "%"PRIu64, lft->time.rekey);
! 935: b->add_kv(b, "rekey_bytes", "%"PRIu64, lft->bytes.rekey);
! 936: b->add_kv(b, "rekey_packets", "%"PRIu64, lft->packets.rekey);
! 937: free(lft);
! 938:
! 939: b->add_kv(b, "dpd_action", "%N", action_names,
! 940: child_cfg->get_dpd_action(child_cfg));
! 941: b->add_kv(b, "close_action", "%N", action_names,
! 942: child_cfg->get_close_action(child_cfg));
! 943:
! 944: b->begin_list(b, "local-ts");
! 945: list = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL,
! 946: NULL, FALSE);
! 947: selectors = list->create_enumerator(list);
! 948: while (selectors->enumerate(selectors, &ts))
! 949: {
! 950: b->add_li(b, "%R", ts);
! 951: }
! 952: selectors->destroy(selectors);
! 953: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
! 954: b->end_list(b /* local-ts */);
! 955:
! 956: b->begin_list(b, "remote-ts");
! 957: list = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL,
! 958: NULL, FALSE);
! 959: selectors = list->create_enumerator(list);
! 960: while (selectors->enumerate(selectors, &ts))
! 961: {
! 962: b->add_li(b, "%R", ts);
! 963: }
! 964: selectors->destroy(selectors);
! 965: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
! 966: b->end_list(b /* remote-ts */);
! 967:
! 968: interface = child_cfg->get_interface(child_cfg);
! 969: if (interface)
! 970: {
! 971: b->add_kv(b, "interface", "%s", interface);
! 972: }
! 973:
! 974: manual_prio = child_cfg->get_manual_prio(child_cfg);
! 975: if (manual_prio)
! 976: {
! 977: b->add_kv(b, "priority", "%u", manual_prio);
! 978: }
! 979:
! 980: b->end_section(b);
! 981: }
! 982: children->destroy(children);
! 983:
! 984: b->end_section(b); /* children */
! 985:
! 986: b->end_section(b); /* name */
! 987:
! 988: this->dispatcher->raise_event(this->dispatcher, "list-conn", id,
! 989: b->finalize(b));
! 990: }
! 991: enumerator->destroy(enumerator);
! 992:
! 993: b = vici_builder_create();
! 994: return b->finalize(b);
! 995: }
! 996:
! 997: /**
! 998: * Do we have a private key for given certificate
! 999: */
! 1000: static bool has_privkey(certificate_t *cert)
! 1001: {
! 1002: private_key_t *private;
! 1003: public_key_t *public;
! 1004: identification_t *keyid;
! 1005: chunk_t chunk;
! 1006: bool found = FALSE;
! 1007:
! 1008: public = cert->get_public_key(cert);
! 1009: if (public)
! 1010: {
! 1011: if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &chunk))
! 1012: {
! 1013: keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
! 1014: private = lib->credmgr->get_private(lib->credmgr,
! 1015: public->get_type(public), keyid, NULL);
! 1016: if (private)
! 1017: {
! 1018: found = TRUE;
! 1019: private->destroy(private);
! 1020: }
! 1021: keyid->destroy(keyid);
! 1022: }
! 1023: public->destroy(public);
! 1024: }
! 1025: return found;
! 1026: }
! 1027:
! 1028: /**
! 1029: * Store cert filter data
! 1030: */
! 1031: typedef struct {
! 1032: certificate_type_t type;
! 1033: x509_flag_t flag;
! 1034: identification_t *subject;
! 1035: } cert_filter_t;
! 1036:
! 1037: /**
! 1038: * Enumerate all X.509 certificates with a given flag
! 1039: */
! 1040: static void enum_x509(private_vici_query_t *this, u_int id,
! 1041: linked_list_t *certs, cert_filter_t *filter,
! 1042: x509_flag_t flag)
! 1043: {
! 1044: enumerator_t *enumerator;
! 1045: certificate_t *cert;
! 1046: vici_builder_t *b;
! 1047: chunk_t encoding;
! 1048: x509_t *x509;
! 1049:
! 1050: if (filter->type != CERT_ANY && filter->flag != X509_ANY &&
! 1051: filter->flag != flag)
! 1052: {
! 1053: return;
! 1054: }
! 1055:
! 1056: enumerator = certs->create_enumerator(certs);
! 1057: while (enumerator->enumerate(enumerator, &cert))
! 1058: {
! 1059: x509 = (x509_t*)cert;
! 1060: if ((x509->get_flags(x509) & X509_ANY) != flag)
! 1061: {
! 1062: continue;
! 1063: }
! 1064:
! 1065: if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
! 1066: {
! 1067: b = vici_builder_create();
! 1068: b->add_kv(b, "type", "%N", certificate_type_names, CERT_X509);
! 1069: b->add_kv(b, "flag", "%N", x509_flag_names, flag);
! 1070: if (has_privkey(cert))
! 1071: {
! 1072: b->add_kv(b, "has_privkey", "yes");
! 1073: }
! 1074: b->add(b, VICI_KEY_VALUE, "data", encoding);
! 1075: free(encoding.ptr);
! 1076:
! 1077: this->dispatcher->raise_event(this->dispatcher, "list-cert", id,
! 1078: b->finalize(b));
! 1079: }
! 1080: }
! 1081: enumerator->destroy(enumerator);
! 1082: }
! 1083:
! 1084: /**
! 1085: * Enumerate all non-X.509 certificate types
! 1086: */
! 1087: static void enum_others(private_vici_query_t *this, u_int id,
! 1088: linked_list_t *certs, certificate_type_t type)
! 1089: {
! 1090: enumerator_t *enumerator;
! 1091: certificate_t *cert;
! 1092: vici_builder_t *b;
! 1093: chunk_t encoding, t_ch;
! 1094: cred_encoding_type_t encoding_type;
! 1095: identification_t *subject;
! 1096: time_t not_before, not_after;
! 1097:
! 1098: encoding_type = (type == CERT_TRUSTED_PUBKEY) ? PUBKEY_SPKI_ASN1_DER :
! 1099: CERT_ASN1_DER;
! 1100:
! 1101: enumerator = certs->create_enumerator(certs);
! 1102: while (enumerator->enumerate(enumerator, &cert))
! 1103: {
! 1104: if (cert->get_encoding(cert, encoding_type, &encoding))
! 1105: {
! 1106: b = vici_builder_create();
! 1107: b->add_kv(b, "type", "%N", certificate_type_names, type);
! 1108: if (has_privkey(cert))
! 1109: {
! 1110: b->add_kv(b, "has_privkey", "yes");
! 1111: }
! 1112: b->add(b, VICI_KEY_VALUE, "data", encoding);
! 1113: free(encoding.ptr);
! 1114:
! 1115: if (type == CERT_TRUSTED_PUBKEY)
! 1116: {
! 1117: subject = cert->get_subject(cert);
! 1118: if (subject->get_type(subject) != ID_KEY_ID)
! 1119: {
! 1120: b->add_kv(b, "subject", "%Y", cert->get_subject(cert));
! 1121: }
! 1122: cert->get_validity(cert, NULL, ¬_before, ¬_after);
! 1123: if (not_before != UNDEFINED_TIME)
! 1124: {
! 1125: t_ch = asn1_from_time(¬_before, ASN1_GENERALIZEDTIME);
! 1126: b->add(b, VICI_KEY_VALUE, "not-before", chunk_skip(t_ch, 2));
! 1127: chunk_free(&t_ch);
! 1128: }
! 1129: if (not_after != UNDEFINED_TIME)
! 1130: {
! 1131: t_ch = asn1_from_time(¬_after, ASN1_GENERALIZEDTIME);
! 1132: b->add(b, VICI_KEY_VALUE, "not-after", chunk_skip(t_ch, 2));
! 1133: chunk_free(&t_ch);
! 1134: }
! 1135: }
! 1136: this->dispatcher->raise_event(this->dispatcher, "list-cert", id,
! 1137: b->finalize(b));
! 1138: }
! 1139: }
! 1140: enumerator->destroy(enumerator);
! 1141: }
! 1142:
! 1143: /**
! 1144: * Enumerate all certificates of a given type
! 1145: */
! 1146: static void enum_certs(private_vici_query_t *this, u_int id,
! 1147: cert_filter_t *filter, certificate_type_t type)
! 1148: {
! 1149: enumerator_t *e1, *e2;
! 1150: certificate_t *cert, *current;
! 1151: linked_list_t *certs;
! 1152: bool found;
! 1153:
! 1154: if (filter->type != CERT_ANY && filter->type != type)
! 1155: {
! 1156: return;
! 1157: }
! 1158: certs = linked_list_create();
! 1159:
! 1160: e1 = lib->credmgr->create_cert_enumerator(lib->credmgr, type, KEY_ANY,
! 1161: filter->subject, FALSE);
! 1162: while (e1->enumerate(e1, &cert))
! 1163: {
! 1164: found = FALSE;
! 1165:
! 1166: e2 = certs->create_enumerator(certs);
! 1167: while (e2->enumerate(e2, ¤t))
! 1168: {
! 1169: if (current->equals(current, cert))
! 1170: {
! 1171: found = TRUE;
! 1172: break;
! 1173: }
! 1174: }
! 1175: e2->destroy(e2);
! 1176:
! 1177: if (!found)
! 1178: {
! 1179: certs->insert_last(certs, cert->get_ref(cert));
! 1180: }
! 1181: }
! 1182: e1->destroy(e1);
! 1183:
! 1184: if (type == CERT_X509)
! 1185: {
! 1186: enum_x509(this, id, certs, filter, X509_NONE);
! 1187: enum_x509(this, id, certs, filter, X509_CA);
! 1188: enum_x509(this, id, certs, filter, X509_AA);
! 1189: enum_x509(this, id, certs, filter, X509_OCSP_SIGNER);
! 1190: }
! 1191: else
! 1192: {
! 1193: enum_others(this, id, certs, type);
! 1194: }
! 1195: certs->destroy_offset(certs, offsetof(certificate_t, destroy));
! 1196: }
! 1197:
! 1198: CALLBACK(list_certs, vici_message_t*,
! 1199: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1200: {
! 1201: cert_filter_t filter = {
! 1202: .type = CERT_ANY,
! 1203: .flag = X509_ANY,
! 1204: .subject = NULL
! 1205: };
! 1206: vici_builder_t *b;
! 1207: char *str;
! 1208:
! 1209: str = request->get_str(request, "ANY", "type");
! 1210: if (enum_from_name(certificate_type_names, str, &filter.type))
! 1211: {
! 1212: if (filter.type == CERT_X509)
! 1213: {
! 1214: str = request->get_str(request, "ANY", "flag");
! 1215: if (!enum_from_name(x509_flag_names, str, &filter.flag))
! 1216: {
! 1217: DBG1(DBG_CFG, "invalid certificate flag '%s'", str);
! 1218: goto finalize;
! 1219: }
! 1220: }
! 1221: }
! 1222: else if (!vici_cert_info_from_str(str, &filter.type, &filter.flag))
! 1223: {
! 1224: DBG1(DBG_CFG, "invalid certificate type '%s'", str);
! 1225: goto finalize;
! 1226: }
! 1227:
! 1228: str = request->get_str(request, NULL, "subject");
! 1229: if (str)
! 1230: {
! 1231: filter.subject = identification_create_from_string(str);
! 1232: }
! 1233:
! 1234: enum_certs(this, id, &filter, CERT_TRUSTED_PUBKEY);
! 1235: enum_certs(this, id, &filter, CERT_X509);
! 1236: enum_certs(this, id, &filter, CERT_X509_AC);
! 1237: enum_certs(this, id, &filter, CERT_X509_CRL);
! 1238: enum_certs(this, id, &filter, CERT_X509_OCSP_RESPONSE);
! 1239: DESTROY_IF(filter.subject);
! 1240:
! 1241: finalize:
! 1242: b = vici_builder_create();
! 1243: return b->finalize(b);
! 1244: }
! 1245:
! 1246: /**
! 1247: * Add a key/value pair of ALG => plugin
! 1248: */
! 1249: static void add_algorithm(vici_builder_t *b, enum_name_t *alg_names,
! 1250: int alg_type, const char *plugin_name)
! 1251: {
! 1252: char alg_name[BUF_LEN];
! 1253:
! 1254: sprintf(alg_name, "%N", alg_names, alg_type);
! 1255: b->add_kv(b, alg_name, (char*)plugin_name);
! 1256: }
! 1257:
! 1258: CALLBACK(get_algorithms, vici_message_t*,
! 1259: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1260: {
! 1261: vici_builder_t *b;
! 1262: enumerator_t *enumerator;
! 1263: encryption_algorithm_t encryption;
! 1264: integrity_algorithm_t integrity;
! 1265: hash_algorithm_t hash;
! 1266: pseudo_random_function_t prf;
! 1267: ext_out_function_t xof;
! 1268: drbg_type_t drbg;
! 1269: diffie_hellman_group_t group;
! 1270: rng_quality_t quality;
! 1271: const char *plugin_name;
! 1272:
! 1273: b = vici_builder_create();
! 1274:
! 1275: b->begin_section(b, "encryption");
! 1276: enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
! 1277: while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
! 1278: {
! 1279: add_algorithm(b, encryption_algorithm_names, encryption, plugin_name);
! 1280: }
! 1281: enumerator->destroy(enumerator);
! 1282: b->end_section(b);
! 1283:
! 1284: b->begin_section(b, "integrity");
! 1285: enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
! 1286: while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
! 1287: {
! 1288: add_algorithm(b, integrity_algorithm_names, integrity, plugin_name);
! 1289: }
! 1290: enumerator->destroy(enumerator);
! 1291: b->end_section(b);
! 1292:
! 1293: b->begin_section(b, "aead");
! 1294: enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
! 1295: while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
! 1296: {
! 1297: add_algorithm(b, encryption_algorithm_names, encryption, plugin_name);
! 1298: }
! 1299: enumerator->destroy(enumerator);
! 1300: b->end_section(b);
! 1301:
! 1302: b->begin_section(b, "hasher");
! 1303: enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
! 1304: while (enumerator->enumerate(enumerator, &hash, &plugin_name))
! 1305: {
! 1306: add_algorithm(b, hash_algorithm_names, hash, plugin_name);
! 1307: }
! 1308: enumerator->destroy(enumerator);
! 1309: b->end_section(b);
! 1310:
! 1311: b->begin_section(b, "prf");
! 1312: enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
! 1313: while (enumerator->enumerate(enumerator, &prf, &plugin_name))
! 1314: {
! 1315: add_algorithm(b, pseudo_random_function_names, prf, plugin_name);
! 1316: }
! 1317: enumerator->destroy(enumerator);
! 1318: b->end_section(b);
! 1319:
! 1320: b->begin_section(b, "xof");
! 1321: enumerator = lib->crypto->create_xof_enumerator(lib->crypto);
! 1322: while (enumerator->enumerate(enumerator, &xof, &plugin_name))
! 1323: {
! 1324: add_algorithm(b, ext_out_function_names, xof, plugin_name);
! 1325: }
! 1326: enumerator->destroy(enumerator);
! 1327: b->end_section(b);
! 1328:
! 1329: b->begin_section(b, "drbg");
! 1330: enumerator = lib->crypto->create_drbg_enumerator(lib->crypto);
! 1331: while (enumerator->enumerate(enumerator, &drbg, &plugin_name))
! 1332: {
! 1333: add_algorithm(b, drbg_type_names, drbg, plugin_name);
! 1334: }
! 1335: enumerator->destroy(enumerator);
! 1336: b->end_section(b);
! 1337:
! 1338: b->begin_section(b, "dh");
! 1339: enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
! 1340: while (enumerator->enumerate(enumerator, &group, &plugin_name))
! 1341: {
! 1342: add_algorithm(b, diffie_hellman_group_names, group, plugin_name);
! 1343: }
! 1344: enumerator->destroy(enumerator);
! 1345: b->end_section(b);
! 1346:
! 1347: b->begin_section(b, "rng");
! 1348: enumerator = lib->crypto->create_rng_enumerator(lib->crypto);
! 1349: while (enumerator->enumerate(enumerator, &quality, &plugin_name))
! 1350: {
! 1351: add_algorithm(b, rng_quality_names, quality, plugin_name);
! 1352: }
! 1353: enumerator->destroy(enumerator);
! 1354: b->end_section(b);
! 1355:
! 1356: b->begin_section(b, "nonce-gen");
! 1357: enumerator = lib->crypto->create_nonce_gen_enumerator(lib->crypto);
! 1358: while (enumerator->enumerate(enumerator, &plugin_name))
! 1359: {
! 1360: b->add_kv(b, "NONCE_GEN", (char*)plugin_name);
! 1361: }
! 1362: enumerator->destroy(enumerator);
! 1363: b->end_section(b);
! 1364:
! 1365: return b->finalize(b);
! 1366: }
! 1367:
! 1368: /**
! 1369: * Make sure we have the counters query interface
! 1370: */
! 1371: static inline bool ensure_counters(private_vici_query_t *this)
! 1372: {
! 1373: if (this->counters)
! 1374: {
! 1375: return TRUE;
! 1376: }
! 1377: return (this->counters = lib->get(lib, "counters")) != NULL;
! 1378: }
! 1379:
! 1380: /**
! 1381: * Add a single set of counters to the message
! 1382: *
! 1383: * Frees the array of counter values
! 1384: */
! 1385: static void add_counters(vici_builder_t *b, char *name, uint64_t *counters)
! 1386: {
! 1387: char buf[BUF_LEN];
! 1388: counter_type_t i;
! 1389:
! 1390: b->begin_section(b, name ?: "");
! 1391: for (i = 0; i < COUNTER_MAX; i++)
! 1392: {
! 1393: snprintf(buf, sizeof(buf), "%N", vici_counter_type_names, i);
! 1394: b->add_kv(b, buf, "%"PRIu64, counters[i]);
! 1395: }
! 1396: b->end_section(b);
! 1397: free(counters);
! 1398: }
! 1399:
! 1400: CALLBACK(get_counters, vici_message_t*,
! 1401: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1402: {
! 1403: vici_builder_t *b;
! 1404: enumerator_t *enumerator;
! 1405: uint64_t *counters;
! 1406: char *conn, *errmsg = NULL;
! 1407: bool all;
! 1408:
! 1409: b = vici_builder_create();
! 1410:
! 1411: if (ensure_counters(this))
! 1412: {
! 1413: conn = request->get_str(request, NULL, "name");
! 1414: all = request->get_bool(request, FALSE, "all");
! 1415:
! 1416: b->begin_section(b, "counters");
! 1417: if (all)
! 1418: {
! 1419: enumerator = this->counters->get_names(this->counters);
! 1420: while (enumerator->enumerate(enumerator, &conn))
! 1421: {
! 1422: counters = this->counters->get_all(this->counters, conn);
! 1423: if (counters)
! 1424: {
! 1425: add_counters(b, conn, counters);
! 1426: }
! 1427: }
! 1428: enumerator->destroy(enumerator);
! 1429: }
! 1430: else
! 1431: {
! 1432: counters = this->counters->get_all(this->counters, conn);
! 1433: if (counters)
! 1434: {
! 1435: add_counters(b, conn, counters);
! 1436: }
! 1437: else
! 1438: {
! 1439: errmsg = "no counters found for this connection";
! 1440: }
! 1441: }
! 1442: b->end_section(b);
! 1443: }
! 1444: else
! 1445: {
! 1446: errmsg = "no counters available (plugin missing?)";
! 1447: }
! 1448:
! 1449: b->add_kv(b, "success", errmsg ? "no" : "yes");
! 1450: if (errmsg)
! 1451: {
! 1452: b->add_kv(b, "errmsg", "%s", errmsg);
! 1453: }
! 1454: return b->finalize(b);
! 1455: }
! 1456:
! 1457: CALLBACK(reset_counters, vici_message_t*,
! 1458: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1459: {
! 1460: vici_builder_t *b;
! 1461: char *conn, *errmsg = NULL;
! 1462: bool all;
! 1463:
! 1464: b = vici_builder_create();
! 1465:
! 1466: if (ensure_counters(this))
! 1467: {
! 1468: conn = request->get_str(request, NULL, "name");
! 1469: all = request->get_bool(request, FALSE, "all");
! 1470:
! 1471: if (all)
! 1472: {
! 1473: this->counters->reset_all(this->counters);
! 1474: }
! 1475: else
! 1476: {
! 1477: this->counters->reset(this->counters, conn);
! 1478: }
! 1479: }
! 1480: else
! 1481: {
! 1482: errmsg = "no counters available (plugin missing?)";
! 1483: }
! 1484:
! 1485: b->add_kv(b, "success", errmsg ? "no" : "yes");
! 1486: if (errmsg)
! 1487: {
! 1488: b->add_kv(b, "errmsg", "%s", errmsg);
! 1489: }
! 1490: return b->finalize(b);
! 1491: }
! 1492:
! 1493: CALLBACK(version, vici_message_t*,
! 1494: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1495: {
! 1496: vici_builder_t *b;
! 1497:
! 1498: b = vici_builder_create();
! 1499: b->add_kv(b, "daemon", "%s", lib->ns);
! 1500: b->add_kv(b, "version", "%s", VERSION);
! 1501:
! 1502: #ifdef WIN32
! 1503: {
! 1504: OSVERSIONINFOEX osvie;
! 1505:
! 1506: memset(&osvie, 0, sizeof(osvie));
! 1507: osvie.dwOSVersionInfoSize = sizeof(osvie);
! 1508:
! 1509: if (GetVersionEx((LPOSVERSIONINFO)&osvie))
! 1510: {
! 1511: b->add_kv(b, "sysname", "Windows %s",
! 1512: osvie.wProductType == VER_NT_WORKSTATION ? "Client" : "Server");
! 1513: b->add_kv(b, "release", "%d.%d.%d (SP %d.%d)",
! 1514: osvie.dwMajorVersion, osvie.dwMinorVersion, osvie.dwBuildNumber,
! 1515: osvie.wServicePackMajor, osvie.wServicePackMinor);
! 1516: b->add_kv(b, "machine", "%s",
! 1517: #ifdef WIN64
! 1518: "x86_64");
! 1519: #else
! 1520: "x86");
! 1521: #endif /* !WIN64 */
! 1522: }
! 1523: }
! 1524: #else /* !WIN32 */
! 1525: {
! 1526: struct utsname utsname;
! 1527:
! 1528: if (uname(&utsname) == 0)
! 1529: {
! 1530: b->add_kv(b, "sysname", "%s", utsname.sysname);
! 1531: b->add_kv(b, "release", "%s", utsname.release);
! 1532: b->add_kv(b, "machine", "%s", utsname.machine);
! 1533: }
! 1534: }
! 1535: #endif /* !WIN32 */
! 1536: return b->finalize(b);
! 1537: }
! 1538:
! 1539: CALLBACK(stats, vici_message_t*,
! 1540: private_vici_query_t *this, char *name, u_int id, vici_message_t *request)
! 1541: {
! 1542: vici_builder_t *b;
! 1543: enumerator_t *enumerator;
! 1544: plugin_t *plugin;
! 1545: time_t since, now;
! 1546: int i;
! 1547:
! 1548: b = vici_builder_create();
! 1549:
! 1550: now = time_monotonic(NULL);
! 1551: since = time(NULL) - (now - this->uptime);
! 1552:
! 1553: b->begin_section(b, "uptime");
! 1554: b->add_kv(b, "running", "%V", &now, &this->uptime);
! 1555: b->add_kv(b, "since", "%T", &since, FALSE);
! 1556: b->end_section(b);
! 1557:
! 1558: b->begin_section(b, "workers");
! 1559: b->add_kv(b, "total", "%d",
! 1560: lib->processor->get_total_threads(lib->processor));
! 1561: b->add_kv(b, "idle", "%d",
! 1562: lib->processor->get_idle_threads(lib->processor));
! 1563: b->begin_section(b, "active");
! 1564: for (i = 0; i < JOB_PRIO_MAX; i++)
! 1565: {
! 1566: b->add_kv(b, enum_to_name(job_priority_names, i), "%d",
! 1567: lib->processor->get_working_threads(lib->processor, i));
! 1568: }
! 1569: b->end_section(b);
! 1570: b->end_section(b);
! 1571:
! 1572: b->begin_section(b, "queues");
! 1573: for (i = 0; i < JOB_PRIO_MAX; i++)
! 1574: {
! 1575: b->add_kv(b, enum_to_name(job_priority_names, i), "%d",
! 1576: lib->processor->get_job_load(lib->processor, i));
! 1577: }
! 1578: b->end_section(b);
! 1579:
! 1580: b->add_kv(b, "scheduled", "%d",
! 1581: lib->scheduler->get_job_load(lib->scheduler));
! 1582:
! 1583: b->begin_section(b, "ikesas");
! 1584: b->add_kv(b, "total", "%u",
! 1585: charon->ike_sa_manager->get_count(charon->ike_sa_manager));
! 1586: b->add_kv(b, "half-open", "%u",
! 1587: charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
! 1588: NULL, FALSE));
! 1589: b->end_section(b);
! 1590:
! 1591: b->begin_list(b, "plugins");
! 1592: enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
! 1593: while (enumerator->enumerate(enumerator, &plugin, NULL))
! 1594: {
! 1595: b->add_li(b, "%s", plugin->get_name(plugin));
! 1596: }
! 1597: enumerator->destroy(enumerator);
! 1598: b->end_list(b);
! 1599:
! 1600: #ifdef WIN32
! 1601: {
! 1602: DWORD lasterr = ERROR_INVALID_HANDLE;
! 1603: HANDLE heaps[32];
! 1604: int i, count;
! 1605: char buf[16];
! 1606: size_t total = 0;
! 1607: int allocs = 0;
! 1608:
! 1609: b->begin_section(b, "mem");
! 1610: count = GetProcessHeaps(countof(heaps), heaps);
! 1611: for (i = 0; i < count; i++)
! 1612: {
! 1613: PROCESS_HEAP_ENTRY entry = {};
! 1614: size_t heap_total = 0;
! 1615: int heap_allocs = 0;
! 1616:
! 1617: if (HeapLock(heaps[i]))
! 1618: {
! 1619: while (HeapWalk(heaps[i], &entry))
! 1620: {
! 1621: if (entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)
! 1622: {
! 1623: heap_total += entry.cbData;
! 1624: heap_allocs++;
! 1625: }
! 1626: }
! 1627: lasterr = GetLastError();
! 1628: HeapUnlock(heaps[i]);
! 1629: }
! 1630: if (lasterr != ERROR_NO_MORE_ITEMS)
! 1631: {
! 1632: break;
! 1633: }
! 1634: snprintf(buf, sizeof(buf), "heap-%d", i);
! 1635: b->begin_section(b, buf);
! 1636: b->add_kv(b, "total", "%zu", heap_total);
! 1637: b->add_kv(b, "allocs", "%d", heap_allocs);
! 1638: b->end_section(b);
! 1639:
! 1640: total += heap_total;
! 1641: allocs += heap_allocs;
! 1642: }
! 1643: if (lasterr == ERROR_NO_MORE_ITEMS)
! 1644: {
! 1645: b->add_kv(b, "total", "%zu", total);
! 1646: b->add_kv(b, "allocs", "%d", allocs);
! 1647: }
! 1648: b->end_section(b);
! 1649: }
! 1650: #endif
! 1651:
! 1652: #ifdef HAVE_MALLINFO
! 1653: {
! 1654: struct mallinfo mi = mallinfo();
! 1655:
! 1656: b->begin_section(b, "mallinfo");
! 1657: b->add_kv(b, "sbrk", "%u", mi.arena);
! 1658: b->add_kv(b, "mmap", "%u", mi.hblkhd);
! 1659: b->add_kv(b, "used", "%u", mi.uordblks);
! 1660: b->add_kv(b, "free", "%u", mi.fordblks);
! 1661: b->end_section(b);
! 1662: }
! 1663: #endif /* HAVE_MALLINFO */
! 1664:
! 1665: return b->finalize(b);
! 1666: }
! 1667:
! 1668: static void manage_command(private_vici_query_t *this,
! 1669: char *name, vici_command_cb_t cb, bool reg)
! 1670: {
! 1671: this->dispatcher->manage_command(this->dispatcher, name,
! 1672: reg ? cb : NULL, this);
! 1673: }
! 1674:
! 1675: /**
! 1676: * (Un-)register dispatcher functions
! 1677: */
! 1678: static void manage_commands(private_vici_query_t *this, bool reg)
! 1679: {
! 1680: this->dispatcher->manage_event(this->dispatcher, "list-sa", reg);
! 1681: this->dispatcher->manage_event(this->dispatcher, "list-policy", reg);
! 1682: this->dispatcher->manage_event(this->dispatcher, "list-conn", reg);
! 1683: this->dispatcher->manage_event(this->dispatcher, "list-cert", reg);
! 1684: this->dispatcher->manage_event(this->dispatcher, "ike-updown", reg);
! 1685: this->dispatcher->manage_event(this->dispatcher, "ike-rekey", reg);
! 1686: this->dispatcher->manage_event(this->dispatcher, "child-updown", reg);
! 1687: this->dispatcher->manage_event(this->dispatcher, "child-rekey", reg);
! 1688: manage_command(this, "list-sas", list_sas, reg);
! 1689: manage_command(this, "list-policies", list_policies, reg);
! 1690: manage_command(this, "list-conns", list_conns, reg);
! 1691: manage_command(this, "list-certs", list_certs, reg);
! 1692: manage_command(this, "get-algorithms", get_algorithms, reg);
! 1693: manage_command(this, "get-counters", get_counters, reg);
! 1694: manage_command(this, "reset-counters", reset_counters, reg);
! 1695: manage_command(this, "version", version, reg);
! 1696: manage_command(this, "stats", stats, reg);
! 1697: }
! 1698:
! 1699: METHOD(listener_t, ike_updown, bool,
! 1700: private_vici_query_t *this, ike_sa_t *ike_sa, bool up)
! 1701: {
! 1702: vici_builder_t *b;
! 1703: time_t now;
! 1704:
! 1705: if (!this->dispatcher->has_event_listeners(this->dispatcher, "ike-updown"))
! 1706: {
! 1707: return TRUE;
! 1708: }
! 1709:
! 1710: now = time_monotonic(NULL);
! 1711:
! 1712: b = vici_builder_create();
! 1713:
! 1714: if (up)
! 1715: {
! 1716: b->add_kv(b, "up", "yes");
! 1717: }
! 1718:
! 1719: b->begin_section(b, ike_sa->get_name(ike_sa));
! 1720: list_ike(this, b, ike_sa, now);
! 1721: b->end_section(b);
! 1722:
! 1723: this->dispatcher->raise_event(this->dispatcher,
! 1724: "ike-updown", 0, b->finalize(b));
! 1725:
! 1726: return TRUE;
! 1727: }
! 1728:
! 1729: METHOD(listener_t, ike_rekey, bool,
! 1730: private_vici_query_t *this, ike_sa_t *old, ike_sa_t *new)
! 1731: {
! 1732: vici_builder_t *b;
! 1733: time_t now;
! 1734:
! 1735: if (!this->dispatcher->has_event_listeners(this->dispatcher, "ike-rekey"))
! 1736: {
! 1737: return TRUE;
! 1738: }
! 1739:
! 1740: now = time_monotonic(NULL);
! 1741:
! 1742: b = vici_builder_create();
! 1743: b->begin_section(b, old->get_name(old));
! 1744: b->begin_section(b, "old");
! 1745: list_ike(this, b, old, now);
! 1746: b->end_section(b);
! 1747: b->begin_section(b, "new");
! 1748: list_ike(this, b, new, now);
! 1749: b->end_section(b);
! 1750: b->end_section(b);
! 1751:
! 1752: this->dispatcher->raise_event(this->dispatcher,
! 1753: "ike-rekey", 0, b->finalize(b));
! 1754:
! 1755: return TRUE;
! 1756: }
! 1757:
! 1758: METHOD(listener_t, child_updown, bool,
! 1759: private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, bool up)
! 1760: {
! 1761: vici_builder_t *b;
! 1762: time_t now;
! 1763: char buf[BUF_LEN];
! 1764:
! 1765: if (!this->dispatcher->has_event_listeners(this->dispatcher, "child-updown"))
! 1766: {
! 1767: return TRUE;
! 1768: }
! 1769:
! 1770: now = time_monotonic(NULL);
! 1771: b = vici_builder_create();
! 1772:
! 1773: if (up)
! 1774: {
! 1775: b->add_kv(b, "up", "yes");
! 1776: }
! 1777:
! 1778: b->begin_section(b, ike_sa->get_name(ike_sa));
! 1779: list_ike(this, b, ike_sa, now);
! 1780: b->begin_section(b, "child-sas");
! 1781:
! 1782: snprintf(buf, sizeof(buf), "%s-%u", child_sa->get_name(child_sa),
! 1783: child_sa->get_unique_id(child_sa));
! 1784:
! 1785: b->begin_section(b, buf);
! 1786: list_child(this, b, child_sa, now);
! 1787: b->end_section(b);
! 1788:
! 1789: b->end_section(b);
! 1790: b->end_section(b);
! 1791:
! 1792: this->dispatcher->raise_event(this->dispatcher,
! 1793: "child-updown", 0, b->finalize(b));
! 1794:
! 1795: return TRUE;
! 1796: }
! 1797:
! 1798: METHOD(listener_t, child_rekey, bool,
! 1799: private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *old,
! 1800: child_sa_t *new)
! 1801: {
! 1802: vici_builder_t *b;
! 1803: time_t now;
! 1804:
! 1805: if (!this->dispatcher->has_event_listeners(this->dispatcher, "child-rekey"))
! 1806: {
! 1807: return TRUE;
! 1808: }
! 1809:
! 1810: now = time_monotonic(NULL);
! 1811: b = vici_builder_create();
! 1812:
! 1813: b->begin_section(b, ike_sa->get_name(ike_sa));
! 1814: list_ike(this, b, ike_sa, now);
! 1815: b->begin_section(b, "child-sas");
! 1816:
! 1817: b->begin_section(b, old->get_name(old));
! 1818:
! 1819: b->begin_section(b, "old");
! 1820: list_child(this, b, old, now);
! 1821: b->end_section(b);
! 1822: b->begin_section(b, "new");
! 1823: list_child(this, b, new, now);
! 1824: b->end_section(b);
! 1825:
! 1826: b->end_section(b);
! 1827:
! 1828: b->end_section(b);
! 1829: b->end_section(b);
! 1830:
! 1831: this->dispatcher->raise_event(this->dispatcher,
! 1832: "child-rekey", 0, b->finalize(b));
! 1833:
! 1834: return TRUE;
! 1835: }
! 1836:
! 1837: METHOD(vici_query_t, destroy, void,
! 1838: private_vici_query_t *this)
! 1839: {
! 1840: manage_commands(this, FALSE);
! 1841: free(this);
! 1842: }
! 1843:
! 1844: /**
! 1845: * See header
! 1846: */
! 1847: vici_query_t *vici_query_create(vici_dispatcher_t *dispatcher)
! 1848: {
! 1849: private_vici_query_t *this;
! 1850:
! 1851: INIT(this,
! 1852: .public = {
! 1853: .listener = {
! 1854: .ike_updown = _ike_updown,
! 1855: .ike_rekey = _ike_rekey,
! 1856: .child_updown = _child_updown,
! 1857: .child_rekey = _child_rekey,
! 1858: },
! 1859: .destroy = _destroy,
! 1860: },
! 1861: .dispatcher = dispatcher,
! 1862: .uptime = time_monotonic(NULL),
! 1863: );
! 1864:
! 1865: manage_commands(this, TRUE);
! 1866:
! 1867: return &this->public;
! 1868: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>