Annotation of embedaddon/strongswan/src/swanctl/commands/list_conns.c, revision 1.1.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>