Annotation of embedaddon/strongswan/src/starter/starterstroke.c, revision 1.1.1.1
1.1 misho 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>