File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / conftest / actions.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 09:46:43 2020 UTC (4 years, 1 month ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    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>