Return to actions.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / conftest |
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, ¤t)) ! 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: }