Fixed compiler warning.
[strongswan.git] / src / stroke / stroke.c
index c8ec9c7..1cb8cc2 100644 (file)
@@ -1,5 +1,7 @@
 /* Stroke for charon is the counterpart to whack from pluto
 /* Stroke for charon is the counterpart to whack from pluto
- * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2006 Martin Willi
+ * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
 #include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
 #include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
-#include <linux/stddef.h>
+#include <stddef.h>
+#include <string.h>
 
 
-#include <types.h>
-
-#include "stroke.h"
+#include "stroke_msg.h"
 #include "stroke_keywords.h"
 
 struct stroke_token {
 #include "stroke_keywords.h"
 
 struct stroke_token {
@@ -36,7 +37,7 @@ struct stroke_token {
 
 static char* push_string(stroke_msg_t *msg, char *string)
 {
 
 static char* push_string(stroke_msg_t *msg, char *string)
 {
-       u_int string_start = msg->length;
+       unsigned long string_start = msg->length;
 
        if (string == NULL ||  msg->length + strlen(string) >= sizeof(stroke_msg_t))
        {
 
        if (string == NULL ||  msg->length + strlen(string) >= sizeof(stroke_msg_t))
        {
@@ -52,11 +53,16 @@ static char* push_string(stroke_msg_t *msg, char *string)
 
 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, STROKE_SOCKET };
+       struct sockaddr_un ctl_addr;
        int sock;
        int sock;
-       char buffer[64];
+       char buffer[512];
        int byte_count;
        int byte_count;
-       
+
+       ctl_addr.sun_family = AF_UNIX;
+       strcpy(ctl_addr.sun_path, STROKE_SOCKET);
+
+       msg->output_verbosity = 1; /* CONTROL */
+
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock < 0)
        {
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock < 0)
        {
@@ -70,7 +76,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
                close(sock);
                return -1;
        }
                close(sock);
                return -1;
        }
-       
+
        /* send message */
        if (write(sock, msg, msg->length) != msg->length)
        {
        /* send message */
        if (write(sock, msg, msg->length) != msg->length)
        {
@@ -78,67 +84,68 @@ static int send_stroke_msg (stroke_msg_t *msg)
                close(sock);
                return -1;
        }
                close(sock);
                return -1;
        }
-       
+
        while ((byte_count = read(sock, buffer, sizeof(buffer)-1)) > 0)
        {
                buffer[byte_count] = '\0';
                printf("%s", buffer);
        while ((byte_count = read(sock, buffer, sizeof(buffer)-1)) > 0)
        {
                buffer[byte_count] = '\0';
                printf("%s", buffer);
+
+               /* we prompt if we receive the "Passphrase:" magic keyword */
+               if (byte_count >= 12 &&
+                       strcmp(buffer + byte_count - 12, "Passphrase:\n") == 0)
+               {
+                       if (fgets(buffer, sizeof(buffer), stdin))
+                       {
+                               ignore_result(write(sock, buffer, strlen(buffer)));
+                       }
+               }
        }
        if (byte_count < 0)
        {
                fprintf(stderr, "reading from socket failed: %s\n", strerror(errno));
        }
        }
        if (byte_count < 0)
        {
                fprintf(stderr, "reading from socket failed: %s\n", strerror(errno));
        }
-       
+
        close(sock);
        return 0;
 }
 
 static int add_connection(char *name,
        close(sock);
        return 0;
 }
 
 static int add_connection(char *name,
-                                                 char *my_id, char *other_id, 
+                                                 char *my_id, char *other_id,
                                                  char *my_addr, char *other_addr,
                                                  char *my_addr, char *other_addr,
-                                                 char *my_net, char *other_net,
-                                                 u_int my_netmask, u_int other_netmask)
+                                                 char *my_nets, char *other_nets)
 {
        stroke_msg_t msg;
 {
        stroke_msg_t msg;
-       
+
+       memset(&msg, 0, sizeof(msg));
        msg.length = offsetof(stroke_msg_t, buffer);
        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.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.algorithms.ike = NULL;
-       msg.add_conn.algorithms.esp = NULL;
-       
+       msg.add_conn.auth_method = 2;
+       msg.add_conn.mode = 1;
+       msg.add_conn.mobike = 1;
+       msg.add_conn.dpd.action = 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.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.ikeport = 500;
+       msg.add_conn.me.subnets = push_string(&msg, my_nets);
        msg.add_conn.me.sendcert = 1;
        msg.add_conn.me.sendcert = 1;
-       
+
        msg.add_conn.other.id = push_string(&msg, other_id);
        msg.add_conn.other.address = push_string(&msg, other_addr);
        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.ikeport = 500;
+       msg.add_conn.other.subnets = push_string(&msg, other_nets);
        msg.add_conn.other.sendcert = 1;
        msg.add_conn.other.sendcert = 1;
-       
+
        return send_stroke_msg(&msg);
 }
 
 static int del_connection(char *name)
 {
        stroke_msg_t msg;
        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);
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.type = STR_DEL_CONN;
        msg.initiate.name = push_string(&msg, name);
@@ -148,7 +155,7 @@ static int del_connection(char *name)
 static int initiate_connection(char *name)
 {
        stroke_msg_t msg;
 static int initiate_connection(char *name)
 {
        stroke_msg_t msg;
-       
+
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.type = STR_INITIATE;
        msg.initiate.name = push_string(&msg, name);
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.type = STR_INITIATE;
        msg.initiate.name = push_string(&msg, name);
@@ -158,17 +165,48 @@ static int initiate_connection(char *name)
 static int terminate_connection(char *name)
 {
        stroke_msg_t msg;
 static int terminate_connection(char *name)
 {
        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.type = STR_TERMINATE;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.initiate.name = push_string(&msg, name);
        return send_stroke_msg(&msg);
 }
 
+static int terminate_connection_srcip(char *start, char *end)
+{
+       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);
+}
+
+static int route_connection(char *name)
+{
+       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);
+}
+
+static int unroute_connection(char *name)
+{
+       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);
+}
+
 static int show_status(stroke_keyword_t kw, char *connection)
 {
        stroke_msg_t msg;
 static int show_status(stroke_keyword_t kw, char *connection)
 {
        stroke_msg_t msg;
-       
+
        msg.type = (kw == STROKE_STATUS)? STR_STATUS:STR_STATUS_ALL;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.status.name = push_string(&msg, connection);
        msg.type = (kw == STROKE_STATUS)? STR_STATUS:STR_STATUS_ALL;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.status.name = push_string(&msg, connection);
@@ -176,16 +214,24 @@ static int show_status(stroke_keyword_t kw, char *connection)
 }
 
 static int list_flags[] = {
 }
 
 static int list_flags[] = {
+       LIST_PUBKEYS,
        LIST_CERTS,
        LIST_CACERTS,
        LIST_CERTS,
        LIST_CACERTS,
+       LIST_OCSPCERTS,
+       LIST_AACERTS,
+       LIST_ACERTS,
+       LIST_GROUPS,
+       LIST_CAINFOS,
        LIST_CRLS,
        LIST_CRLS,
+       LIST_OCSP,
+       LIST_ALGS,
        LIST_ALL
 };
 
        LIST_ALL
 };
 
-static int list(stroke_keyword_t kw, bool utc)
+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.type = STR_LIST;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.list.utc = utc;
@@ -194,7 +240,11 @@ static int list(stroke_keyword_t kw, bool utc)
 }
 
 static int reread_flags[] = {
 }
 
 static int reread_flags[] = {
+       REREAD_SECRETS,
        REREAD_CACERTS,
        REREAD_CACERTS,
+       REREAD_OCSPCERTS,
+       REREAD_AACERTS,
+       REREAD_ACERTS,
        REREAD_CRLS,
        REREAD_ALL
 };
        REREAD_CRLS,
        REREAD_ALL
 };
@@ -202,32 +252,47 @@ static int reread_flags[] = {
 static int reread(stroke_keyword_t kw)
 {
        stroke_msg_t msg;
 static int reread(stroke_keyword_t kw)
 {
        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.type = STR_REREAD;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.reread.flags = reread_flags[kw - STROKE_REREAD_FIRST];
        return send_stroke_msg(&msg);
 }
 
-static int set_logtype(char *context, char *type, int enable)
+static int purge_flags[] = {
+       PURGE_OCSP,
+       PURGE_IKE,
+};
+
+static int purge(stroke_keyword_t kw)
 {
        stroke_msg_t msg;
 {
        stroke_msg_t msg;
-       
-       msg.type = STR_LOGTYPE;
+
+       msg.type = STR_PURGE;
        msg.length = offsetof(stroke_msg_t, buffer);
        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;
+       msg.purge.flags = purge_flags[kw - STROKE_PURGE_FIRST];
        return send_stroke_msg(&msg);
 }
 
        return send_stroke_msg(&msg);
 }
 
-static int set_loglevel(char *context, u_int level)
+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);
+}
+
+static int set_loglevel(char *type, u_int level)
+{
+       stroke_msg_t msg;
+
        msg.type = STR_LOGLEVEL;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.type = STR_LOGLEVEL;
        msg.length = offsetof(stroke_msg_t, buffer);
-       msg.loglevel.context = push_string(&msg, context);
+       msg.loglevel.type = push_string(&msg, type);
        msg.loglevel.level = level;
        return send_stroke_msg(&msg);
 }
        msg.loglevel.level = level;
        return send_stroke_msg(&msg);
 }
@@ -249,8 +314,7 @@ static void exit_usage(char *error)
        printf("           MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
        printf("    where: ID is any IKEv2 ID \n");
        printf("           ADDR is a IPv4 address\n");
        printf("           MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
        printf("    where: ID is any IKEv2 ID \n");
        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("           NET is a IPv4 subnet in CIDR notation\n");
        printf("  Delete a connection:\n");
        printf("    stroke delete NAME\n");
        printf("    where: NAME is a connection name added with \"stroke add\"\n");
        printf("  Delete a connection:\n");
        printf("    stroke delete NAME\n");
        printf("    where: NAME is a connection name added with \"stroke add\"\n");
@@ -260,23 +324,31 @@ static void exit_usage(char *error)
        printf("  Terminate a connection:\n");
        printf("    stroke down NAME\n");
        printf("    where: NAME is a connection name added with \"stroke add\"\n");
        printf("  Terminate a connection:\n");
        printf("    stroke down NAME\n");
        printf("    where: NAME is a connection name added with \"stroke add\"\n");
-       printf("  Set logtype for a logging context:\n");
-       printf("    stroke logtype CONTEXT TYPE ENABLE\n");
-       printf("    where: CONTEXT is PARSR|GNRAT|IKESA|SAMGR|CHDSA|MESSG|TPOOL|WORKR|SCHED|\n");
-       printf("                      SENDR|RECVR|SOCKT|TESTR|DAEMN|CONFG|ENCPL|PAYLD\n");
-       printf("           TYPE is CONTROL|ERROR|AUDIT|RAW|PRIVATE\n");
-       printf("           ENABLE is 0|1\n");
-       printf("  Set loglevel for a logging context:\n");
-       printf("    stroke loglevel CONTEXT LEVEL\n");
-       printf("    where: CONTEXT is PARSR|GNRAT|IKESA|SAMGR|CHDSA|MESSG|TPOOL|WORKR|SCHED|\n");
-       printf("                      SENDR|RECVR|SOCKT|TESTR|DAEMN|CONFG|ENCPL|PAYLD\n");
-       printf("           LEVEL is 0|1|2|3\n");
+       printf("  Terminate a connection by remote srcip:\n");
+       printf("    stroke down-srcip START [END]\n");
+       printf("    where: START and optional END define the clients source IP\n");
+       printf("  Set loglevel for a logging type:\n");
+       printf("    stroke loglevel TYPE LEVEL\n");
+       printf("    where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib\n");
+       printf("           LEVEL is -1|0|1|2|3|4\n");
        printf("  Show connection status:\n");
        printf("    stroke status\n");
        printf("  Show connection status:\n");
        printf("    stroke status\n");
-       printf("  Show list of locally loaded certificates and crls:\n");
-       printf("    stroke listcerts|listcacerts|listcrls|listall\n");
-       printf("  Reload ca certificates and crls:\n");
-       printf("    stroke rereadcacerts|rereadcrls|rereadall\n");
+       printf("  Show list of authority and attribute certificates:\n");
+       printf("    stroke listcacerts|listocspcerts|listaacerts|listacerts\n");
+       printf("  Show list of end entity certificates, ca info records  and crls:\n");
+       printf("    stroke listcerts|listcainfos|listcrls|listall\n");
+       printf("  Show list of supported algorithms:\n");
+       printf("    stroke listalgs\n");
+       printf("  Reload authority and attribute certificates:\n");
+       printf("    stroke rereadcacerts|rereadocspcerts|rereadaacerts|rereadacerts\n");
+       printf("  Reload secrets and crls:\n");
+       printf("    stroke rereadsecrets|rereadcrls|rereadall\n");
+       printf("  Purge ocsp cache entries:\n");
+       printf("    stroke purgeocsp\n");
+       printf("  Purge IKE_SAs without a CHILD_SA:\n");
+       printf("    stroke purgeike\n");
+       printf("  Show leases of a pool:\n");
+       printf("    stroke leases [POOL [ADDRESS]]\n");
        exit_error(error);
 }
 
        exit_error(error);
 }
 
@@ -289,7 +361,7 @@ int main(int argc, char *argv[])
        {
                exit_usage(NULL);
        }
        {
                exit_usage(NULL);
        }
-       
+
        token = in_word_set(argv[1], strlen(argv[1]));
 
        if (token == NULL)
        token = in_word_set(argv[1], strlen(argv[1]));
 
        if (token == NULL)
@@ -305,10 +377,9 @@ int main(int argc, char *argv[])
                                exit_usage("\"add\" needs more parameters...");
                        }
                        res = add_connection(argv[2],
                                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]));
+                                                                argv[3], argv[4],
+                                                                argv[5], argv[6],
+                                                                argv[7], argv[8]);
                        break;
                case STROKE_DELETE:
                case STROKE_DEL:
                        break;
                case STROKE_DELETE:
                case STROKE_DEL:
@@ -332,35 +403,68 @@ int main(int argc, char *argv[])
                        }
                        res = terminate_connection(argv[2]);
                        break;
                        }
                        res = terminate_connection(argv[2]);
                        break;
-               case STROKE_LOGTYPE:
-                       if (argc < 5)
+               case STROKE_DOWN_SRCIP:
+                       if (argc < 3)
                        {
                        {
-                               exit_usage("\"logtype\" needs more parameters...");
+                               exit_usage("\"down-srcip\" needs start and optional end address");
+                       }
+                       res = terminate_connection_srcip(argv[2], argc > 3 ? argv[3] : NULL);
+                       break;
+               case STROKE_ROUTE:
+                       if (argc < 3)
+                       {
+                               exit_usage("\"route\" needs a connection name");
+                       }
+                       res = route_connection(argv[2]);
+                       break;
+               case STROKE_UNROUTE:
+                       if (argc < 3)
+                       {
+                               exit_usage("\"unroute\" needs a connection name");
                        }
                        }
-                       res = set_logtype(argv[2], argv[3], atoi(argv[4])); 
+                       res = unroute_connection(argv[2]);
                        break;
                case STROKE_LOGLEVEL:
                        if (argc < 4)
                        {
                                exit_usage("\"logtype\" needs more parameters...");
                        }
                        break;
                case STROKE_LOGLEVEL:
                        if (argc < 4)
                        {
                                exit_usage("\"logtype\" needs more parameters...");
                        }
-                       res = set_loglevel(argv[2], atoi(argv[3])); 
+                       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;
                        break;
                case STROKE_STATUS:
                case STROKE_STATUSALL:
                        res = show_status(token->kw, argc > 2 ? argv[2] : NULL);
                        break;
+               case STROKE_LIST_PUBKEYS:
                case STROKE_LIST_CERTS:
                case STROKE_LIST_CACERTS:
                case STROKE_LIST_CERTS:
                case STROKE_LIST_CACERTS:
+               case STROKE_LIST_OCSPCERTS:
+               case STROKE_LIST_AACERTS:
+               case STROKE_LIST_ACERTS:
+               case STROKE_LIST_CAINFOS:
                case STROKE_LIST_CRLS:
                case STROKE_LIST_CRLS:
+               case STROKE_LIST_OCSP:
+               case STROKE_LIST_ALGS:
                case STROKE_LIST_ALL:
                case STROKE_LIST_ALL:
-                       res = list(token->kw, argc > 2 && streq(argv[2], "--utc"));
+                       res = list(token->kw, argc > 2 && strcmp(argv[2], "--utc") == 0);
                        break;
                        break;
+               case STROKE_REREAD_SECRETS:
                case STROKE_REREAD_CACERTS:
                case STROKE_REREAD_CACERTS:
+               case STROKE_REREAD_OCSPCERTS:
+               case STROKE_REREAD_AACERTS:
+               case STROKE_REREAD_ACERTS:
                case STROKE_REREAD_CRLS:
                case STROKE_REREAD_ALL:
                        res = reread(token->kw);
                        break;
                case STROKE_REREAD_CRLS:
                case STROKE_REREAD_ALL:
                        res = reread(token->kw);
                        break;
+               case STROKE_PURGE_OCSP:
+               case STROKE_PURGE_IKE:
+                       res = purge(token->kw);
+                       break;
+               case STROKE_LEASES:
+                       res = leases(token->kw, argc > 2 ? argv[2] : NULL,
+                                                argc > 3 ? argv[3] : NULL);
+                       break;
                default:
                        exit_usage(NULL);
        }
                default:
                        exit_usage(NULL);
        }