Annotation of embedaddon/strongswan/src/libcharon/processing/jobs/initiate_mediation_job.c, revision 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>