stroke now uses constant size string buffer
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 29 May 2006 07:14:57 +0000 (07:14 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 29 May 2006 07:14:57 +0000 (07:14 -0000)
src/charon/threads/stroke_interface.c
src/starter/starterstroke.c
src/stroke/stroke.c
src/stroke/stroke.h

index b8e5ba9..9110f5c 100755 (executable)
@@ -92,17 +92,16 @@ struct private_stroke_t {
  */
 static void pop_string(stroke_msg_t *msg, char **string)
 {
-       /* check for sanity of string pointer and string */
        if (*string == NULL)
+               return;
+
+       /* check for sanity of string pointer and string */
+       if (string < (char**)msg
+       ||      string > (char**)msg + sizeof(stroke_msg_t)
+       || (u_int)*string < (u_int)((char*)msg->buffer - (char*)msg)
+       || (u_int)*string > msg->length)
        {
-               *string = "";
-       }
-       else if (string < (char**)msg ||
-               string > (char**)msg + sizeof(stroke_msg_t) ||
-               *string < (char*)msg->buffer - (u_int)msg ||
-               *string > (char*)(u_int)msg->length)
-       {
-               *string = "(invalid char* in stroke msg)";
+               *string = "(invalid pointer in stroke msg)";
        }
        else
        {
@@ -136,7 +135,7 @@ static void load_end_certificate(const char *filename, identification_t **idp)
                identification_t *id = *idp;
                identification_t *subject = cert->get_subject(cert);
 
-               if (!id->equals(id, subject))
+               if (!id->equals(id, subject) && !cert->equals_subjectAltName(cert, id))
                {
                        id->destroy(id);
                        id = subject;
@@ -170,21 +169,25 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                                
        this->logger->log(this->logger, CONTROL, "received stroke: add connection \"%s\"", msg->add_conn.name);
                                
-       my_host = host_create(AF_INET, msg->add_conn.me.address, IKE_PORT);
+       my_host = msg->add_conn.me.address?
+                         host_create(AF_INET, msg->add_conn.me.address, IKE_PORT) : NULL;
        if (my_host == NULL)
        {
                this->stroke_logger->log(this->stroke_logger, ERROR, "invalid host: %s", msg->add_conn.me.address);
                return;
        }
-       other_host = host_create(AF_INET, msg->add_conn.other.address, IKE_PORT);
+
+       other_host = msg->add_conn.other.address ?
+                                host_create(AF_INET, msg->add_conn.other.address, IKE_PORT) : NULL;
        if (other_host == NULL)
        {
                this->stroke_logger->log(this->stroke_logger, ERROR, "invalid host: %s", msg->add_conn.other.address);
                my_host->destroy(my_host);
                return;
        }
-       my_id = identification_create_from_string(*msg->add_conn.me.id ? 
-                                                                                          msg->add_conn.me.id : msg->add_conn.me.address);
+
+       my_id = identification_create_from_string(msg->add_conn.me.id ?
+                                                                                         msg->add_conn.me.id : msg->add_conn.me.address);
        if (my_id == NULL)
        {
                this->stroke_logger->log(this->stroke_logger, ERROR, "invalid id: %s", msg->add_conn.me.id);
@@ -192,8 +195,9 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                other_host->destroy(other_host);
                return;
        }
-       other_id = identification_create_from_string(*msg->add_conn.other.id ? 
-                                                                                                 msg->add_conn.other.id : msg->add_conn.other.address);
+
+       other_id = identification_create_from_string(msg->add_conn.other.id ?
+                                                                                                msg->add_conn.other.id : msg->add_conn.other.address);
        if (other_id == NULL)
        {
                my_host->destroy(my_host);
@@ -203,7 +207,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                return;
        }
        
-       my_subnet = host_create(AF_INET, *msg->add_conn.me.subnet ? msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
+       my_subnet = host_create(AF_INET, msg->add_conn.me.subnet ?
+                                                                        msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
        if (my_subnet == NULL)
        {
                my_host->destroy(my_host);
@@ -214,7 +219,8 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                return;
        }
        
-       other_subnet = host_create(AF_INET, *msg->add_conn.other.subnet ? msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
+       other_subnet = host_create(AF_INET, msg->add_conn.other.subnet ?
+                                                                               msg->add_conn.other.subnet : msg->add_conn.other.address, IKE_PORT);
        if (other_subnet == NULL)
        {
                my_host->destroy(my_host);
@@ -226,27 +232,37 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
                return;
        }
                                
-       my_ts = traffic_selector_create_from_subnet(my_subnet, *msg->add_conn.me.subnet ? msg->add_conn.me.subnet_mask : 32);
+       my_ts = traffic_selector_create_from_subnet(my_subnet, msg->add_conn.me.subnet ?
+                                                                                                                  msg->add_conn.me.subnet_mask : 32);
        my_subnet->destroy(my_subnet);
-       other_ts = traffic_selector_create_from_subnet(other_subnet, *msg->add_conn.other.subnet ? msg->add_conn.other.subnet_mask : 32);
+
+       other_ts = traffic_selector_create_from_subnet(other_subnet, msg->add_conn.other.subnet ?
+                                                                                                                                msg->add_conn.other.subnet_mask : 32);
        other_subnet->destroy(other_subnet);
                                
        if (charon->socket->is_listening_on(charon->socket, other_host))
        {
                this->stroke_logger->log(this->stroke_logger, CONTROL|LEVEL1, "left is other host, switching");
                
-               host_t *tmp_host = my_host;
-               identification_t *tmp_id = my_id;
-               traffic_selector_t *tmp_ts = my_ts;
-               char *tmp_cert = msg->add_conn.me.cert;
+               host_t *tmp_host;
+               identification_t *tmp_id;
+               traffic_selector_t *tmp_ts;
+               char *tmp_cert;
                
-               my_host = other_host;
+               tmp_host   = my_host;
+               my_host    = other_host;
                other_host = tmp_host;
-               my_id = other_id;
+
+               tmp_id   = my_id;
+               my_id    = other_id;
                other_id = tmp_id;
-               my_ts = other_ts;
+
+               tmp_ts   = my_ts;
+               my_ts    = other_ts;
                other_ts = tmp_ts;
-               msg->add_conn.me.cert = msg->add_conn.other.cert;
+
+        tmp_cert                 = msg->add_conn.me.cert;
+               msg->add_conn.me.cert    = msg->add_conn.other.cert;
                msg->add_conn.other.cert = tmp_cert;
        }
        else if (charon->socket->is_listening_on(charon->socket, my_host))
index e480227..c20e7f6 100644 (file)
 #include "confread.h"
 #include "files.h"
 
-static char* 
-push_string(stroke_msg_t **strm, char *string)
+static char* push_string(stroke_msg_t *msg, char *string)
 {
-    stroke_msg_t *stroke_msg;
-    size_t string_length;
-
-    if (string == NULL)
-    {
-       return NULL;
-    }
-    stroke_msg = *strm;
-    string_length = strlen(string) + 1;
-    stroke_msg->length += string_length;
-
-    stroke_msg = realloc(stroke_msg, stroke_msg->length);
-    strcpy((char*)stroke_msg + stroke_msg->length - string_length, string);
-
-    *strm = stroke_msg;
-    return (char*)(u_int)stroke_msg->length - string_length;
+       u_int string_start = msg->length;
+
+       if (string == NULL || msg->length + strlen(string) >= sizeof(stroke_msg_t))
+       {
+               return NULL;
+       }
+       else
+       {
+               msg->length += strlen(string) + 1;
+               strcpy((char*)msg + string_start, string);
+               return (char*)string_start;
+       }
 }
 
-static int
-send_stroke_msg (stroke_msg_t *msg)
+static int send_stroke_msg (stroke_msg_t *msg)
 {
-    struct sockaddr_un ctl_addr = { AF_UNIX, CHARON_CTL_FILE };
-    int sock;
-    int byte_count;
-    char buffer[64];
-
-    sock = socket(AF_UNIX, SOCK_STREAM, 0);
-    if (sock < 0)
-    {
-       plog("socket() failed: %s", strerror(errno));
-       return -1;
-    }
-    if (connect(sock, (struct sockaddr *)&ctl_addr, 
-       offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
-    {
-       plog("connect(charon_ctl) failed: %s", strerror(errno));
-       close(sock);
-       return -1;
-    }
+       struct sockaddr_un ctl_addr = { AF_UNIX, CHARON_CTL_FILE };
+       int byte_count;
+       char buffer[64];
+
+       int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+       if (sock < 0)
+       {
+               plog("socket() failed: %s", strerror(errno));
+               return -1;
+       }
+       if (connect(sock, (struct sockaddr *)&ctl_addr, offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
+       {
+               plog("connect(charon_ctl) failed: %s", strerror(errno));
+               close(sock);
+               return -1;
+       }
+
+       /* send message */
+       if (write(sock, msg, msg->length) != msg->length)
+       {
+               plog("write(charon_ctl) failed: %s", strerror(errno));
+               close(sock);
+               return -1;
+       }
+       while ((byte_count = read(sock, buffer, sizeof(buffer)-1)) > 0)
+       {
+               buffer[byte_count] = '\0';
+               plog("%s", buffer);
+       }
+       if (byte_count < 0)
+       {
+               plog("read() failed: %s", strerror(errno));
+       }
 
-    /* send message */
-    if (write(sock, msg, msg->length) != msg->length)
-    {
-       plog("write(charon_ctl) failed: %s", strerror(errno));
        close(sock);
-       return -1;
-    }
-    while ((byte_count = read(sock, buffer, sizeof(buffer)-1)) > 0)
-    {
-       buffer[byte_count] = '\0';
-       plog("%s", buffer);
-    }
-    if (byte_count < 0)
-    {
-       plog("read() failed: %s", strerror(errno));
-    }
-
-    close(sock);
-    return 0;
+       return 0;
 }
 
-static char*
-connection_name(starter_conn_t *conn)
+static char* connection_name(starter_conn_t *conn)
 {
-    /* if connection name is '%auto', create a new name like conn_xxxxx */
-    static char buf[32];
-
-    if (streq(conn->name, "%auto"))
-    {
-       sprintf(buf, "conn_%ld", conn->id);
-       return buf;
-    }
-    return conn->name;
+        /* if connection name is '%auto', create a new name like conn_xxxxx */
+       static char buf[32];
+
+       if (streq(conn->name, "%auto"))
+       {
+               sprintf(buf, "conn_%ld", conn->id);
+               return buf;
+       }
+       return conn->name;
 }
 
-
-int 
-starter_stroke_add_conn(starter_conn_t *conn)
+int starter_stroke_add_conn(starter_conn_t *conn)
 {
-    stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-    int res;
-
-    msg->length = sizeof(stroke_msg_t);
-    msg->type = STR_ADD_CONN;
-
-    msg->add_conn.name = push_string(&msg, connection_name(conn));
-       msg->add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2 ? 1 : 0;
-
-    msg->add_conn.me.id = push_string(&msg, conn->left.id);
-    msg->add_conn.me.cert = push_string(&msg, conn->left.cert);
-    msg->add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr));
-    msg->add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr));
-    msg->add_conn.me.subnet_mask = conn->left.subnet.maskbits;
-
-    msg->add_conn.other.id = push_string(&msg, conn->right.id);
-    msg->add_conn.other.cert = push_string(&msg, conn->right.cert);
-    msg->add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr));
-    msg->add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr));
-    msg->add_conn.other.subnet_mask = conn->right.subnet.maskbits;
-
-    res = send_stroke_msg(msg);
-    free(msg);
-    return res;
+       stroke_msg_t msg;
+
+       msg.type = STR_ADD_CONN;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2;
+       msg.add_conn.name = push_string(&msg, connection_name(conn));
+
+       msg.add_conn.me.id = push_string(&msg, conn->left.id);
+       msg.add_conn.me.cert = push_string(&msg, conn->left.cert);
+       msg.add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr));
+       msg.add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr));
+       msg.add_conn.me.subnet_mask = conn->left.subnet.maskbits;
+
+       msg.add_conn.other.id = push_string(&msg, conn->right.id);
+       msg.add_conn.other.cert = push_string(&msg, conn->right.cert);
+       msg.add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr));
+       msg.add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr));
+       msg.add_conn.other.subnet_mask = conn->right.subnet.maskbits;
+
+       return send_stroke_msg(&msg);
 }
 
-int 
-starter_stroke_del_conn(starter_conn_t *conn)
+int starter_stroke_del_conn(starter_conn_t *conn)
 {
     return 0;
 }
 
-int 
-starter_stroke_route_conn(starter_conn_t *conn)
+int starter_stroke_route_conn(starter_conn_t *conn)
 {
-    stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-    int res;
-
-    msg->length = sizeof(stroke_msg_t);
-    msg->type = STR_INSTALL;
-    msg->install.name = push_string(&msg, connection_name(conn));
-    res = send_stroke_msg(msg);
-    free(msg);
-    return res;
+       stroke_msg_t msg;
+
+       msg.type = STR_INSTALL;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.install.name = push_string(&msg, connection_name(conn));
+       return send_stroke_msg(&msg);
 }
 
-int 
-starter_stroke_initiate_conn(starter_conn_t *conn)
+int starter_stroke_initiate_conn(starter_conn_t *conn)
 {
-    stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-    int res;
-
-    msg->length = sizeof(stroke_msg_t);
-    msg->type = STR_INITIATE;
-    msg->initiate.name = push_string(&msg, connection_name(conn));
-    res = send_stroke_msg(msg);
-    free(msg);
-    return res;
+       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);
 }
index c844c6a..d104f8d 100644 (file)
 
 #define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
 
-static char* push_string(stroke_msg_t **strm, char *string)
+static char* push_string(stroke_msg_t *msg, char *string)
 {
-       stroke_msg_t *stroke_msg;
-       size_t string_length;
-       
-       if (string == NULL)
+       u_int string_start = msg->length;
+
+       if (string == NULL ||  msg->length + strlen(string) >= sizeof(stroke_msg_t))
        {
                return NULL;
        }
-       stroke_msg = *strm;
-       string_length = strlen(string) + 1;
-       stroke_msg->length += string_length;
-       
-       stroke_msg = realloc(stroke_msg, stroke_msg->length);
-       strcpy((char*)stroke_msg + stroke_msg->length - string_length, string);
-       
-       *strm = stroke_msg;
-       return (char*)(u_int)stroke_msg->length - string_length;
+       else
+       {
+               msg->length += strlen(string) + 1;
+               strcpy((char*)msg + string_start, string);
+               return (char*)string_start;
+       }
 }
 
 static int send_stroke_msg (stroke_msg_t *msg)
@@ -97,117 +93,93 @@ static int add_connection(char *name,
                                                  char *my_net, char *other_net,
                                                  u_int my_netmask, u_int other_netmask)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_ADD_CONN;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.type = STR_ADD_CONN;
        
-       msg->add_conn.name = push_string(&msg, name);
-       msg->add_conn.ikev2 = 1;
+       msg.add_conn.name = push_string(&msg, name);
+       msg.add_conn.ikev2 = 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.subnet = push_string(&msg, my_net);
-       msg->add_conn.me.subnet_mask = my_netmask;
-       msg->add_conn.me.cert = NULL;
+       msg.add_conn.me.id = push_string(&msg, my_id);
+       msg.add_conn.me.address = push_string(&msg, my_addr);
+       msg.add_conn.me.subnet = push_string(&msg, my_net);
+       msg.add_conn.me.subnet_mask = my_netmask;
+       msg.add_conn.me.cert = NULL;
        
-       msg->add_conn.other.id = push_string(&msg, other_id);
-       msg->add_conn.other.address = push_string(&msg, other_addr);
-       msg->add_conn.other.subnet = push_string(&msg, other_net);
-       msg->add_conn.other.subnet_mask = other_netmask;
-       msg->add_conn.other.cert = NULL;
+       msg.add_conn.other.id = push_string(&msg, other_id);
+       msg.add_conn.other.address = push_string(&msg, other_addr);
+       msg.add_conn.other.subnet = push_string(&msg, other_net);
+       msg.add_conn.other.subnet_mask = other_netmask;
+       msg.add_conn.other.cert = NULL;
        
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       return send_stroke_msg(&msg);
 }
 
 static int initiate_connection(char *name)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_INITIATE;
-       msg->initiate.name = push_string(&msg, name);
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.type = STR_INITIATE;
+       msg.initiate.name = push_string(&msg, name);
+       return send_stroke_msg(&msg);
 }
 
 static int terminate_connection(char *name)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_TERMINATE;
-       msg->initiate.name = push_string(&msg, name);
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.type = STR_TERMINATE;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.initiate.name = push_string(&msg, name);
+       return send_stroke_msg(&msg);
 }
 
 static int show_status(char *mode, char *connection)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
        if (strcmp(mode, "statusall") == 0)
-       {
-               msg->type = STR_STATUS_ALL;
-       }
+               msg.type = STR_STATUS_ALL;
        else
-       {
-               msg->type = STR_STATUS;
-       }
-       msg->status.name = push_string(&msg, connection);
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+               msg.type = STR_STATUS;
+
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.status.name = push_string(&msg, connection);
+       return send_stroke_msg(&msg);
 }
 
 static int list_certs(void)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_LIST_CERTS;
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.type = STR_LIST_CERTS;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       return send_stroke_msg(&msg);
 }
 
 static int set_logtype(char *context, char *type, int enable)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_LOGTYPE;
-       msg->logtype.context = push_string(&msg, context);
-       msg->logtype.type = push_string(&msg, type);
-       msg->logtype.enable = enable;
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.type = STR_LOGTYPE;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.logtype.context = push_string(&msg, context);
+       msg.logtype.type = push_string(&msg, type);
+       msg.logtype.enable = enable;
+       return send_stroke_msg(&msg);
 }
 
 static int set_loglevel(char *context, u_int level)
 {
-       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
-       int res;
+       stroke_msg_t msg;
        
-       msg->length = sizeof(stroke_msg_t);
-       msg->type = STR_LOGLEVEL;
-       msg->loglevel.context = push_string(&msg, context);
-       msg->loglevel.level = level;
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.type = STR_LOGLEVEL;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.loglevel.context = push_string(&msg, context);
+       msg.loglevel.level = level;
+       return send_stroke_msg(&msg);
 }
 
 static void exit_error(char *error)
index 7e45b3c..f860b36 100644 (file)
@@ -28,6 +28,7 @@
  */
 #define STROKE_SOCKET "/var/run/charon.ctl"
 
+#define STROKE_BUF_LEN         2048
 
 typedef struct stroke_msg_t stroke_msg_t;
 
@@ -36,7 +37,7 @@ typedef struct stroke_msg_t stroke_msg_t;
  */
 struct stroke_msg_t {
        /* length of this message with all strings */
-       u_int16_t length;
+       u_int length;
 
        /* type of the message */
        enum {
@@ -68,6 +69,7 @@ struct stroke_msg_t {
                struct {
                        char *name;
                } initiate, install, terminate, status;
+
                /* data for STR_ADD_CONN */
                struct {
                        char *name;
@@ -81,17 +83,19 @@ struct stroke_msg_t {
                                int subnet_mask;
                        } me, other;
                } add_conn;
+
                struct {
                        char *context;
                        char *type;
                        int enable;
                } logtype;
+
                struct {
                        char *context;
                        int level;
                } loglevel;
        };
-       u_int8_t buffer[];
+       char buffer[STROKE_BUF_LEN];
 };
 
 #endif /* STROKE_H_ */