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