File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / starter / starterstroke.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, 4 months ago) by misho
Branches: strongswan, MAIN
CVS tags: v5_9_2p0, v5_8_4p7, HEAD
Strongswan

    1: /*
    2:  * Copyright (C) 2007-2015 Tobias Brunner
    3:  * Copyright (C) 2006 Martin Willi
    4:  * HSR Hochschule fuer Technik Rapperswil
    5:  *
    6:  * This program is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2 of the License, or (at your
    9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
   10:  *
   11:  * This program is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14:  * for more details.
   15:  */
   16: 
   17: #include <unistd.h>
   18: #include <stdlib.h>
   19: #include <stdint.h>
   20: #include <string.h>
   21: 
   22: #include <credentials/auth_cfg.h>
   23: 
   24: #include <library.h>
   25: #include <utils/debug.h>
   26: 
   27: #include <stroke_msg.h>
   28: 
   29: #include "starterstroke.h"
   30: #include "confread.h"
   31: #include "files.h"
   32: 
   33: #define IPV4_LEN	 4
   34: #define IPV6_LEN	16
   35: 
   36: static stroke_msg_t *create_stroke_msg(int type)
   37: {
   38: 	stroke_msg_t *msg;
   39: 
   40: 	INIT(msg,
   41: 		.type = type,
   42: 		.length = offsetof(stroke_msg_t, buffer),
   43: 	);
   44: 	return msg;
   45: }
   46: 
   47: #define push_string(msg, field, str) \
   48: 	push_string_impl(msg, offsetof(stroke_msg_t, field), str)
   49: #define push_string_end(msg, offset, field, str) \
   50: 	push_string_impl(msg, offset + offsetof(stroke_end_t, field), str)
   51: 
   52: static void push_string_impl(stroke_msg_t **msg, size_t offset, char *string)
   53: {
   54: 	size_t cur_len = (*msg)->length, str_len;
   55: 
   56: 	if (!string)
   57: 	{
   58: 		return;
   59: 	}
   60: 	str_len = strlen(string) + 1;
   61: 	if (cur_len + str_len >= UINT16_MAX)
   62: 	{
   63: 		(*msg)->length = UINT16_MAX;
   64: 		return;
   65: 	}
   66: 	while (cur_len + str_len > sizeof(stroke_msg_t) + (*msg)->buflen)
   67: 	{
   68: 		*msg = realloc(*msg, sizeof(stroke_msg_t) + (*msg)->buflen +
   69: 					   STROKE_BUF_LEN_INC);
   70: 		(*msg)->buflen += STROKE_BUF_LEN_INC;
   71: 	}
   72: 	(*msg)->length += str_len;
   73: 	strcpy((char*)*msg + cur_len, string);
   74: 	*(char**)((char*)*msg + offset) = (char*)cur_len;
   75: }
   76: 
   77: static int send_stroke_msg(stroke_msg_t *msg)
   78: {
   79: 	stream_t *stream;
   80: 	char *uri, buffer[64];
   81: 	int count;
   82: 
   83: 	if (msg->length == UINT16_MAX)
   84: 	{
   85: 		DBG1(DBG_APP, "stroke message exceeds maximum buffer size");
   86: 		free(msg);
   87: 		return -1;
   88: 	}
   89: 
   90: 	/* starter is not called from commandline, and therefore absolutely silent */
   91: 	msg->output_verbosity = -1;
   92: 
   93: 	uri = lib->settings->get_str(lib->settings, "%s.plugins.stroke.socket",
   94: 								 "unix://" CHARON_CTL_FILE, daemon_name);
   95: 	stream = lib->streams->connect(lib->streams, uri);
   96: 	if (!stream)
   97: 	{
   98: 		DBG1(DBG_APP, "failed to connect to stroke socket '%s'", uri);
   99: 		free(msg);
  100: 		return -1;
  101: 	}
  102: 
  103: 	if (!stream->write_all(stream, msg, msg->length))
  104: 	{
  105: 		DBG1(DBG_APP, "sending stroke message failed");
  106: 		stream->destroy(stream);
  107: 		free(msg);
  108: 		return -1;
  109: 	}
  110: 	while ((count = stream->read(stream, buffer, sizeof(buffer)-1, TRUE)) > 0)
  111: 	{
  112: 		buffer[count] = '\0';
  113: 		DBG1(DBG_APP, "%s", buffer);
  114: 	}
  115: 	if (count < 0)
  116: 	{
  117: 		DBG1(DBG_APP, "reading stroke response failed");
  118: 	}
  119: 	stream->destroy(stream);
  120: 	free(msg);
  121: 	return 0;
  122: }
  123: 
  124: static char* connection_name(starter_conn_t *conn)
  125: {
  126: 	 /* if connection name is '%auto', create a new name like conn_xxxxx */
  127: 	static char buf[32];
  128: 
  129: 	if (streq(conn->name, "%auto"))
  130: 	{
  131: 		sprintf(buf, "conn_%lu", conn->id);
  132: 		return buf;
  133: 	}
  134: 	return conn->name;
  135: }
  136: 
  137: static void add_end(stroke_msg_t **msg, size_t offset, starter_end_t *conn_end)
  138: {
  139: 	stroke_end_t *msg_end;
  140: 
  141: 	push_string_end(msg, offset, auth, conn_end->auth);
  142: 	push_string_end(msg, offset, auth2, conn_end->auth2);
  143: 	push_string_end(msg, offset, id, conn_end->id);
  144: 	push_string_end(msg, offset, id2, conn_end->id2);
  145: 	push_string_end(msg, offset, rsakey, conn_end->rsakey);
  146: 	push_string_end(msg, offset, cert, conn_end->cert);
  147: 	push_string_end(msg, offset, cert2, conn_end->cert2);
  148: 	push_string_end(msg, offset, cert_policy, conn_end->cert_policy);
  149: 	push_string_end(msg, offset, ca, conn_end->ca);
  150: 	push_string_end(msg, offset, ca2, conn_end->ca2);
  151: 	push_string_end(msg, offset, groups, conn_end->groups);
  152: 	push_string_end(msg, offset, groups2, conn_end->groups2);
  153: 	push_string_end(msg, offset, updown, conn_end->updown);
  154: 	if (conn_end->host)
  155: 	{
  156: 		push_string_end(msg, offset, address, conn_end->host);
  157: 	}
  158: 	else
  159: 	{
  160: 		push_string_end(msg, offset, address, "%any");
  161: 	}
  162: 	push_string_end(msg, offset, subnets, conn_end->subnet);
  163: 	push_string_end(msg, offset, sourceip, conn_end->sourceip);
  164: 	push_string_end(msg, offset, dns, conn_end->dns);
  165: 
  166: 	/* we can't assign it earlier as msg might change */
  167: 	msg_end = (stroke_end_t*)((char*)(*msg) + offset);
  168: 	msg_end->ikeport = conn_end->ikeport;
  169: 	msg_end->sendcert = conn_end->sendcert;
  170: 	msg_end->hostaccess = conn_end->hostaccess;
  171: 	msg_end->tohost = !conn_end->subnet;
  172: 	msg_end->allow_any = conn_end->allow_any;
  173: 	msg_end->protocol = conn_end->protocol;
  174: 	msg_end->from_port = conn_end->from_port;
  175: 	msg_end->to_port = conn_end->to_port;
  176: }
  177: 
  178: int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
  179: {
  180: 	stroke_msg_t *msg;
  181: 
  182: 	msg = create_stroke_msg(STR_ADD_CONN);
  183: 	msg->add_conn.version = conn->keyexchange;
  184: 	push_string(&msg, add_conn.name, connection_name(conn));
  185: 	push_string(&msg, add_conn.eap_identity, conn->eap_identity);
  186: 	push_string(&msg, add_conn.aaa_identity, conn->aaa_identity);
  187: 	push_string(&msg, add_conn.xauth_identity, conn->xauth_identity);
  188: 
  189: 	msg->add_conn.mode = conn->mode;
  190: 	msg->add_conn.proxy_mode = conn->proxy_mode;
  191: 
  192: 	if (!(conn->options & SA_OPTION_DONT_REKEY))
  193: 	{
  194: 		msg->add_conn.rekey.reauth = !(conn->options & SA_OPTION_DONT_REAUTH);
  195: 		msg->add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
  196: 		msg->add_conn.rekey.ike_lifetime = conn->sa_ike_life_seconds;
  197: 		msg->add_conn.rekey.margin = conn->sa_rekey_margin;
  198: 		msg->add_conn.rekey.life_bytes = conn->sa_ipsec_life_bytes;
  199: 		msg->add_conn.rekey.margin_bytes = conn->sa_ipsec_margin_bytes;
  200: 		msg->add_conn.rekey.life_packets = conn->sa_ipsec_life_packets;
  201: 		msg->add_conn.rekey.margin_packets = conn->sa_ipsec_margin_packets;
  202: 		msg->add_conn.rekey.fuzz = conn->sa_rekey_fuzz;
  203: 	}
  204: 	msg->add_conn.rekey.tries = conn->sa_keying_tries;
  205: 
  206: 	msg->add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
  207: 	msg->add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
  208: 	msg->add_conn.fragmentation = conn->fragmentation;
  209: 	msg->add_conn.ikedscp = conn->ikedscp;
  210: 	msg->add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
  211: 	msg->add_conn.install_policy = conn->install_policy;
  212: 	msg->add_conn.aggressive = conn->aggressive;
  213: 	msg->add_conn.pushmode = conn->options & SA_OPTION_MODECFG_PUSH;
  214: 	msg->add_conn.crl_policy = (crl_policy_t)cfg->setup.strictcrlpolicy;
  215: 	msg->add_conn.unique = cfg->setup.uniqueids;
  216: 	push_string(&msg, add_conn.algorithms.ike, conn->ike);
  217: 	push_string(&msg, add_conn.algorithms.esp, conn->esp);
  218: 	push_string(&msg, add_conn.algorithms.ah, conn->ah);
  219: 	msg->add_conn.dpd.delay = conn->dpd_delay;
  220: 	msg->add_conn.dpd.timeout = conn->dpd_timeout;
  221: 	msg->add_conn.dpd.action = conn->dpd_action;
  222: 	msg->add_conn.close_action = conn->close_action;
  223: 	msg->add_conn.sha256_96 = conn->sha256_96;
  224: 	msg->add_conn.inactivity = conn->inactivity;
  225: 	msg->add_conn.ikeme.mediation = conn->me_mediation;
  226: 	push_string(&msg, add_conn.ikeme.mediated_by, conn->me_mediated_by);
  227: 	push_string(&msg, add_conn.ikeme.peerid, conn->me_peerid);
  228: 	msg->add_conn.reqid = conn->reqid;
  229: 	msg->add_conn.replay_window = conn->replay_window;
  230: 	msg->add_conn.mark_in.value = conn->mark_in.value;
  231: 	msg->add_conn.mark_in.mask = conn->mark_in.mask;
  232: 	msg->add_conn.mark_out.value = conn->mark_out.value;
  233: 	msg->add_conn.mark_out.mask = conn->mark_out.mask;
  234: 	msg->add_conn.tfc = conn->tfc;
  235: 
  236: 	add_end(&msg, offsetof(stroke_msg_t, add_conn.me), &conn->left);
  237: 	add_end(&msg, offsetof(stroke_msg_t, add_conn.other), &conn->right);
  238: 
  239: 	if (!msg->add_conn.me.auth && !msg->add_conn.other.auth &&
  240: 		 conn->authby)
  241: 	{	/* leftauth/rightauth not set, use legacy options */
  242: 		if (streq(conn->authby, "rsa")   || streq(conn->authby, "rsasig")   ||
  243: 			streq(conn->authby, "ecdsa") || streq(conn->authby, "ecdsasig") ||
  244: 			streq(conn->authby, "pubkey"))
  245: 		{
  246: 			push_string(&msg, add_conn.me.auth, "pubkey");
  247: 			push_string(&msg, add_conn.other.auth, "pubkey");
  248: 		}
  249: 		else if (streq(conn->authby, "secret") || streq(conn->authby, "psk"))
  250: 		{
  251: 			push_string(&msg, add_conn.me.auth, "psk");
  252: 			push_string(&msg, add_conn.other.auth, "psk");
  253: 		}
  254: 		else if (streq(conn->authby, "xauthrsasig"))
  255: 		{
  256: 			push_string(&msg, add_conn.me.auth, "pubkey");
  257: 			push_string(&msg, add_conn.other.auth, "pubkey");
  258: 			if (conn->options & SA_OPTION_XAUTH_SERVER)
  259: 			{
  260: 				push_string(&msg, add_conn.other.auth2, "xauth");
  261: 			}
  262: 			else
  263: 			{
  264: 				push_string(&msg, add_conn.me.auth2, "xauth");
  265: 			}
  266: 		}
  267: 		else if (streq(conn->authby, "xauthpsk"))
  268: 		{
  269: 			push_string(&msg, add_conn.me.auth, "psk");
  270: 			push_string(&msg, add_conn.other.auth, "psk");
  271: 			if (conn->options & SA_OPTION_XAUTH_SERVER)
  272: 			{
  273: 				push_string(&msg, add_conn.other.auth2, "xauth");
  274: 			}
  275: 			else
  276: 			{
  277: 				push_string(&msg, add_conn.me.auth2, "xauth");
  278: 			}
  279: 		}
  280: 	}
  281: 	return send_stroke_msg(msg);
  282: }
  283: 
  284: int starter_stroke_del_conn(starter_conn_t *conn)
  285: {
  286: 	stroke_msg_t *msg;
  287: 
  288: 	msg = create_stroke_msg(STR_DEL_CONN);
  289: 	push_string(&msg, del_conn.name, connection_name(conn));
  290: 	return send_stroke_msg(msg);
  291: }
  292: 
  293: int starter_stroke_route_conn(starter_conn_t *conn)
  294: {
  295: 	stroke_msg_t *msg;
  296: 
  297: 	msg = create_stroke_msg(STR_ROUTE);
  298: 	push_string(&msg, route.name, connection_name(conn));
  299: 	return send_stroke_msg(msg);
  300: }
  301: 
  302: int starter_stroke_unroute_conn(starter_conn_t *conn)
  303: {
  304: 	stroke_msg_t *msg;
  305: 
  306: 	msg = create_stroke_msg(STR_UNROUTE);
  307: 	push_string(&msg, route.name, connection_name(conn));
  308: 	return send_stroke_msg(msg);
  309: }
  310: 
  311: int starter_stroke_initiate_conn(starter_conn_t *conn)
  312: {
  313: 	stroke_msg_t *msg;
  314: 
  315: 	msg = create_stroke_msg(STR_INITIATE);
  316: 	push_string(&msg, initiate.name, connection_name(conn));
  317: 	return send_stroke_msg(msg);
  318: }
  319: 
  320: int starter_stroke_add_ca(starter_ca_t *ca)
  321: {
  322: 	stroke_msg_t *msg;
  323: 
  324: 	msg = create_stroke_msg(STR_ADD_CA);
  325: 	push_string(&msg, add_ca.name, ca->name);
  326: 	push_string(&msg, add_ca.cacert, ca->cacert);
  327: 	push_string(&msg, add_ca.crluri, ca->crluri);
  328: 	push_string(&msg, add_ca.crluri2, ca->crluri2);
  329: 	push_string(&msg, add_ca.ocspuri, ca->ocspuri);
  330: 	push_string(&msg, add_ca.ocspuri2, ca->ocspuri2);
  331: 	push_string(&msg, add_ca.certuribase, ca->certuribase);
  332: 	return send_stroke_msg(msg);
  333: }
  334: 
  335: int starter_stroke_del_ca(starter_ca_t *ca)
  336: {
  337: 	stroke_msg_t *msg;
  338: 
  339: 	msg = create_stroke_msg(STR_DEL_CA);
  340: 	push_string(&msg, del_ca.name, ca->name);
  341: 	return send_stroke_msg(msg);
  342: }
  343: 
  344: int starter_stroke_configure(starter_config_t *cfg)
  345: {
  346: 	stroke_msg_t *msg;
  347: 
  348: 	if (cfg->setup.cachecrls)
  349: 	{
  350: 		msg = create_stroke_msg(STR_CONFIG);
  351: 		msg->config.cachecrl = 1;
  352: 		return send_stroke_msg(msg);
  353: 	}
  354: 	return 0;
  355: }

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