Annotation of embedaddon/strongswan/src/conftest/actions.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2010 Martin Willi
        !             3:  * Copyright (C) 2010 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: #include "actions.h"
        !            17: #include "conftest.h"
        !            18: 
        !            19: #include <daemon.h>
        !            20: #include <processing/jobs/callback_job.h>
        !            21: #include <processing/jobs/rekey_ike_sa_job.h>
        !            22: #include <processing/jobs/rekey_child_sa_job.h>
        !            23: #include <processing/jobs/send_dpd_job.h>
        !            24: 
        !            25: typedef struct private_actions_t private_actions_t;
        !            26: 
        !            27: /**
        !            28:  * Private data of an actions_t object.
        !            29:  */
        !            30: struct private_actions_t {
        !            31: 
        !            32:        /**
        !            33:         * Public actions_t interface.
        !            34:         */
        !            35:        actions_t public;
        !            36: };
        !            37: 
        !            38: /**
        !            39:  * Initiate a CHILD_SA
        !            40:  */
        !            41: static job_requeue_t initiate(char *config)
        !            42: {
        !            43:        peer_cfg_t *peer_cfg;
        !            44:        child_cfg_t *child_cfg = NULL, *current;
        !            45:        enumerator_t *enumerator;
        !            46: 
        !            47:        peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, config);
        !            48:        if (!peer_cfg)
        !            49:        {
        !            50:                DBG1(DBG_CFG, "initiating '%s' failed, config not found", config);
        !            51:                return JOB_REQUEUE_NONE;
        !            52:        }
        !            53:        enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
        !            54:        while (enumerator->enumerate(enumerator, &current))
        !            55:        {
        !            56:                if (streq(current->get_name(current), config))
        !            57:                {
        !            58:                        child_cfg = current;
        !            59:                        child_cfg->get_ref(child_cfg);
        !            60:                        break;
        !            61:                }
        !            62:        }
        !            63:        enumerator->destroy(enumerator);
        !            64:        if (child_cfg)
        !            65:        {
        !            66:                DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
        !            67:                charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
        !            68:                                                                         NULL, NULL, 0, FALSE);
        !            69:        }
        !            70:        else
        !            71:        {
        !            72:                DBG1(DBG_CFG, "initiating '%s' failed, CHILD_SA config not found",
        !            73:                         config);
        !            74:        }
        !            75: 
        !            76:        return JOB_REQUEUE_NONE;
        !            77: }
        !            78: 
        !            79: /**
        !            80:  * Rekey an IKE_SA
        !            81:  */
        !            82: static job_requeue_t rekey_ike(char *config)
        !            83: {
        !            84:        enumerator_t *enumerator;
        !            85:        job_t *job = NULL;
        !            86:        ike_sa_t *ike_sa;
        !            87: 
        !            88:        enumerator = charon->controller->create_ike_sa_enumerator(
        !            89:                                                                                                        charon->controller, TRUE);
        !            90:        while (enumerator->enumerate(enumerator, &ike_sa))
        !            91:        {
        !            92:                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
        !            93:                {
        !            94:                        job = (job_t*)rekey_ike_sa_job_create(ike_sa->get_id(ike_sa), FALSE);
        !            95:                        break;
        !            96:                }
        !            97:        }
        !            98:        enumerator->destroy(enumerator);
        !            99: 
        !           100:        if (job)
        !           101:        {
        !           102:                DBG1(DBG_CFG, "starting rekey of IKE_SA '%s'", config);
        !           103:                lib->processor->queue_job(lib->processor, job);
        !           104:        }
        !           105:        else
        !           106:        {
        !           107:                DBG1(DBG_CFG, "rekeying '%s' failed, IKE_SA not found", config);
        !           108:        }
        !           109:        return JOB_REQUEUE_NONE;
        !           110: }
        !           111: 
        !           112: /**
        !           113:  * Rekey an CHILD_SA
        !           114:  */
        !           115: static job_requeue_t rekey_child(char *config)
        !           116: {
        !           117:        enumerator_t *enumerator, *children;
        !           118:        ike_sa_t *ike_sa;
        !           119:        child_sa_t *child_sa;
        !           120:        uint32_t spi, proto;
        !           121:        host_t *dst = NULL;
        !           122: 
        !           123:        enumerator = charon->controller->create_ike_sa_enumerator(
        !           124:                                                                                                        charon->controller, TRUE);
        !           125:        while (enumerator->enumerate(enumerator, &ike_sa))
        !           126:        {
        !           127:                children = ike_sa->create_child_sa_enumerator(ike_sa);
        !           128:                while (children->enumerate(children, &child_sa))
        !           129:                {
        !           130:                        if (streq(config, child_sa->get_name(child_sa)))
        !           131:                        {
        !           132:                                dst = ike_sa->get_my_host(ike_sa);
        !           133:                                dst = dst->clone(dst);
        !           134:                                proto = child_sa->get_protocol(child_sa);
        !           135:                                spi = child_sa->get_spi(child_sa, TRUE);
        !           136:                                break;
        !           137:                        }
        !           138:                }
        !           139:                children->destroy(children);
        !           140:        }
        !           141:        enumerator->destroy(enumerator);
        !           142:        if (dst)
        !           143:        {
        !           144:                DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
        !           145:                lib->processor->queue_job(lib->processor,
        !           146:                                                (job_t*)rekey_child_sa_job_create(proto, spi, dst));
        !           147:                dst->destroy(dst);
        !           148:        }
        !           149:        else
        !           150:        {
        !           151:                DBG1(DBG_CFG, "rekeying '%s' failed, CHILD_SA not found", config);
        !           152:        }
        !           153:        return JOB_REQUEUE_NONE;
        !           154: }
        !           155: 
        !           156: /**
        !           157:  * Do a liveness check
        !           158:  */
        !           159: static job_requeue_t liveness(char *config)
        !           160: {
        !           161:        enumerator_t *enumerator;
        !           162:        job_t *job = NULL;
        !           163:        ike_sa_t *ike_sa;
        !           164: 
        !           165:        enumerator = charon->controller->create_ike_sa_enumerator(
        !           166:                                                                                                        charon->controller, TRUE);
        !           167:        while (enumerator->enumerate(enumerator, &ike_sa))
        !           168:        {
        !           169:                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
        !           170:                {
        !           171:                        job = (job_t*)send_dpd_job_create(ike_sa->get_id(ike_sa));
        !           172:                        break;
        !           173:                }
        !           174:        }
        !           175:        enumerator->destroy(enumerator);
        !           176: 
        !           177:        if (job)
        !           178:        {
        !           179:                DBG1(DBG_CFG, "starting liveness check of IKE_SA '%s'", config);
        !           180:                lib->processor->queue_job(lib->processor, job);
        !           181:        }
        !           182:        else
        !           183:        {
        !           184:                DBG1(DBG_CFG, "liveness check for '%s' failed, IKE_SA not found", config);
        !           185:        }
        !           186:        return JOB_REQUEUE_NONE;
        !           187: }
        !           188: 
        !           189: /**
        !           190:  * Close an IKE_SA with all CHILD_SAs
        !           191:  */
        !           192: static job_requeue_t close_ike(char *config)
        !           193: {
        !           194:        enumerator_t *enumerator;
        !           195:        ike_sa_t *ike_sa;
        !           196:        int id = 0;
        !           197: 
        !           198:        enumerator = charon->controller->create_ike_sa_enumerator(
        !           199:                                                                                                        charon->controller, TRUE);
        !           200:        while (enumerator->enumerate(enumerator, &ike_sa))
        !           201:        {
        !           202:                if (strcaseeq(config, ike_sa->get_name(ike_sa)))
        !           203:                {
        !           204:                        id = ike_sa->get_unique_id(ike_sa);
        !           205:                        break;
        !           206:                }
        !           207:        }
        !           208:        enumerator->destroy(enumerator);
        !           209:        if (id)
        !           210:        {
        !           211:                DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
        !           212:                charon->controller->terminate_ike(charon->controller, id, FALSE, NULL,
        !           213:                                                                                  NULL, 0);
        !           214:        }
        !           215:        else
        !           216:        {
        !           217:                DBG1(DBG_CFG, "unable to close IKE_SA '%s', not found", config);
        !           218:        }
        !           219:        return JOB_REQUEUE_NONE;
        !           220: }
        !           221: 
        !           222: /**
        !           223:  * Close a CHILD_SAs
        !           224:  */
        !           225: static job_requeue_t close_child(char *config)
        !           226: {
        !           227:        enumerator_t *enumerator, *children;
        !           228:        ike_sa_t *ike_sa;
        !           229:        child_sa_t *child_sa;
        !           230:        int id = 0;
        !           231: 
        !           232:        enumerator = charon->controller->create_ike_sa_enumerator(
        !           233:                                                                                                        charon->controller, TRUE);
        !           234:        while (enumerator->enumerate(enumerator, &ike_sa))
        !           235:        {
        !           236: 
        !           237:                children = ike_sa->create_child_sa_enumerator(ike_sa);
        !           238:                while (children->enumerate(children, (void**)&child_sa))
        !           239:                {
        !           240:                        if (streq(config, child_sa->get_name(child_sa)))
        !           241:                        {
        !           242:                                id = child_sa->get_unique_id(child_sa);
        !           243:                                break;
        !           244:                        }
        !           245:                }
        !           246:                children->destroy(children);
        !           247:        }
        !           248:        enumerator->destroy(enumerator);
        !           249:        if (id)
        !           250:        {
        !           251:                DBG1(DBG_CFG, "closing CHILD_SA '%s'", config);
        !           252:                charon->controller->terminate_child(charon->controller, id,
        !           253:                                                                                        NULL, NULL, 0);
        !           254:        }
        !           255:        else
        !           256:        {
        !           257:                DBG1(DBG_CFG, "unable to close CHILD_SA '%s', not found", config);
        !           258:        }
        !           259:        return JOB_REQUEUE_NONE;
        !           260: }
        !           261: 
        !           262: /**
        !           263:  * Load a single action
        !           264:  */
        !           265: static void load_action(settings_t *settings, char *action)
        !           266: {
        !           267:        static struct {
        !           268:                char *name;
        !           269:                callback_job_cb_t cb;
        !           270:        } actions[] = {
        !           271:                {"initiate",            (void*)initiate},
        !           272:                {"rekey_ike",           (void*)rekey_ike},
        !           273:                {"rekey_child",         (void*)rekey_child},
        !           274:                {"liveness",            (void*)liveness},
        !           275:                {"close_ike",           (void*)close_ike},
        !           276:                {"close_child",         (void*)close_child},
        !           277:        };
        !           278:        bool found = FALSE;
        !           279:        int i;
        !           280: 
        !           281:        for (i = 0; i < countof(actions); i++)
        !           282:        {
        !           283:                if (strncaseeq(actions[i].name, action, strlen(actions[i].name)))
        !           284:                {
        !           285:                        int delay;
        !           286:                        char *config;
        !           287: 
        !           288:                        found = TRUE;
        !           289:                        delay = settings->get_int(settings, "actions.%s.delay", 0, action);
        !           290:                        config = settings->get_str(settings, "actions.%s.config",
        !           291:                                                                           NULL, action);
        !           292:                        if (!config)
        !           293:                        {
        !           294:                                DBG1(DBG_CFG, "no config defined for action '%s'", action);
        !           295:                                break;
        !           296:                        }
        !           297:                        lib->scheduler->schedule_job(lib->scheduler,
        !           298:                                (job_t*)callback_job_create(actions[i].cb, config, NULL, NULL),
        !           299:                                delay);
        !           300:                }
        !           301:        }
        !           302:        if (!found)
        !           303:        {
        !           304:                DBG1(DBG_CFG, "unknown action '%s', skipped", action);
        !           305:        }
        !           306: }
        !           307: 
        !           308: /**
        !           309:  * Load configured actions
        !           310:  */
        !           311: static void load_actions(settings_t *settings)
        !           312: {
        !           313:        enumerator_t *enumerator;
        !           314:        char *action;
        !           315: 
        !           316:        enumerator = settings->create_section_enumerator(settings, "actions");
        !           317:        while (enumerator->enumerate(enumerator, &action))
        !           318:        {
        !           319:                load_action(settings, action);
        !           320:        }
        !           321:        enumerator->destroy(enumerator);
        !           322: }
        !           323: 
        !           324: METHOD(actions_t, destroy, void,
        !           325:        private_actions_t *this)
        !           326: {
        !           327:        free(this);
        !           328: }
        !           329: 
        !           330: /**
        !           331:  * See header
        !           332:  */
        !           333: actions_t *actions_create()
        !           334: {
        !           335:        private_actions_t *this;
        !           336: 
        !           337:        INIT(this,
        !           338:                .public = {
        !           339:                        .destroy = _destroy,
        !           340:                },
        !           341:        );
        !           342: 
        !           343:        load_actions(conftest->test);
        !           344: 
        !           345:        return &this->public;
        !           346: }

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