Annotation of embedaddon/strongswan/src/swanctl/commands/load_authorities.c, revision 1.1.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, &current))
                    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, &section))
                    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**)&section) == 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>