Annotation of embedaddon/strongswan/src/swanctl/commands/list_conns.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2014 Martin Willi
! 3: * Copyright (C) 2014 revosec AG
! 4: *
! 5: * Copyright (C) 2016-2018 Andreas Steffen
! 6: * HSR Hochschule fuer Technik Rapperswil
! 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: #define _GNU_SOURCE
! 20: #include <stdio.h>
! 21: #include <errno.h>
! 22:
! 23: #include "command.h"
! 24:
! 25: #include <collections/hashtable.h>
! 26:
! 27: /**
! 28: * Free hashtable with contained strings
! 29: */
! 30: static void free_hashtable(hashtable_t *hashtable)
! 31: {
! 32: enumerator_t *enumerator;
! 33: char *str;
! 34:
! 35: enumerator = hashtable->create_enumerator(hashtable);
! 36: while (enumerator->enumerate(enumerator, NULL, &str))
! 37: {
! 38: free(str);
! 39: }
! 40: enumerator->destroy(enumerator);
! 41:
! 42: hashtable->destroy(hashtable);
! 43: }
! 44:
! 45: CALLBACK(values, int,
! 46: hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
! 47: {
! 48: chunk_t chunk;
! 49: char *str;
! 50:
! 51: chunk = chunk_create(value, len);
! 52: if (chunk_printable(chunk, NULL, ' '))
! 53: {
! 54: if (asprintf(&str, "%.*s", len, value) >= 0)
! 55: {
! 56: free(sa->put(sa, name, str));
! 57: }
! 58: }
! 59: return 0;
! 60: }
! 61:
! 62:
! 63: CALLBACK(list, int,
! 64: hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
! 65: {
! 66: chunk_t chunk;
! 67: char *str;
! 68:
! 69: chunk = chunk_create(value, len);
! 70: if (chunk_printable(chunk, NULL, ' '))
! 71: {
! 72: str = sa->get(sa, name);
! 73: if (asprintf(&str, "%s%s%.*s",
! 74: str ?: "", str ? " " : "", len, value) >= 0)
! 75: {
! 76: free(sa->put(sa, name, str));
! 77: }
! 78: }
! 79: return 0;
! 80: }
! 81:
! 82: CALLBACK(children_sn, int,
! 83: hashtable_t *ike, vici_res_t *res, char *name)
! 84: {
! 85: hashtable_t *child;
! 86: char *mode, *interface, *priority;
! 87: char *rekey_time, *rekey_bytes, *rekey_packets, *dpd_action, *dpd_delay;
! 88: bool no_time, no_bytes, no_packets, no_dpd, or = FALSE;
! 89: int ret;
! 90:
! 91: child = hashtable_create(hashtable_hash_str, hashtable_equals_str, 1);
! 92: ret = vici_parse_cb(res, NULL, values, list, child);
! 93: if (ret == 0)
! 94: {
! 95: mode = child->get(child, "mode");
! 96: printf(" %s: %s, ", name, mode);
! 97:
! 98: rekey_time = child->get(child, "rekey_time");
! 99: rekey_bytes = child->get(child, "rekey_bytes");
! 100: rekey_packets = child->get(child, "rekey_packets");
! 101: dpd_action = child->get(child, "dpd_action");
! 102: dpd_delay = ike->get(ike, "dpd_delay");
! 103:
! 104: no_time = streq(rekey_time, "0");
! 105: no_bytes = streq(rekey_bytes, "0");
! 106: no_packets = streq(rekey_packets, "0");
! 107: no_dpd = streq(dpd_delay, "0");
! 108:
! 109: if (strcaseeq(mode, "PASS") || strcaseeq(mode, "DROP") ||
! 110: (no_time && no_bytes && no_packets))
! 111: {
! 112: printf("no rekeying");
! 113: }
! 114: else
! 115: {
! 116: printf("rekeying every");
! 117: if (!no_time)
! 118: {
! 119: printf(" %ss", rekey_time);
! 120: or = TRUE;
! 121: }
! 122: if (!no_bytes)
! 123: {
! 124: printf("%s %s bytes", or ? " or" : "", rekey_bytes);
! 125: or = TRUE;
! 126: }
! 127: if (!no_packets)
! 128: {
! 129: printf("%s %s packets", or ? " or" : "", rekey_packets);
! 130: }
! 131: }
! 132: if (!no_dpd)
! 133: {
! 134: printf(", dpd action is %s", dpd_action);
! 135: }
! 136: printf("\n");
! 137:
! 138: printf(" local: %s\n", child->get(child, "local-ts"));
! 139: printf(" remote: %s\n", child->get(child, "remote-ts"));
! 140:
! 141: interface = child->get(child, "interface");
! 142: if (interface)
! 143: {
! 144: printf(" interface: %s\n", interface);
! 145: }
! 146:
! 147: priority = child->get(child, "priority");
! 148: if (priority)
! 149: {
! 150: printf(" priority: %s\n", priority);
! 151: }
! 152: }
! 153: free_hashtable(child);
! 154: return ret;
! 155: }
! 156:
! 157: CALLBACK(conn_sn, int,
! 158: hashtable_t *ike, vici_res_t *res, char *name)
! 159: {
! 160: int ret = 0;
! 161:
! 162: if (streq(name, "children"))
! 163: {
! 164: return vici_parse_cb(res, children_sn, NULL, NULL, ike);
! 165: }
! 166: if (strpfx(name, "local") || strpfx(name, "remote"))
! 167: {
! 168: hashtable_t *auth;
! 169: char *class;
! 170:
! 171: auth = hashtable_create(hashtable_hash_str, hashtable_equals_str, 1);
! 172: ret = vici_parse_cb(res, NULL, values, list, auth);
! 173: if (ret == 0)
! 174: {
! 175: class = auth->get(auth, "class") ?: "unspecified";
! 176: if (strcaseeq(class, "EAP"))
! 177: {
! 178: class = auth->get(auth, "eap-type") ?: class;
! 179: }
! 180: printf(" %s %s authentication:\n",
! 181: strpfx(name, "local") ? "local" : "remote", class);
! 182: if (auth->get(auth, "id"))
! 183: {
! 184: printf(" id: %s\n", auth->get(auth, "id"));
! 185: }
! 186: if (auth->get(auth, "ca_id"))
! 187: {
! 188: printf(" ca_id: %s\n", auth->get(auth, "ca_id"));
! 189: }
! 190: if (auth->get(auth, "eap_id"))
! 191: {
! 192: printf(" eap_id: %s\n", auth->get(auth, "eap_id"));
! 193: }
! 194: if (auth->get(auth, "xauth_id"))
! 195: {
! 196: printf(" xauth_id: %s\n", auth->get(auth, "xauth_id"));
! 197: }
! 198: if (auth->get(auth, "aaa_id"))
! 199: {
! 200: printf(" aaa_id: %s\n", auth->get(auth, "aaa_id"));
! 201: }
! 202: if (auth->get(auth, "groups"))
! 203: {
! 204: printf(" groups: %s\n", auth->get(auth, "groups"));
! 205: }
! 206: if (auth->get(auth, "cert_policy"))
! 207: {
! 208: printf(" cert policy: %s\n", auth->get(auth, "cert_policy"));
! 209: }
! 210: if (auth->get(auth, "certs"))
! 211: {
! 212: printf(" certs: %s\n", auth->get(auth, "certs"));
! 213: }
! 214: if (auth->get(auth, "cacerts"))
! 215: {
! 216: printf(" cacerts: %s\n", auth->get(auth, "cacerts"));
! 217: }
! 218: }
! 219: free_hashtable(auth);
! 220: }
! 221: return ret;
! 222: }
! 223:
! 224: CALLBACK(conn_list, int,
! 225: hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
! 226: {
! 227: if (chunk_printable(chunk_create(value, len), NULL, ' '))
! 228: {
! 229: if (streq(name, "local_addrs"))
! 230: {
! 231: printf(" local: %.*s\n", len, value);
! 232: }
! 233: if (streq(name, "remote_addrs"))
! 234: {
! 235: printf(" remote: %.*s\n", len, value);
! 236: }
! 237: }
! 238: return 0;
! 239: }
! 240:
! 241: CALLBACK(conns, int,
! 242: void *null, vici_res_t *res, char *name)
! 243: {
! 244: int ret;
! 245: char *version, *reauth_time, *rekey_time, *dpd_delay, *ppk_id, *ppk_req;
! 246: hashtable_t *ike;
! 247:
! 248: version = vici_find_str(res, "", "%s.version", name);
! 249: reauth_time = vici_find_str(res, "0", "%s.reauth_time", name);
! 250: rekey_time = vici_find_str(res, "0", "%s.rekey_time", name);
! 251: dpd_delay = vici_find_str(res, "0", "%s.dpd_delay", name);
! 252:
! 253: ike = hashtable_create(hashtable_hash_str, hashtable_equals_str, 1);
! 254: free(ike->put(ike,"dpd_delay", strdup(dpd_delay)));
! 255:
! 256: printf("%s: %s, ", name, version);
! 257: if (streq(version, "IKEv1"))
! 258: {
! 259: if (streq(reauth_time, "0"))
! 260: {
! 261: reauth_time = rekey_time;
! 262: }
! 263: }
! 264: if (streq(reauth_time, "0"))
! 265: {
! 266: printf("no reauthentication");
! 267: }
! 268: else
! 269: {
! 270: printf("reauthentication every %ss", reauth_time);
! 271: }
! 272: if (!streq(version, "IKEv1"))
! 273: {
! 274: if (streq(rekey_time, "0"))
! 275: {
! 276: printf(", no rekeying");
! 277: }
! 278: else
! 279: {
! 280: printf(", rekeying every %ss", rekey_time);
! 281: }
! 282: }
! 283: if (!streq(dpd_delay, "0"))
! 284: {
! 285: printf(", dpd delay %ss", dpd_delay);
! 286: }
! 287: printf("\n");
! 288:
! 289: ppk_id = vici_find_str(res, NULL, "%s.ppk_id", name);
! 290: ppk_req = vici_find_str(res, NULL, "%s.ppk_required", name);
! 291: if (ppk_id || ppk_req)
! 292: {
! 293: printf(" ppk: %s%s%srequired\n", ppk_id ?: "", ppk_id ? ", " : "",
! 294: !ppk_req || !streq(ppk_req, "yes") ? "not " : "");
! 295: }
! 296:
! 297: ret = vici_parse_cb(res, conn_sn, NULL, conn_list, ike);
! 298: free_hashtable(ike);
! 299: return ret;
! 300: }
! 301:
! 302: CALLBACK(list_cb, void,
! 303: command_format_options_t *format, char *name, vici_res_t *res)
! 304: {
! 305: if (*format & COMMAND_FORMAT_RAW)
! 306: {
! 307: vici_dump(res, "list-conn event", *format & COMMAND_FORMAT_PRETTY,
! 308: stdout);
! 309: }
! 310: else
! 311: {
! 312: if (vici_parse_cb(res, conns, NULL, NULL, NULL) != 0)
! 313: {
! 314: fprintf(stderr, "parsing conn event failed: %s\n", strerror(errno));
! 315: }
! 316: }
! 317: }
! 318:
! 319: static int list_conns(vici_conn_t *conn)
! 320: {
! 321: vici_req_t *req;
! 322: vici_res_t *res;
! 323: command_format_options_t format = COMMAND_FORMAT_NONE;
! 324: char *arg;
! 325: int ret;
! 326:
! 327: while (TRUE)
! 328: {
! 329: switch (command_getopt(&arg))
! 330: {
! 331: case 'h':
! 332: return command_usage(NULL);
! 333: case 'P':
! 334: format |= COMMAND_FORMAT_PRETTY;
! 335: /* fall through to raw */
! 336: case 'r':
! 337: format |= COMMAND_FORMAT_RAW;
! 338: continue;
! 339: case EOF:
! 340: break;
! 341: default:
! 342: return command_usage("invalid --list-conns option");
! 343: }
! 344: break;
! 345: }
! 346: if (vici_register(conn, "list-conn", list_cb, &format) != 0)
! 347: {
! 348: ret = errno;
! 349: fprintf(stderr, "registering for connections failed: %s\n",
! 350: strerror(errno));
! 351: return ret;
! 352: }
! 353: req = vici_begin("list-conns");
! 354: res = vici_submit(req, conn);
! 355: if (!res)
! 356: {
! 357: ret = errno;
! 358: fprintf(stderr, "list-conns request failed: %s\n", strerror(errno));
! 359: return ret;
! 360: }
! 361: if (format & COMMAND_FORMAT_RAW)
! 362: {
! 363: vici_dump(res, "list-conns reply", format & COMMAND_FORMAT_PRETTY,
! 364: stdout);
! 365: }
! 366: vici_free_res(res);
! 367: return 0;
! 368: }
! 369:
! 370: /**
! 371: * Register the command.
! 372: */
! 373: static void __attribute__ ((constructor))reg()
! 374: {
! 375: command_register((command_t) {
! 376: list_conns, 'L', "list-conns", "list loaded configurations",
! 377: {"[--raw|--pretty]"},
! 378: {
! 379: {"help", 'h', 0, "show usage information"},
! 380: {"raw", 'r', 0, "dump raw response message"},
! 381: {"pretty", 'P', 0, "dump raw response message in pretty print"},
! 382: }
! 383: });
! 384: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>