Annotation of embedaddon/strongswan/src/swanctl/commands/load_authorities.c, revision 1.1.1.2
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: {
1.1.1.2 ! misho 295: printf("no authorities found, %u unloaded\n", unloaded);
1.1 misho 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: }
1.1.1.2 ! misho 304:
1.1 misho 305: fprintf(stderr, "loaded %u of %u authorities, %u failed to load, "
306: "%u unloaded\n", loaded, found, found - loaded, unloaded);
307: return EINVAL;
308: }
309:
310: static int load_authorities(vici_conn_t *conn)
311: {
312: command_format_options_t format = COMMAND_FORMAT_NONE;
313: settings_t *cfg;
314: char *arg, *file = NULL;
315: int ret;
316:
317: while (TRUE)
318: {
319: switch (command_getopt(&arg))
320: {
321: case 'h':
322: return command_usage(NULL);
323: case 'P':
324: format |= COMMAND_FORMAT_PRETTY;
325: /* fall through to raw */
326: case 'r':
327: format |= COMMAND_FORMAT_RAW;
328: continue;
329: case 'f':
330: file = arg;
331: continue;
332: case EOF:
333: break;
334: default:
335: return command_usage("invalid --load-authorities option");
336: }
337: break;
338: }
339:
340: cfg = load_swanctl_conf(file);
341: if (!cfg)
342: {
343: return EINVAL;
344: }
345:
346: ret = load_authorities_cfg(conn, format, cfg);
347:
348: cfg->destroy(cfg);
349:
350: return ret;
351: }
352:
353: /**
354: * Register the command.
355: */
356: static void __attribute__ ((constructor))reg()
357: {
358: command_register((command_t) {
359: load_authorities, 'b',
360: "load-authorities", "(re-)load authority configuration",
361: {"[--raw|--pretty]"},
362: {
363: {"help", 'h', 0, "show usage information"},
364: {"raw", 'r', 0, "dump raw response message"},
365: {"pretty", 'P', 0, "dump raw response message in pretty print"},
366: {"file", 'f', 1, "custom path to swanctl.conf"},
367: }
368: });
369: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>