Annotation of embedaddon/strongswan/src/libcharon/processing/jobs/initiate_mediation_job.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2007-2008 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      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 "initiate_mediation_job.h"
                     17: 
                     18: #include <sa/ike_sa.h>
                     19: #include <daemon.h>
                     20: 
                     21: 
                     22: typedef struct private_initiate_mediation_job_t private_initiate_mediation_job_t;
                     23: 
                     24: /**
                     25:  * Private data of an initiate_mediation_job_t Object
                     26:  */
                     27: struct private_initiate_mediation_job_t {
                     28:        /**
                     29:         * public initiate_mediation_job_t interface
                     30:         */
                     31:        initiate_mediation_job_t public;
                     32: 
                     33:        /**
                     34:         * ID of the IKE_SA of the mediated connection.
                     35:         */
                     36:        ike_sa_id_t *mediated_sa_id;
                     37: 
                     38:        /**
                     39:         * ID of the IKE_SA of the mediation connection.
                     40:         */
                     41:        ike_sa_id_t *mediation_sa_id;
                     42: };
                     43: 
                     44: METHOD(job_t, destroy, void,
                     45:        private_initiate_mediation_job_t *this)
                     46: {
                     47:        DESTROY_IF(this->mediation_sa_id);
                     48:        DESTROY_IF(this->mediated_sa_id);
                     49:        free(this);
                     50: }
                     51: 
                     52: /**
                     53:  * Callback to handle initiation of mediation connection
                     54:  */
                     55: static bool initiate_callback(private_initiate_mediation_job_t *this,
                     56:                        debug_t group, level_t level, ike_sa_t *ike_sa,
                     57:                        char *message)
                     58: {
                     59:        if (ike_sa && !this->mediation_sa_id)
                     60:        {
                     61:                this->mediation_sa_id = ike_sa->get_id(ike_sa);
                     62:                this->mediation_sa_id = this->mediation_sa_id->clone(this->mediation_sa_id);
                     63:        }
                     64:        return TRUE;
                     65: }
                     66: 
                     67: METHOD(job_t, initiate, job_requeue_t,
                     68:        private_initiate_mediation_job_t *this)
                     69: {
                     70:        ike_sa_t *mediated_sa, *mediation_sa;
                     71:        peer_cfg_t *mediated_cfg, *mediation_cfg;
                     72:        enumerator_t *enumerator;
                     73:        auth_cfg_t *auth_cfg;
                     74: 
                     75:        mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
                     76:                                                                                                   this->mediated_sa_id);
                     77:        if (mediated_sa)
                     78:        {
                     79:                DBG1(DBG_IKE, "initiating mediation connection");
                     80:                mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
                     81:                mediated_cfg->get_ref(mediated_cfg);
                     82: 
                     83:                charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
                     84: 
                     85:                mediation_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
                     86:                                                                mediated_cfg->get_mediated_by(mediated_cfg));
                     87:                if (!mediation_cfg)
                     88:                {
                     89:                        DBG1(DBG_IKE, "mediation connection '%s' not found, aborting",
                     90:                                 mediated_cfg->get_mediated_by(mediated_cfg));
                     91:                        mediated_cfg->destroy(mediated_cfg);
                     92:                        return JOB_REQUEUE_NONE;
                     93:                }
                     94:                if (!mediation_cfg->is_mediation(mediation_cfg))
                     95:                {
                     96:                        DBG1(DBG_CFG, "connection '%s' as referred to by '%s' is no "
                     97:                                 "mediation connection, aborting",
                     98:                                 mediated_cfg->get_mediated_by(mediated_cfg),
                     99:                                 mediated_cfg->get_name(mediated_cfg));
                    100:                        mediated_cfg->destroy(mediated_cfg);
                    101:                        mediation_cfg->destroy(mediation_cfg);
                    102:                        return JOB_REQUEUE_NONE;
                    103:                }
                    104: 
                    105:                enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
                    106:                                                                                                                           TRUE);
                    107:                if (!enumerator->enumerate(enumerator, &auth_cfg) ||
                    108:                        auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY) == NULL)
                    109:                {
                    110:                        mediated_cfg->destroy(mediated_cfg);
                    111:                        mediation_cfg->destroy(mediation_cfg);
                    112:                        enumerator->destroy(enumerator);
                    113:                        return JOB_REQUEUE_NONE;
                    114:                }
                    115:                enumerator->destroy(enumerator);
                    116: 
                    117:                if (charon->connect_manager->check_and_register(charon->connect_manager,
                    118:                                auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY),
                    119:                                mediated_cfg->get_peer_id(mediated_cfg),
                    120:                                this->mediated_sa_id))
                    121:                {
                    122:                        mediated_cfg->destroy(mediated_cfg);
                    123:                        mediation_cfg->destroy(mediation_cfg);
                    124: 
                    125:                        mediated_sa = charon->ike_sa_manager->checkout(
                    126:                                                                charon->ike_sa_manager, this->mediated_sa_id);
                    127:                        if (mediated_sa)
                    128:                        {
                    129:                                DBG1(DBG_IKE, "mediation with the same peer is already in "
                    130:                                         "progress, queued");
                    131:                                charon->ike_sa_manager->checkin(
                    132:                                                                charon->ike_sa_manager, mediated_sa);
                    133:                        }
                    134:                        return JOB_REQUEUE_NONE;
                    135:                }
                    136:                /* we need an additional reference because initiate consumes one */
                    137:                mediation_cfg->get_ref(mediation_cfg);
                    138: 
                    139:                if (charon->controller->initiate(charon->controller, mediation_cfg, NULL,
                    140:                                (controller_cb_t)initiate_callback, this, 0, FALSE) != SUCCESS)
                    141:                {
                    142:                        mediation_cfg->destroy(mediation_cfg);
                    143:                        mediated_cfg->destroy(mediated_cfg);
                    144:                        mediated_sa = charon->ike_sa_manager->checkout(
                    145:                                                                charon->ike_sa_manager, this->mediated_sa_id);
                    146:                        if (mediated_sa)
                    147:                        {
                    148:                                DBG1(DBG_IKE, "initiating mediation connection failed");
                    149:                                charon->ike_sa_manager->checkin_and_destroy(
                    150:                                                                        charon->ike_sa_manager, mediated_sa);
                    151:                        }
                    152:                        return JOB_REQUEUE_NONE;
                    153:                }
                    154:                mediation_cfg->destroy(mediation_cfg);
                    155: 
                    156:                mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
                    157:                                                                                                                this->mediation_sa_id);
                    158:                if (mediation_sa)
                    159:                {
                    160:                        if (mediation_sa->initiate_mediation(mediation_sa,
                    161:                                                                                                 mediated_cfg) != SUCCESS)
                    162:                        {
                    163:                                mediated_cfg->destroy(mediated_cfg);
                    164:                                charon->ike_sa_manager->checkin_and_destroy(
                    165:                                                                charon->ike_sa_manager, mediation_sa);
                    166:                                mediated_sa = charon->ike_sa_manager->checkout(
                    167:                                                                charon->ike_sa_manager, this->mediated_sa_id);
                    168:                                if (mediated_sa)
                    169:                                {
                    170:                                        DBG1(DBG_IKE, "establishing mediation connection failed");
                    171:                                        charon->ike_sa_manager->checkin_and_destroy(
                    172:                                                                                charon->ike_sa_manager, mediated_sa);
                    173:                                }
                    174:                                return JOB_REQUEUE_NONE;
                    175:                        }
                    176:                        charon->ike_sa_manager->checkin(charon->ike_sa_manager,
                    177:                                                                                        mediation_sa);
                    178:                }
                    179:                mediated_cfg->destroy(mediated_cfg);
                    180:        }
                    181:        else
                    182:        {       /* newly created IKE_SA is not checked in yet, try again */
                    183:                return JOB_RESCHEDULE_MS(100);
                    184:        }
                    185:        return JOB_REQUEUE_NONE;
                    186: }
                    187: 
                    188: METHOD(job_t, reinitiate, job_requeue_t,
                    189:        private_initiate_mediation_job_t *this)
                    190: {
                    191:        ike_sa_t *mediated_sa, *mediation_sa;
                    192:        peer_cfg_t *mediated_cfg;
                    193: 
                    194:        mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
                    195:                                                                                                   this->mediated_sa_id);
                    196:        if (mediated_sa)
                    197:        {
                    198:                mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
                    199:                mediated_cfg->get_ref(mediated_cfg);
                    200:                charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
                    201: 
                    202:                mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
                    203:                                                                                                                this->mediation_sa_id);
                    204:                if (mediation_sa)
                    205:                {
                    206:                        if (mediation_sa->initiate_mediation(mediation_sa,
                    207:                                                                                                 mediated_cfg) != SUCCESS)
                    208:                        {
                    209:                                DBG1(DBG_JOB, "initiating mediated connection '%s' failed",
                    210:                                         mediated_cfg->get_name(mediated_cfg));
                    211:                                mediated_cfg->destroy(mediated_cfg);
                    212:                                charon->ike_sa_manager->checkin_and_destroy(
                    213:                                                                                charon->ike_sa_manager,
                    214:                                                                                mediation_sa);
                    215:                                mediated_sa = charon->ike_sa_manager->checkout(
                    216:                                                                                charon->ike_sa_manager,
                    217:                                                                                this->mediated_sa_id);
                    218:                                if (mediated_sa)
                    219:                                {
                    220:                                        DBG1(DBG_IKE, "establishing mediation connection failed");
                    221:                                        charon->ike_sa_manager->checkin_and_destroy(
                    222:                                                                                charon->ike_sa_manager,
                    223:                                                                                mediated_sa);
                    224:                                }
                    225:                                return JOB_REQUEUE_NONE;
                    226:                        }
                    227:                        charon->ike_sa_manager->checkin(charon->ike_sa_manager,
                    228:                                                                                        mediation_sa);
                    229:                }
                    230: 
                    231:                mediated_cfg->destroy(mediated_cfg);
                    232:        }
                    233:        return JOB_REQUEUE_NONE;
                    234: }
                    235: 
                    236: METHOD(job_t, get_priority, job_priority_t,
                    237:        private_initiate_mediation_job_t *this)
                    238: {
                    239:        return JOB_PRIO_MEDIUM;
                    240: }
                    241: 
                    242: /**
                    243:  * Creates an empty job
                    244:  */
                    245: static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
                    246: {
                    247:        private_initiate_mediation_job_t *this;
                    248:        INIT(this,
                    249:                .public = {
                    250:                        .job_interface = {
                    251:                                .get_priority = _get_priority,
                    252:                                .destroy = _destroy,
                    253:                        },
                    254:                },
                    255:        );
                    256:        return this;
                    257: }
                    258: 
                    259: /*
                    260:  * Described in header
                    261:  */
                    262: initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
                    263: {
                    264:        private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
                    265: 
                    266:        this->public.job_interface.execute = _initiate;
                    267:        this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
                    268: 
                    269:        return &this->public;
                    270: }
                    271: 
                    272: /*
                    273:  * Described in header
                    274:  */
                    275: initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation_sa_id,
                    276:                ike_sa_id_t *mediated_sa_id)
                    277: {
                    278:        private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
                    279: 
                    280:        this->public.job_interface.execute = _reinitiate;
                    281:        this->mediation_sa_id = mediation_sa_id->clone(mediation_sa_id);
                    282:        this->mediated_sa_id = mediated_sa_id->clone(mediated_sa_id);
                    283: 
                    284:        return &this->public;
                    285: }

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