fixed logleve(l) keyword typo
[strongswan.git] / src / stroke / stroke.c
index b65a757..b8b0cc0 100644 (file)
 #include <stdio.h>
 #include <linux/stddef.h>
 
+#include <types.h>
+
 #include "stroke.h"
+#include "stroke_keywords.h"
 
-#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
+struct stroke_token {
+    char *name;
+    stroke_keyword_t kw;
+};
 
-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,116 +99,118 @@ 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.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.rekey.ipsec_lifetime = 0;
+       msg.add_conn.rekey.ike_lifetime = 0;
+       msg.add_conn.rekey.margin = 0;
+       msg.add_conn.rekey.tries = 0;
+       msg.add_conn.rekey.fuzz = 0;
        
-       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.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.ca = NULL;
+       msg.add_conn.me.sendcert = CERT_SEND_IF_ASKED;
        
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       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.ca = NULL;
+       msg.add_conn.other.sendcert = CERT_SEND_IF_ASKED;
+       
+       return send_stroke_msg(&msg);
+}
+
+static int del_connection(char *name)
+{
+       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);
 }
 
 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)
+static int show_status(stroke_keyword_t kw, 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;
-       }
-       else
-       {
-               msg->type = STR_STATUS;
-       }
-       msg->status.name = push_string(&msg, connection);
-       res = send_stroke_msg(msg);
-       free(msg);
-       return res;
+       msg.type = (kw == STROKE_STATUS)? STR_STATUS:STR_STATUS_ALL;
+       msg.length = offsetof(stroke_msg_t, buffer);
+       msg.status.name = push_string(&msg, connection);
+       return send_stroke_msg(&msg);
 }
 
-static int list_certs(void)
+static int list_flags[] = {
+       LIST_CERTS,
+       LIST_CACERTS,
+       LIST_CRLS,
+       LIST_ALL
+};
+
+static int list(stroke_keyword_t kw, bool utc)
 {
-       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;
+       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);
 }
 
 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)
@@ -228,6 +232,9 @@ static void exit_usage(char *error)
        printf("           ADDR is a IPv4 address\n");
        printf("           NET is a IPv4 address of the subnet to tunnel\n");
        printf("           NETBITS is the size of the subnet, as the \"24\" in 192.168.0.0/24\n");
+       printf("  Delete a connection:\n");
+       printf("    stroke delete NAME\n");
+       printf("    where: NAME is a connection name added with \"stroke add\"\n");
        printf("  Initiate a connection:\n");
        printf("    stroke up NAME\n");
        printf("    where: NAME is a connection name added with \"stroke add\"\n");
@@ -254,72 +261,82 @@ static void exit_usage(char *error)
 
 int main(int argc, char *argv[])
 {
+       const stroke_token_t *token;
        int res = 0;
-       char *op;
-       
+
        if (argc < 2)
        {
                exit_usage(NULL);
        }
        
-       op = argv[1];
+       token = in_word_set(argv[1], strlen(argv[1]));
 
-       if (streq(op, "status") || streq(op, "statusall"))
-       {
-               res = show_status(op, argc > 2 ? argv[2] : NULL);
-       }
-       else if (streq(op, "listcerts") || streq(op, "listall"))
-       {
-               res = list_certs();
-       }
-       else if (streq(op, "up"))
-       {
-               if (argc < 3)
-               {
-                       exit_usage("\"up\" needs a connection name");
-               }
-               res = initiate_connection(argv[2]);
-       }
-       else if (streq(op, "down"))
-       {
-               if (argc < 3)
-               {
-                       exit_usage("\"down\" needs a connection name");
-               }
-               res = terminate_connection(argv[2]);
-       }
-       else if (streq(op, "add"))
+       if (token == NULL)
        {
-               if (argc < 11)
-               {
-                       exit_usage("\"add\" needs more parameters...");
-               }
-               res = add_connection(argv[2],
-                                                        argv[3], argv[4], 
-                                                        argv[5], argv[6], 
-                                                        argv[7], argv[8], 
-                                                        atoi(argv[9]), atoi(argv[10]));
+               exit_usage("unknown keyword");
        }
-       else if (streq(op, "logtype"))
-       {
-               if (argc < 5)
-               {
-                       exit_usage("\"logtype\" needs more parameters...");
-               }
-               res = set_logtype(argv[2], argv[3], atoi(argv[4])); 
-       }
-       else if (streq(op, "loglevel"))
-       {
-               if (argc < 4)
-               {
-                       exit_usage("\"logtype\" needs more parameters...");
-               }
-               res = set_loglevel(argv[2], atoi(argv[3])); 
-       }
-       else
+
+       switch (token->kw)
        {
-               exit_usage(NULL);
+               case STROKE_ADD:
+                       if (argc < 11)
+                       {
+                               exit_usage("\"add\" needs more parameters...");
+                       }
+                       res = add_connection(argv[2],
+                                                                argv[3], argv[4], 
+                                                                argv[5], argv[6], 
+                                                                argv[7], argv[8], 
+                                                                atoi(argv[9]), atoi(argv[10]));
+                       break;
+               case STROKE_DELETE:
+               case STROKE_DEL:
+                       if (argc < 3)
+                       {
+                               exit_usage("\"delete\" needs a connection name");
+                       }
+                       res = del_connection(argv[2]);
+                       break;
+               case STROKE_UP:
+                       if (argc < 3)
+                       {
+                               exit_usage("\"up\" needs a connection name");
+                       }
+                       res = initiate_connection(argv[2]);
+                       break;
+               case STROKE_DOWN:
+                       if (argc < 3)
+                       {
+                               exit_usage("\"down\" needs a connection name");
+                       }
+                       res = terminate_connection(argv[2]);
+                       break;
+               case STROKE_LOGTYPE:
+                       if (argc < 5)
+                       {
+                               exit_usage("\"logtype\" needs more parameters...");
+                       }
+                       res = set_logtype(argv[2], argv[3], atoi(argv[4])); 
+                       break;
+               case STROKE_LOGLEVEL:
+                       if (argc < 4)
+                       {
+                               exit_usage("\"logtype\" needs more parameters...");
+                       }
+                       res = set_loglevel(argv[2], atoi(argv[3])); 
+                       break;
+               case STROKE_STATUS:
+               case STROKE_STATUSALL:
+                       res = show_status(token->kw, argc > 2 ? argv[2] : NULL);
+                       break;
+               case STROKE_LIST_CERTS:
+               case STROKE_LIST_CACERTS:
+               case STROKE_LIST_CRLS:
+               case STROKE_LIST_ALL:
+                       res = list(token->kw, argc > 2 && streq(argv[2], "--utc"));
+                       break;
+               default:
+                       exit_usage(NULL);
        }
-       
        return res;
 }