]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
stroke: Dynamically resize stroke messages
authorTobias Brunner <tobias@strongswan.org>
Wed, 20 May 2015 16:21:15 +0000 (18:21 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 22 May 2015 08:40:15 +0000 (10:40 +0200)
The maximum size of a stroke message is currently 64k due to the 2 byte
length field.

Fixes #943.

src/starter/starterstroke.c
src/stroke/stroke.c
src/stroke/stroke_msg.h

index 6e1f1605de461ce3a0ccbaeff0c006910637930f..79a92cdad493e000b3ba4b9b17dad6c9aa4c5643 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2007-2015 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
 #define IPV4_LEN        4
 #define IPV6_LEN       16
 
-static char* push_string(stroke_msg_t *msg, char *string)
+static stroke_msg_t *create_stroke_msg(int type)
 {
-       unsigned long string_start = msg->length;
+       stroke_msg_t *msg;
 
-       if (string == NULL)
+       INIT(msg,
+               .type = type,
+               .length = offsetof(stroke_msg_t, buffer),
+       );
+       return msg;
+}
+
+#define push_string(msg, field, str) \
+       push_string_impl(msg, offsetof(stroke_msg_t, field), str)
+#define push_string_end(msg, offset, field, str) \
+       push_string_impl(msg, offset + offsetof(stroke_end_t, field), str)
+
+static void push_string_impl(stroke_msg_t **msg, size_t offset, char *string)
+{
+       size_t cur_len = (*msg)->length, str_len;
+
+       if (!string)
        {
-               return NULL;
+               return;
        }
-       else if ((size_t)msg->length + strlen(string) >= sizeof(stroke_msg_t))
+       str_len = strlen(string) + 1;
+       if (cur_len + str_len >= UINT16_MAX)
        {
-               /* set invalid length to fail during message send */
-               msg->length = ~0;
-               return NULL;
+               (*msg)->length = UINT16_MAX;
+               return;
        }
-       else
+       while (cur_len + str_len > sizeof(stroke_msg_t) + (*msg)->buflen)
        {
-               msg->length += strlen(string) + 1;
-               strcpy((char*)msg + string_start, string);
-               return (char*)string_start;
+               *msg = realloc(*msg, sizeof(stroke_msg_t) + (*msg)->buflen +
+                                          STROKE_BUF_LEN_INC);
+               (*msg)->buflen += STROKE_BUF_LEN_INC;
        }
+       (*msg)->length += str_len;
+       strcpy((char*)*msg + cur_len, string);
+       *(char**)((char*)*msg + offset) = (char*)cur_len;
 }
 
-static int send_stroke_msg (stroke_msg_t *msg)
+static int send_stroke_msg(stroke_msg_t *msg)
 {
        stream_t *stream;
        char *uri, buffer[64];
        int count;
 
-       if (msg->length > sizeof(stroke_msg_t))
+       if (msg->length == UINT16_MAX)
        {
-               DBG1(DBG_APP, "stroke message exceeds buffer size");
+               DBG1(DBG_APP, "stroke message exceeds maximum buffer size");
+               free(msg);
                return -1;
        }
 
@@ -74,6 +95,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
        if (!stream)
        {
                DBG1(DBG_APP, "failed to connect to stroke socket '%s'", uri);
+               free(msg);
                return -1;
        }
 
@@ -81,6 +103,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
        {
                DBG1(DBG_APP, "sending stroke message failed");
                stream->destroy(stream);
+               free(msg);
                return -1;
        }
        while ((count = stream->read(stream, buffer, sizeof(buffer)-1, TRUE)) > 0)
@@ -93,6 +116,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
                DBG1(DBG_APP, "reading stroke response failed");
        }
        stream->destroy(stream);
+       free(msg);
        return 0;
 }
 
@@ -109,33 +133,38 @@ static char* connection_name(starter_conn_t *conn)
        return conn->name;
 }
 
-static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, starter_end_t *conn_end)
+static void add_end(stroke_msg_t **msg, size_t offset, starter_end_t *conn_end)
 {
-       msg_end->auth = push_string(msg, conn_end->auth);
-       msg_end->auth2 = push_string(msg, conn_end->auth2);
-       msg_end->id = push_string(msg, conn_end->id);
-       msg_end->id2 = push_string(msg, conn_end->id2);
-       msg_end->rsakey = push_string(msg, conn_end->rsakey);
-       msg_end->cert = push_string(msg, conn_end->cert);
-       msg_end->cert2 = push_string(msg, conn_end->cert2);
-       msg_end->cert_policy = push_string(msg, conn_end->cert_policy);
-       msg_end->ca = push_string(msg, conn_end->ca);
-       msg_end->ca2 = push_string(msg, conn_end->ca2);
-       msg_end->groups = push_string(msg, conn_end->groups);
-       msg_end->groups2 = push_string(msg, conn_end->groups2);
-       msg_end->updown = push_string(msg, conn_end->updown);
+       stroke_end_t *msg_end;
+
+       push_string_end(msg, offset, auth, conn_end->auth);
+       push_string_end(msg, offset, auth2, conn_end->auth2);
+       push_string_end(msg, offset, id, conn_end->id);
+       push_string_end(msg, offset, id2, conn_end->id2);
+       push_string_end(msg, offset, rsakey, conn_end->rsakey);
+       push_string_end(msg, offset, cert, conn_end->cert);
+       push_string_end(msg, offset, cert2, conn_end->cert2);
+       push_string_end(msg, offset, cert_policy, conn_end->cert_policy);
+       push_string_end(msg, offset, ca, conn_end->ca);
+       push_string_end(msg, offset, ca2, conn_end->ca2);
+       push_string_end(msg, offset, groups, conn_end->groups);
+       push_string_end(msg, offset, groups2, conn_end->groups2);
+       push_string_end(msg, offset, updown, conn_end->updown);
        if (conn_end->host)
        {
-               msg_end->address = push_string(msg, conn_end->host);
+               push_string_end(msg, offset, address, conn_end->host);
        }
        else
        {
-               msg_end->address = push_string(msg, "%any");
+               push_string_end(msg, offset, address, "%any");
        }
+       push_string_end(msg, offset, subnets, conn_end->subnet);
+       push_string_end(msg, offset, sourceip, conn_end->sourceip);
+       push_string_end(msg, offset, dns, conn_end->dns);
+
+       /* we can't assign it earlier as msg might change */
+       msg_end = (stroke_end_t*)((char*)(*msg) + offset);
        msg_end->ikeport = conn_end->ikeport;
-       msg_end->subnets = push_string(msg, conn_end->subnet);
-       msg_end->sourceip = push_string(msg, conn_end->sourceip);
-       msg_end->dns = push_string(msg, conn_end->dns);
        msg_end->sendcert = conn_end->sendcert;
        msg_end->hostaccess = conn_end->hostaccess;
        msg_end->tohost = !conn_end->subnet;
@@ -147,187 +176,178 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
 
 int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       memset(&msg, 0, sizeof(msg));
-       msg.type = STR_ADD_CONN;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.add_conn.version = conn->keyexchange;
-       msg.add_conn.name = push_string(&msg, connection_name(conn));
-       msg.add_conn.eap_identity = push_string(&msg, conn->eap_identity);
-       msg.add_conn.aaa_identity = push_string(&msg, conn->aaa_identity);
-       msg.add_conn.xauth_identity = push_string(&msg, conn->xauth_identity);
+       msg = create_stroke_msg(STR_ADD_CONN);
+       msg->add_conn.version = conn->keyexchange;
+       push_string(&msg, add_conn.name, connection_name(conn));
+       push_string(&msg, add_conn.eap_identity, conn->eap_identity);
+       push_string(&msg, add_conn.aaa_identity, conn->aaa_identity);
+       push_string(&msg, add_conn.xauth_identity, conn->xauth_identity);
 
-       msg.add_conn.mode = conn->mode;
-       msg.add_conn.proxy_mode = conn->proxy_mode;
+       msg->add_conn.mode = conn->mode;
+       msg->add_conn.proxy_mode = conn->proxy_mode;
 
        if (!(conn->options & SA_OPTION_DONT_REKEY))
        {
-               msg.add_conn.rekey.reauth = !(conn->options & SA_OPTION_DONT_REAUTH);
-               msg.add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
-               msg.add_conn.rekey.ike_lifetime = conn->sa_ike_life_seconds;
-               msg.add_conn.rekey.margin = conn->sa_rekey_margin;
-               msg.add_conn.rekey.life_bytes = conn->sa_ipsec_life_bytes;
-               msg.add_conn.rekey.margin_bytes = conn->sa_ipsec_margin_bytes;
-               msg.add_conn.rekey.life_packets = conn->sa_ipsec_life_packets;
-               msg.add_conn.rekey.margin_packets = conn->sa_ipsec_margin_packets;
-               msg.add_conn.rekey.fuzz = conn->sa_rekey_fuzz;
+               msg->add_conn.rekey.reauth = !(conn->options & SA_OPTION_DONT_REAUTH);
+               msg->add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
+               msg->add_conn.rekey.ike_lifetime = conn->sa_ike_life_seconds;
+               msg->add_conn.rekey.margin = conn->sa_rekey_margin;
+               msg->add_conn.rekey.life_bytes = conn->sa_ipsec_life_bytes;
+               msg->add_conn.rekey.margin_bytes = conn->sa_ipsec_margin_bytes;
+               msg->add_conn.rekey.life_packets = conn->sa_ipsec_life_packets;
+               msg->add_conn.rekey.margin_packets = conn->sa_ipsec_margin_packets;
+               msg->add_conn.rekey.fuzz = conn->sa_rekey_fuzz;
        }
-       msg.add_conn.rekey.tries = conn->sa_keying_tries;
-
-       msg.add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
-       msg.add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
-       msg.add_conn.fragmentation = conn->fragmentation;
-       msg.add_conn.ikedscp = conn->ikedscp;
-       msg.add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
-       msg.add_conn.install_policy = conn->install_policy;
-       msg.add_conn.aggressive = conn->aggressive;
-       msg.add_conn.pushmode = conn->options & SA_OPTION_MODECFG_PUSH;
-       msg.add_conn.crl_policy = (crl_policy_t)cfg->setup.strictcrlpolicy;
-       msg.add_conn.unique = cfg->setup.uniqueids;
-       msg.add_conn.algorithms.ike = push_string(&msg, conn->ike);
-       msg.add_conn.algorithms.esp = push_string(&msg, conn->esp);
-       msg.add_conn.algorithms.ah = push_string(&msg, conn->ah);
-       msg.add_conn.dpd.delay = conn->dpd_delay;
-       msg.add_conn.dpd.timeout = conn->dpd_timeout;
-       msg.add_conn.dpd.action = conn->dpd_action;
-       msg.add_conn.close_action = conn->close_action;
-       msg.add_conn.inactivity = conn->inactivity;
-       msg.add_conn.ikeme.mediation = conn->me_mediation;
-       msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);
-       msg.add_conn.ikeme.peerid = push_string(&msg, conn->me_peerid);
-       msg.add_conn.reqid = conn->reqid;
-       msg.add_conn.replay_window = conn->replay_window;
-       msg.add_conn.mark_in.value = conn->mark_in.value;
-       msg.add_conn.mark_in.mask = conn->mark_in.mask;
-       msg.add_conn.mark_out.value = conn->mark_out.value;
-       msg.add_conn.mark_out.mask = conn->mark_out.mask;
-       msg.add_conn.tfc = conn->tfc;
-
-       starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->left);
-       starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->right);
-
-       if (!msg.add_conn.me.auth && !msg.add_conn.other.auth &&
+       msg->add_conn.rekey.tries = conn->sa_keying_tries;
+
+       msg->add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
+       msg->add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
+       msg->add_conn.fragmentation = conn->fragmentation;
+       msg->add_conn.ikedscp = conn->ikedscp;
+       msg->add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
+       msg->add_conn.install_policy = conn->install_policy;
+       msg->add_conn.aggressive = conn->aggressive;
+       msg->add_conn.pushmode = conn->options & SA_OPTION_MODECFG_PUSH;
+       msg->add_conn.crl_policy = (crl_policy_t)cfg->setup.strictcrlpolicy;
+       msg->add_conn.unique = cfg->setup.uniqueids;
+       push_string(&msg, add_conn.algorithms.ike, conn->ike);
+       push_string(&msg, add_conn.algorithms.esp, conn->esp);
+       push_string(&msg, add_conn.algorithms.ah, conn->ah);
+       msg->add_conn.dpd.delay = conn->dpd_delay;
+       msg->add_conn.dpd.timeout = conn->dpd_timeout;
+       msg->add_conn.dpd.action = conn->dpd_action;
+       msg->add_conn.close_action = conn->close_action;
+       msg->add_conn.inactivity = conn->inactivity;
+       msg->add_conn.ikeme.mediation = conn->me_mediation;
+       push_string(&msg, add_conn.ikeme.mediated_by, conn->me_mediated_by);
+       push_string(&msg, add_conn.ikeme.peerid, conn->me_peerid);
+       msg->add_conn.reqid = conn->reqid;
+       msg->add_conn.replay_window = conn->replay_window;
+       msg->add_conn.mark_in.value = conn->mark_in.value;
+       msg->add_conn.mark_in.mask = conn->mark_in.mask;
+       msg->add_conn.mark_out.value = conn->mark_out.value;
+       msg->add_conn.mark_out.mask = conn->mark_out.mask;
+       msg->add_conn.tfc = conn->tfc;
+
+       add_end(&msg, offsetof(stroke_msg_t, add_conn.me), &conn->left);
+       add_end(&msg, offsetof(stroke_msg_t, add_conn.other), &conn->right);
+
+       if (!msg->add_conn.me.auth && !msg->add_conn.other.auth &&
                 conn->authby)
        {       /* leftauth/rightauth not set, use legacy options */
                if (streq(conn->authby, "rsa")   || streq(conn->authby, "rsasig")   ||
                        streq(conn->authby, "ecdsa") || streq(conn->authby, "ecdsasig") ||
                        streq(conn->authby, "pubkey"))
                {
-                       msg.add_conn.me.auth = push_string(&msg, "pubkey");
-                       msg.add_conn.other.auth = push_string(&msg, "pubkey");
+                       push_string(&msg, add_conn.me.auth, "pubkey");
+                       push_string(&msg, add_conn.other.auth, "pubkey");
                }
                else if (streq(conn->authby, "secret") || streq(conn->authby, "psk"))
                {
-                       msg.add_conn.me.auth = push_string(&msg, "psk");
-                       msg.add_conn.other.auth = push_string(&msg, "psk");
+                       push_string(&msg, add_conn.me.auth, "psk");
+                       push_string(&msg, add_conn.other.auth, "psk");
                }
                else if (streq(conn->authby, "xauthrsasig"))
                {
-                       msg.add_conn.me.auth = push_string(&msg, "pubkey");
-                       msg.add_conn.other.auth = push_string(&msg, "pubkey");
+                       push_string(&msg, add_conn.me.auth, "pubkey");
+                       push_string(&msg, add_conn.other.auth, "pubkey");
                        if (conn->options & SA_OPTION_XAUTH_SERVER)
                        {
-                               msg.add_conn.other.auth2 = push_string(&msg, "xauth");
+                               push_string(&msg, add_conn.other.auth2, "xauth");
                        }
                        else
                        {
-                               msg.add_conn.me.auth2 = push_string(&msg, "xauth");
+                               push_string(&msg, add_conn.me.auth2, "xauth");
                        }
                }
                else if (streq(conn->authby, "xauthpsk"))
                {
-                       msg.add_conn.me.auth = push_string(&msg, "psk");
-                       msg.add_conn.other.auth = push_string(&msg, "psk");
+                       push_string(&msg, add_conn.me.auth, "psk");
+                       push_string(&msg, add_conn.other.auth, "psk");
                        if (conn->options & SA_OPTION_XAUTH_SERVER)
                        {
-                               msg.add_conn.other.auth2 = push_string(&msg, "xauth");
+                               push_string(&msg, add_conn.other.auth2, "xauth");
                        }
                        else
                        {
-                               msg.add_conn.me.auth2 = push_string(&msg, "xauth");
+                               push_string(&msg, add_conn.me.auth2, "xauth");
                        }
                }
        }
-       return send_stroke_msg(&msg);
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_del_conn(starter_conn_t *conn)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_DEL_CONN;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.del_conn.name = push_string(&msg, connection_name(conn));
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_DEL_CONN);
+       push_string(&msg, del_conn.name, connection_name(conn));
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_route_conn(starter_conn_t *conn)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_ROUTE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.route.name = push_string(&msg, connection_name(conn));
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_ROUTE);
+       push_string(&msg, route.name, connection_name(conn));
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_unroute_conn(starter_conn_t *conn)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_UNROUTE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.route.name = push_string(&msg, connection_name(conn));
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_UNROUTE);
+       push_string(&msg, route.name, connection_name(conn));
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_initiate_conn(starter_conn_t *conn)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_INITIATE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.initiate.name = push_string(&msg, connection_name(conn));
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_INITIATE);
+       push_string(&msg, initiate.name, connection_name(conn));
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_add_ca(starter_ca_t *ca)
 {
-       stroke_msg_t msg;
-
-       msg.type = STR_ADD_CA;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.add_ca.name =        push_string(&msg, ca->name);
-       msg.add_ca.cacert =      push_string(&msg, ca->cacert);
-       msg.add_ca.crluri =      push_string(&msg, ca->crluri);
-       msg.add_ca.crluri2 =     push_string(&msg, ca->crluri2);
-       msg.add_ca.ocspuri =     push_string(&msg, ca->ocspuri);
-       msg.add_ca.ocspuri2 =    push_string(&msg, ca->ocspuri2);
-       msg.add_ca.certuribase = push_string(&msg, ca->certuribase);
-       return send_stroke_msg(&msg);
+       stroke_msg_t *msg;
+
+       msg = create_stroke_msg(STR_ADD_CA);
+       push_string(&msg, add_ca.name, ca->name);
+       push_string(&msg, add_ca.cacert, ca->cacert);
+       push_string(&msg, add_ca.crluri, ca->crluri);
+       push_string(&msg, add_ca.crluri2, ca->crluri2);
+       push_string(&msg, add_ca.ocspuri, ca->ocspuri);
+       push_string(&msg, add_ca.ocspuri2, ca->ocspuri2);
+       push_string(&msg, add_ca.certuribase, ca->certuribase);
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_del_ca(starter_ca_t *ca)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_DEL_CA;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.del_ca.name = push_string(&msg, ca->name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_DEL_CA);
+       push_string(&msg, del_ca.name, ca->name);
+       return send_stroke_msg(msg);
 }
 
 int starter_stroke_configure(starter_config_t *cfg)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
        if (cfg->setup.cachecrls)
        {
-               msg.type = STR_CONFIG;
-               msg.length = offsetof(stroke_msg_t, buffer);
-               msg.config.cachecrl = 1;
-               return send_stroke_msg(&msg);
+               msg = create_stroke_msg(STR_CONFIG);
+               msg->config.cachecrl = 1;
+               return send_stroke_msg(msg);
        }
        return 0;
 }
index ae20b0ca38feeef4e711b7eecf8222fe293f36ee..07911d2d2762fa05ebb37b75d02be758d22679ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2014 Tobias Brunner
+ * Copyright (C) 2007-2015 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -33,28 +33,58 @@ struct stroke_token {
 static char *daemon_name = "charon";
 static int output_verbosity = 1; /* CONTROL */
 
-static char* push_string(stroke_msg_t *msg, char *string)
+static stroke_msg_t *create_stroke_msg(int type)
 {
-       unsigned long string_start = msg->length;
+       stroke_msg_t *msg;
 
-       if (string == NULL ||  msg->length + strlen(string) >= sizeof(stroke_msg_t))
+       INIT(msg,
+               .type = type,
+               .length = offsetof(stroke_msg_t, buffer),
+       );
+       return msg;
+}
+
+#define push_string(msg, field, str) \
+       push_string_impl(msg, offsetof(stroke_msg_t, field), str)
+
+static void push_string_impl(stroke_msg_t **msg, size_t offset, char *string)
+{
+       size_t cur_len = (*msg)->length, str_len;
+
+       if (!string)
+       {
+               return;
+       }
+       str_len = strlen(string) + 1;
+       if (cur_len + str_len >= UINT16_MAX)
        {
-               return NULL;
+               (*msg)->length = UINT16_MAX;
+               return;
        }
-       else
+       while (cur_len + str_len > sizeof(stroke_msg_t) + (*msg)->buflen)
        {
-               msg->length += strlen(string) + 1;
-               strcpy((char*)msg + string_start, string);
-               return (char*)string_start;
+               *msg = realloc(*msg, sizeof(stroke_msg_t) + (*msg)->buflen +
+                                          STROKE_BUF_LEN_INC);
+               (*msg)->buflen += STROKE_BUF_LEN_INC;
        }
+       (*msg)->length += str_len;
+       strcpy((char*)*msg + cur_len, string);
+       *(char**)((char*)*msg + offset) = (char*)cur_len;
 }
 
-static int send_stroke_msg (stroke_msg_t *msg)
+static int send_stroke_msg(stroke_msg_t *msg)
 {
        stream_t *stream;
        char *uri, buffer[512], *pass;
        int count;
 
+       if (msg->length == UINT16_MAX)
+       {
+               fprintf(stderr, "stroke message exceeds maximum buffer size");
+               free(msg);
+               return -1;
+       }
+
        msg->output_verbosity = output_verbosity;
 
        uri = lib->settings->get_str(lib->settings, "%s.plugins.stroke.socket",
@@ -63,6 +93,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
        if (!stream)
        {
                fprintf(stderr, "failed to connect to stroke socket '%s'\n", uri);
+               free(msg);
                return -1;
        }
 
@@ -70,6 +101,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
        {
                fprintf(stderr, "sending stroke message failed\n");
                stream->destroy(stream);
+               free(msg);
                return -1;
        }
 
@@ -109,6 +141,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
                fprintf(stderr, "reading stroke response failed\n");
        }
        stream->destroy(stream);
+       free(msg);
        return 0;
 }
 
@@ -117,126 +150,116 @@ static int add_connection(char *name,
                                                  char *my_addr, char *other_addr,
                                                  char *my_nets, char *other_nets)
 {
-       stroke_msg_t msg;
-
-       memset(&msg, 0, sizeof(msg));
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.type = STR_ADD_CONN;
-
-       msg.add_conn.name = push_string(&msg, name);
-       msg.add_conn.version = 2;
-       msg.add_conn.mode = 1;
-       msg.add_conn.mobike = 1;
-       msg.add_conn.dpd.action = 1;
-       msg.add_conn.install_policy = 1;
-
-       msg.add_conn.me.id = push_string(&msg, my_id);
-       msg.add_conn.me.address = push_string(&msg, my_addr);
-       msg.add_conn.me.ikeport = 500;
-       msg.add_conn.me.subnets = push_string(&msg, my_nets);
-       msg.add_conn.me.sendcert = 1;
-       msg.add_conn.me.to_port = 65535;
-
-       msg.add_conn.other.id = push_string(&msg, other_id);
-       msg.add_conn.other.address = push_string(&msg, other_addr);
-       msg.add_conn.other.ikeport = 500;
-       msg.add_conn.other.subnets = push_string(&msg, other_nets);
-       msg.add_conn.other.sendcert = 1;
-       msg.add_conn.other.to_port = 65535;
-
-       return send_stroke_msg(&msg);
+       stroke_msg_t *msg;
+
+       msg = create_stroke_msg(STR_ADD_CONN);
+
+       push_string(&msg, add_conn.name, name);
+       msg->add_conn.version = 2;
+       msg->add_conn.mode = 1;
+       msg->add_conn.mobike = 1;
+       msg->add_conn.dpd.action = 1;
+       msg->add_conn.install_policy = 1;
+
+       push_string(&msg, add_conn.me.id, my_id);
+       push_string(&msg, add_conn.me.address, my_addr);
+       msg->add_conn.me.ikeport = 500;
+       push_string(&msg, add_conn.me.subnets, my_nets);
+       msg->add_conn.me.sendcert = 1;
+       msg->add_conn.me.to_port = 65535;
+
+       push_string(&msg, add_conn.other.id, other_id);
+       push_string(&msg, add_conn.other.address, other_addr);
+       msg->add_conn.other.ikeport = 500;
+       push_string(&msg, add_conn.other.subnets, other_nets);
+       msg->add_conn.other.sendcert = 1;
+       msg->add_conn.other.to_port = 65535;
+
+       return send_stroke_msg(msg);
 }
 
 static int del_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.type = STR_DEL_CONN;
-       msg.initiate.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_DEL_CONN);
+       push_string(&msg, initiate.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int initiate_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.type = STR_INITIATE;
-       msg.initiate.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_INITIATE);
+       push_string(&msg, initiate.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int terminate_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_TERMINATE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.initiate.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_TERMINATE);
+       push_string(&msg, initiate.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int terminate_connection_srcip(char *start, char *end)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_TERMINATE_SRCIP;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.terminate_srcip.start = push_string(&msg, start);
-       msg.terminate_srcip.end = push_string(&msg, end);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_TERMINATE_SRCIP);
+       push_string(&msg, terminate_srcip.start, start);
+       push_string(&msg, terminate_srcip.end, end);
+       return send_stroke_msg(msg);
 }
 
 static int rekey_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_REKEY;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.rekey.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_REKEY);
+       push_string(&msg, rekey.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int route_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_ROUTE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.route.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_ROUTE);
+       push_string(&msg, route.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int unroute_connection(char *name)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_UNROUTE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.unroute.name = push_string(&msg, name);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_UNROUTE);
+       push_string(&msg, unroute.name, name);
+       return send_stroke_msg(msg);
 }
 
 static int show_status(stroke_keyword_t kw, char *connection)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
        switch (kw)
        {
                case STROKE_STATUSALL:
-                       msg.type = STR_STATUS_ALL;
+                       msg = create_stroke_msg(STR_STATUS_ALL);
                        break;
                case STROKE_STATUSALL_NOBLK:
-                       msg.type = STR_STATUS_ALL_NOBLK;
+                       msg = create_stroke_msg(STR_STATUS_ALL_NOBLK);
                        break;
                default:
-                       msg.type = STR_STATUS;
+                       msg = create_stroke_msg(STR_STATUS);
                        break;
        }
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.status.name = push_string(&msg, connection);
-       return send_stroke_msg(&msg);
+       push_string(&msg, status.name, connection);
+       return send_stroke_msg(msg);
 }
 
 static int list_flags[] = {
@@ -257,13 +280,12 @@ static int list_flags[] = {
 
 static int list(stroke_keyword_t kw, int utc)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_LIST;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.list.utc = utc;
-       msg.list.flags = list_flags[kw - STROKE_LIST_FIRST];
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_LIST);
+       msg->list.utc = utc;
+       msg->list.flags = list_flags[kw - STROKE_LIST_FIRST];
+       return send_stroke_msg(msg);
 }
 
 static int reread_flags[] = {
@@ -278,12 +300,11 @@ static int reread_flags[] = {
 
 static int reread(stroke_keyword_t kw)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_REREAD;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.reread.flags = reread_flags[kw - STROKE_REREAD_FIRST];
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_REREAD);
+       msg->reread.flags = reread_flags[kw - STROKE_REREAD_FIRST];
+       return send_stroke_msg(msg);
 }
 
 static int purge_flags[] = {
@@ -295,12 +316,11 @@ static int purge_flags[] = {
 
 static int purge(stroke_keyword_t kw)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_PURGE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.purge.flags = purge_flags[kw - STROKE_PURGE_FIRST];
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_PURGE);
+       msg->purge.flags = purge_flags[kw - STROKE_PURGE_FIRST];
+       return send_stroke_msg(msg);
 }
 
 static int export_flags[] = {
@@ -311,68 +331,61 @@ static int export_flags[] = {
 
 static int export(stroke_keyword_t kw, char *selector)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_EXPORT;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.export.selector = push_string(&msg, selector);
-       msg.export.flags = export_flags[kw - STROKE_EXPORT_FIRST];
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_EXPORT);
+       push_string(&msg, export.selector, selector);
+       msg->export.flags = export_flags[kw - STROKE_EXPORT_FIRST];
+       return send_stroke_msg(msg);
 }
 
 static int leases(stroke_keyword_t kw, char *pool, char *address)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_LEASES;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.leases.pool = push_string(&msg, pool);
-       msg.leases.address = push_string(&msg, address);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_LEASES);
+       push_string(&msg, leases.pool, pool);
+       push_string(&msg, leases.address, address);
+       return send_stroke_msg(msg);
 }
 
 static int memusage()
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_MEMUSAGE;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_MEMUSAGE);
+       return send_stroke_msg(msg);
 }
 
 static int user_credentials(char *name, char *user, char *pass)
 {
-       stroke_msg_t msg;
-
-       msg.type = STR_USER_CREDS;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.user_creds.name = push_string(&msg, name);
-       msg.user_creds.username = push_string(&msg, user);
-       msg.user_creds.password = push_string(&msg, pass);
-       return send_stroke_msg(&msg);
+       stroke_msg_t *msg;
+
+       msg = create_stroke_msg(STR_USER_CREDS);
+       push_string(&msg, user_creds.name, name);
+       push_string(&msg, user_creds.username, user);
+       push_string(&msg, user_creds.password, pass);
+       return send_stroke_msg(msg);
 }
 
 static int counters(int reset, char *name)
 {
-       stroke_msg_t msg;
-
-       msg.type = STR_COUNTERS;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.counters.name = push_string(&msg, name);
-       msg.counters.reset = reset;
+       stroke_msg_t *msg;
 
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_COUNTERS);
+       push_string(&msg, counters.name, name);
+       msg->counters.reset = reset;
+       return send_stroke_msg(msg);
 }
 
 static int set_loglevel(char *type, u_int level)
 {
-       stroke_msg_t msg;
+       stroke_msg_t *msg;
 
-       msg.type = STR_LOGLEVEL;
-       msg.length = offsetof(stroke_msg_t, buffer);
-       msg.loglevel.type = push_string(&msg, type);
-       msg.loglevel.level = level;
-       return send_stroke_msg(&msg);
+       msg = create_stroke_msg(STR_LOGLEVEL);
+       push_string(&msg, loglevel.type, type);
+       msg->loglevel.level = level;
+       return send_stroke_msg(msg);
 }
 
 static int usage(char *error)
index c2b923f6db9a82e7dd17473b7e7ea024c8de87d6..17f8a4326f2ed9dc2c7f9e36742b4f1da9d163dd 100644 (file)
@@ -1,11 +1,5 @@
-/**
- * @file stroke_msg.h
- *
- * @brief Definition of stroke_msg_t.
- *
- */
-
 /*
+ * Copyright (C) 2015 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  */
 #define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl"
 
-#define STROKE_BUF_LEN         4096
+/**
+ * Number of bytes by which the buffer is increased as needed
+ */
+#define STROKE_BUF_LEN_INC     1024
 
 typedef enum list_flag_t list_flag_t;
 
@@ -371,7 +368,10 @@ struct stroke_msg_t {
                        char *name;
                } counters;
        };
-       char buffer[STROKE_BUF_LEN];
+       /* length of the string buffer */
+       u_int16_t buflen;
+       /* string buffer */
+       char buffer[];
 };
 
 #endif /* STROKE_MSG_H_ */