Annotation of embedaddon/strongswan/src/swanctl/commands/load_authorities.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2015 Andreas Steffen
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #define _GNU_SOURCE
! 17: #include <stdio.h>
! 18: #include <errno.h>
! 19: #include <limits.h>
! 20:
! 21: #include "command.h"
! 22: #include "swanctl.h"
! 23: #include "load_authorities.h"
! 24:
! 25: /**
! 26: * Add a vici list from a comma separated string value
! 27: */
! 28: static void add_list_key(vici_req_t *req, char *key, char *value)
! 29: {
! 30: enumerator_t *enumerator;
! 31: char *token;
! 32:
! 33: vici_begin_list(req, key);
! 34: enumerator = enumerator_create_token(value, ",", " ");
! 35: while (enumerator->enumerate(enumerator, &token))
! 36: {
! 37: vici_add_list_itemf(req, "%s", token);
! 38: }
! 39: enumerator->destroy(enumerator);
! 40: vici_end_list(req);
! 41: }
! 42:
! 43: /**
! 44: * Add a vici certificate blob value given by its file patch
! 45: */
! 46: static bool add_file_key_value(vici_req_t *req, char *key, char *value)
! 47: {
! 48: chunk_t *map;
! 49: char *path, buf[PATH_MAX];
! 50:
! 51: if (path_absolute(value))
! 52: {
! 53: path = value;
! 54: }
! 55: else
! 56: {
! 57: path = buf;
! 58: snprintf(path, PATH_MAX, "%s%s%s%s%s", swanctl_dir,
! 59: DIRECTORY_SEPARATOR, SWANCTL_X509CADIR,
! 60: DIRECTORY_SEPARATOR, value);
! 61: }
! 62: map = chunk_map(path, FALSE);
! 63:
! 64: if (map)
! 65: {
! 66: vici_add_key_value(req, key, map->ptr, map->len);
! 67: chunk_unmap(map);
! 68: return TRUE;
! 69: }
! 70: else
! 71: {
! 72: fprintf(stderr, "loading ca certificate '%s' failed: %s\n",
! 73: path, strerror(errno));
! 74: return FALSE;
! 75: }
! 76: }
! 77:
! 78: /**
! 79: * Translate setting key/values from a section enumerator into vici
! 80: * key-values/lists. Destroys the enumerator.
! 81: */
! 82: static bool add_key_values(vici_req_t *req, enumerator_t *enumerator)
! 83: {
! 84: char *key, *value;
! 85: bool ret = TRUE;
! 86:
! 87: while (enumerator->enumerate(enumerator, &key, &value))
! 88: {
! 89: if (streq(key, "cacert"))
! 90: {
! 91: ret = add_file_key_value(req, key, value);
! 92: }
! 93: else if (streq(key, "crl_uris") ||
! 94: streq(key, "ocsp_uris"))
! 95: {
! 96: add_list_key(req, key, value);
! 97: }
! 98: else
! 99: {
! 100: vici_add_key_valuef(req, key, "%s", value);
! 101: }
! 102: if (!ret)
! 103: {
! 104: break;
! 105: }
! 106: }
! 107: enumerator->destroy(enumerator);
! 108:
! 109: return ret;
! 110: }
! 111:
! 112: /**
! 113: * Load an authority configuration
! 114: */
! 115: static bool load_authority(vici_conn_t *conn, settings_t *cfg,
! 116: char *section, command_format_options_t format)
! 117: {
! 118: enumerator_t *enumerator;
! 119: vici_req_t *req;
! 120: vici_res_t *res;
! 121: bool ret = TRUE;
! 122:
! 123: req = vici_begin("load-authority");
! 124:
! 125: vici_begin_section(req, section);
! 126: enumerator = cfg->create_key_value_enumerator(cfg, "authorities.%s",
! 127: section);
! 128: if (!add_key_values(req, enumerator))
! 129: {
! 130: vici_free_req(req);
! 131: return FALSE;
! 132: }
! 133: vici_end_section(req);
! 134:
! 135: res = vici_submit(req, conn);
! 136: if (!res)
! 137: {
! 138: fprintf(stderr, "load-authority request failed: %s\n", strerror(errno));
! 139: return FALSE;
! 140: }
! 141: if (format & COMMAND_FORMAT_RAW)
! 142: {
! 143: vici_dump(res, "load-authority reply", format & COMMAND_FORMAT_PRETTY,
! 144: stdout);
! 145: }
! 146: else if (!streq(vici_find_str(res, "no", "success"), "yes"))
! 147: {
! 148: fprintf(stderr, "loading authority '%s' failed: %s\n",
! 149: section, vici_find_str(res, "", "errmsg"));
! 150: ret = FALSE;
! 151: }
! 152: else
! 153: {
! 154: printf("loaded authority '%s'\n", section);
! 155: }
! 156: vici_free_res(res);
! 157: return ret;
! 158: }
! 159:
! 160: CALLBACK(list_authority, int,
! 161: linked_list_t *list, vici_res_t *res, char *name, void *value, int len)
! 162: {
! 163: if (streq(name, "authorities"))
! 164: {
! 165: char *str;
! 166:
! 167: if (asprintf(&str, "%.*s", len, value) != -1)
! 168: {
! 169: list->insert_last(list, str);
! 170: }
! 171: }
! 172: return 0;
! 173: }
! 174:
! 175: /**
! 176: * Create a list of currently loaded authorities
! 177: */
! 178: static linked_list_t* list_authorities(vici_conn_t *conn,
! 179: command_format_options_t format)
! 180: {
! 181: linked_list_t *list;
! 182: vici_res_t *res;
! 183:
! 184: list = linked_list_create();
! 185:
! 186: res = vici_submit(vici_begin("get-authorities"), conn);
! 187: if (res)
! 188: {
! 189: if (format & COMMAND_FORMAT_RAW)
! 190: {
! 191: vici_dump(res, "get-authorities reply", format & COMMAND_FORMAT_PRETTY,
! 192: stdout);
! 193: }
! 194: vici_parse_cb(res, NULL, NULL, list_authority, list);
! 195: vici_free_res(res);
! 196: }
! 197: return list;
! 198: }
! 199:
! 200: /**
! 201: * Remove and free a string from a list
! 202: */
! 203: static void remove_from_list(linked_list_t *list, char *str)
! 204: {
! 205: enumerator_t *enumerator;
! 206: char *current;
! 207:
! 208: enumerator = list->create_enumerator(list);
! 209: while (enumerator->enumerate(enumerator, ¤t))
! 210: {
! 211: if (streq(current, str))
! 212: {
! 213: list->remove_at(list, enumerator);
! 214: free(current);
! 215: }
! 216: }
! 217: enumerator->destroy(enumerator);
! 218: }
! 219:
! 220: /**
! 221: * Unload a authority by name
! 222: */
! 223: static bool unload_authority(vici_conn_t *conn, char *name,
! 224: command_format_options_t format)
! 225: {
! 226: vici_req_t *req;
! 227: vici_res_t *res;
! 228: bool ret = TRUE;
! 229:
! 230: req = vici_begin("unload-authority");
! 231: vici_add_key_valuef(req, "name", "%s", name);
! 232: res = vici_submit(req, conn);
! 233: if (!res)
! 234: {
! 235: fprintf(stderr, "unload-authority request failed: %s\n", strerror(errno));
! 236: return FALSE;
! 237: }
! 238: if (format & COMMAND_FORMAT_RAW)
! 239: {
! 240: vici_dump(res, "unload-authority reply", format & COMMAND_FORMAT_PRETTY,
! 241: stdout);
! 242: }
! 243: else if (!streq(vici_find_str(res, "no", "success"), "yes"))
! 244: {
! 245: fprintf(stderr, "unloading authority '%s' failed: %s\n",
! 246: name, vici_find_str(res, "", "errmsg"));
! 247: ret = FALSE;
! 248: }
! 249: vici_free_res(res);
! 250: return ret;
! 251: }
! 252:
! 253: /**
! 254: * See header.
! 255: */
! 256: int load_authorities_cfg(vici_conn_t *conn, command_format_options_t format,
! 257: settings_t *cfg)
! 258: {
! 259: u_int found = 0, loaded = 0, unloaded = 0;
! 260: char *section;
! 261: enumerator_t *enumerator;
! 262: linked_list_t *authorities;
! 263:
! 264: authorities = list_authorities(conn, format);
! 265:
! 266: enumerator = cfg->create_section_enumerator(cfg, "authorities");
! 267: while (enumerator->enumerate(enumerator, §ion))
! 268: {
! 269: remove_from_list(authorities, section);
! 270: found++;
! 271: if (load_authority(conn, cfg, section, format))
! 272: {
! 273: loaded++;
! 274: }
! 275: }
! 276: enumerator->destroy(enumerator);
! 277:
! 278: /* unload all authorities in daemon, but not in file */
! 279: while (authorities->remove_first(authorities, (void**)§ion) == SUCCESS)
! 280: {
! 281: if (unload_authority(conn, section, format))
! 282: {
! 283: unloaded++;
! 284: }
! 285: free(section);
! 286: }
! 287: authorities->destroy(authorities);
! 288:
! 289: if (format & COMMAND_FORMAT_RAW)
! 290: {
! 291: return 0;
! 292: }
! 293: if (found == 0)
! 294: {
! 295: fprintf(stderr, "no authorities found, %u unloaded\n", unloaded);
! 296: return 0;
! 297: }
! 298: if (loaded == found)
! 299: {
! 300: printf("successfully loaded %u authorities, %u unloaded\n",
! 301: loaded, unloaded);
! 302: return 0;
! 303: }
! 304: fprintf(stderr, "loaded %u of %u authorities, %u failed to load, "
! 305: "%u unloaded\n", loaded, found, found - loaded, unloaded);
! 306: return EINVAL;
! 307: }
! 308:
! 309: static int load_authorities(vici_conn_t *conn)
! 310: {
! 311: command_format_options_t format = COMMAND_FORMAT_NONE;
! 312: settings_t *cfg;
! 313: char *arg, *file = NULL;
! 314: int ret;
! 315:
! 316: while (TRUE)
! 317: {
! 318: switch (command_getopt(&arg))
! 319: {
! 320: case 'h':
! 321: return command_usage(NULL);
! 322: case 'P':
! 323: format |= COMMAND_FORMAT_PRETTY;
! 324: /* fall through to raw */
! 325: case 'r':
! 326: format |= COMMAND_FORMAT_RAW;
! 327: continue;
! 328: case 'f':
! 329: file = arg;
! 330: continue;
! 331: case EOF:
! 332: break;
! 333: default:
! 334: return command_usage("invalid --load-authorities option");
! 335: }
! 336: break;
! 337: }
! 338:
! 339: cfg = load_swanctl_conf(file);
! 340: if (!cfg)
! 341: {
! 342: return EINVAL;
! 343: }
! 344:
! 345: ret = load_authorities_cfg(conn, format, cfg);
! 346:
! 347: cfg->destroy(cfg);
! 348:
! 349: return ret;
! 350: }
! 351:
! 352: /**
! 353: * Register the command.
! 354: */
! 355: static void __attribute__ ((constructor))reg()
! 356: {
! 357: command_register((command_t) {
! 358: load_authorities, 'b',
! 359: "load-authorities", "(re-)load authority configuration",
! 360: {"[--raw|--pretty]"},
! 361: {
! 362: {"help", 'h', 0, "show usage information"},
! 363: {"raw", 'r', 0, "dump raw response message"},
! 364: {"pretty", 'P', 0, "dump raw response message in pretty print"},
! 365: {"file", 'f', 1, "custom path to swanctl.conf"},
! 366: }
! 367: });
! 368: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>