Return to initiate_mediation_job.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / processing / jobs |
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: }