Annotation of embedaddon/strongswan/src/conftest/actions.c, revision 1.1.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>