Annotation of embedaddon/strongswan/src/swanctl/commands/load_pools.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2014 Martin Willi
                      3:  * Copyright (C) 2014 revosec AG
                      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_pools.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:  * Translate setting key/values from a section enumerator into vici
                     45:  * key-values/lists. Destroys the enumerator.
                     46:  */
                     47: static void add_key_values(vici_req_t *req, enumerator_t *enumerator)
                     48: {
                     49:        char *key, *value;
                     50: 
                     51:        while (enumerator->enumerate(enumerator, &key, &value))
                     52:        {
                     53:                /* pool subnet is encoded as key/value, all other attributes as list */
                     54:                if (streq(key, "addrs"))
                     55:                {
                     56:                        vici_add_key_valuef(req, key, "%s", value);
                     57:                }
                     58:                else
                     59:                {
                     60:                        add_list_key(req, key, value);
                     61:                }
                     62:        }
                     63:        enumerator->destroy(enumerator);
                     64: }
                     65: 
                     66: /**
                     67:  * Load a pool configuration
                     68:  */
                     69: static bool load_pool(vici_conn_t *conn, settings_t *cfg,
                     70:                                          char *section, command_format_options_t format)
                     71: {
                     72:        enumerator_t *enumerator;
                     73:        vici_req_t *req;
                     74:        vici_res_t *res;
                     75:        bool ret = TRUE;
                     76: 
                     77:        req = vici_begin("load-pool");
                     78: 
                     79:        vici_begin_section(req, section);
                     80:        enumerator = cfg->create_key_value_enumerator(cfg, "pools.%s", section);
                     81:        add_key_values(req, enumerator);
                     82:        vici_end_section(req);
                     83: 
                     84:        res = vici_submit(req, conn);
                     85:        if (!res)
                     86:        {
                     87:                fprintf(stderr, "load-pool request failed: %s\n", strerror(errno));
                     88:                return FALSE;
                     89:        }
                     90:        if (format & COMMAND_FORMAT_RAW)
                     91:        {
                     92:                vici_dump(res, "load-pool reply", format & COMMAND_FORMAT_PRETTY,
                     93:                                  stdout);
                     94:        }
                     95:        else if (!streq(vici_find_str(res, "no", "success"), "yes"))
                     96:        {
                     97:                fprintf(stderr, "loading pool '%s' failed: %s\n",
                     98:                                section, vici_find_str(res, "", "errmsg"));
                     99:                ret = FALSE;
                    100:        }
                    101:        else
                    102:        {
                    103:                printf("loaded pool '%s'\n", section);
                    104:        }
                    105:        vici_free_res(res);
                    106:        return ret;
                    107: }
                    108: 
                    109: CALLBACK(list_pool, int,
                    110:        linked_list_t *list, vici_res_t *res, char *name)
                    111: {
                    112:        list->insert_last(list, strdup(name));
                    113:        return 0;
                    114: }
                    115: 
                    116: /**
                    117:  * Create a list of currently loaded pools
                    118:  */
                    119: static linked_list_t* list_pools(vici_conn_t *conn,
                    120:                                                                 command_format_options_t format)
                    121: {
                    122:        linked_list_t *list;
                    123:        vici_res_t *res;
                    124: 
                    125:        list = linked_list_create();
                    126: 
                    127:        res = vici_submit(vici_begin("get-pools"), conn);
                    128:        if (res)
                    129:        {
                    130:                if (format & COMMAND_FORMAT_RAW)
                    131:                {
                    132:                        vici_dump(res, "get-pools reply", format & COMMAND_FORMAT_PRETTY,
                    133:                                          stdout);
                    134:                }
                    135:                vici_parse_cb(res, list_pool, NULL, NULL, list);
                    136:                vici_free_res(res);
                    137:        }
                    138:        return list;
                    139: }
                    140: 
                    141: /**
                    142:  * Remove and free a string from a list
                    143:  */
                    144: static void remove_from_list(linked_list_t *list, char *str)
                    145: {
                    146:        enumerator_t *enumerator;
                    147:        char *current;
                    148: 
                    149:        enumerator = list->create_enumerator(list);
                    150:        while (enumerator->enumerate(enumerator, &current))
                    151:        {
                    152:                if (streq(current, str))
                    153:                {
                    154:                        list->remove_at(list, enumerator);
                    155:                        free(current);
                    156:                }
                    157:        }
                    158:        enumerator->destroy(enumerator);
                    159: }
                    160: 
                    161: /**
                    162:  * Unload a pool by name
                    163:  */
                    164: static bool unload_pool(vici_conn_t *conn, char *name,
                    165:                                                command_format_options_t format)
                    166: {
                    167:        vici_req_t *req;
                    168:        vici_res_t *res;
                    169:        bool ret = TRUE;
                    170: 
                    171:        req = vici_begin("unload-pool");
                    172:        vici_add_key_valuef(req, "name", "%s", name);
                    173:        res = vici_submit(req, conn);
                    174:        if (!res)
                    175:        {
                    176:                fprintf(stderr, "unload-pool request failed: %s\n", strerror(errno));
                    177:                return FALSE;
                    178:        }
                    179:        if (format & COMMAND_FORMAT_RAW)
                    180:        {
                    181:                vici_dump(res, "unload-pool reply", format & COMMAND_FORMAT_PRETTY,
                    182:                                  stdout);
                    183:        }
                    184:        else if (!streq(vici_find_str(res, "no", "success"), "yes"))
                    185:        {
                    186:                fprintf(stderr, "unloading pool '%s' failed: %s\n",
                    187:                                name, vici_find_str(res, "", "errmsg"));
                    188:                ret = FALSE;
                    189:        }
                    190:        vici_free_res(res);
                    191:        return ret;
                    192: }
                    193: 
                    194: /**
                    195:  * See header.
                    196:  */
                    197: int load_pools_cfg(vici_conn_t *conn, command_format_options_t format,
                    198:                                   settings_t *cfg)
                    199: {
                    200:        u_int found = 0, loaded = 0, unloaded = 0;
                    201:        char *section;
                    202:        enumerator_t *enumerator;
                    203:        linked_list_t *pools;
                    204: 
                    205:        pools = list_pools(conn, format);
                    206: 
                    207:        enumerator = cfg->create_section_enumerator(cfg, "pools");
                    208:        while (enumerator->enumerate(enumerator, &section))
                    209:        {
                    210:                remove_from_list(pools, section);
                    211:                found++;
                    212:                if (load_pool(conn, cfg, section, format))
                    213:                {
                    214:                        loaded++;
                    215:                }
                    216:        }
                    217:        enumerator->destroy(enumerator);
                    218: 
                    219:        /* unload all pools in daemon, but not in file */
                    220:        while (pools->remove_first(pools, (void**)&section) == SUCCESS)
                    221:        {
                    222:                if (unload_pool(conn, section, format))
                    223:                {
                    224:                        unloaded++;
                    225:                }
                    226:                free(section);
                    227:        }
                    228:        pools->destroy(pools);
                    229: 
                    230:        if (format & COMMAND_FORMAT_RAW)
                    231:        {
                    232:                return 0;
                    233:        }
                    234:        if (found == 0)
                    235:        {
                    236:                fprintf(stderr, "no pools found, %u unloaded\n", unloaded);
                    237:                return 0;
                    238:        }
                    239:        if (loaded == found)
                    240:        {
                    241:                printf("successfully loaded %u pools, %u unloaded\n",
                    242:                           loaded, unloaded);
                    243:                return 0;
                    244:        }
                    245:        fprintf(stderr, "loaded %u of %u pools, %u failed to load, "
                    246:                        "%u unloaded\n", loaded, found, found - loaded, unloaded);
                    247:        return EINVAL;
                    248: }
                    249: 
                    250: static int load_pools(vici_conn_t *conn)
                    251: {
                    252:        command_format_options_t format = COMMAND_FORMAT_NONE;
                    253:        settings_t *cfg;
                    254:        char *arg, *file = NULL;
                    255:        int ret;
                    256: 
                    257:        while (TRUE)
                    258:        {
                    259:                switch (command_getopt(&arg))
                    260:                {
                    261:                        case 'h':
                    262:                                return command_usage(NULL);
                    263:                        case 'P':
                    264:                                format |= COMMAND_FORMAT_PRETTY;
                    265:                                /* fall through to raw */
                    266:                        case 'r':
                    267:                                format |= COMMAND_FORMAT_RAW;
                    268:                                continue;
                    269:                        case 'f':
                    270:                                file = arg;
                    271:                                continue;
                    272:                        case EOF:
                    273:                                break;
                    274:                        default:
                    275:                                return command_usage("invalid --load-pools option");
                    276:                }
                    277:                break;
                    278:        }
                    279: 
                    280:        cfg = load_swanctl_conf(file);
                    281:        if (!cfg)
                    282:        {
                    283:                return EINVAL;
                    284:        }
                    285: 
                    286:        ret = load_pools_cfg(conn, format, cfg);
                    287: 
                    288:        cfg->destroy(cfg);
                    289: 
                    290:        return ret;
                    291: }
                    292: 
                    293: /**
                    294:  * Register the command.
                    295:  */
                    296: static void __attribute__ ((constructor))reg()
                    297: {
                    298:        command_register((command_t) {
                    299:                load_pools, 'a', "load-pools", "(re-)load pool configuration",
                    300:                {"[--raw|--pretty]"},
                    301:                {
                    302:                        {"help",                'h', 0, "show usage information"},
                    303:                        {"raw",                 'r', 0, "dump raw response message"},
                    304:                        {"pretty",              'P', 0, "dump raw response message in pretty print"},
                    305:                        {"file",                'f', 1, "custom path to swanctl.conf"},
                    306:                }
                    307:        });
                    308: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>