Fixed compiler warning.
[strongswan.git] / src / stroke / stroke.c
index 6b2e33d..1cb8cc2 100644 (file)
@@ -12,8 +12,6 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
- *
- * RCSID $Id$
  */
 
 #include <stdlib.h>
@@ -27,6 +25,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stddef.h>
+#include <string.h>
 
 #include "stroke_msg.h"
 #include "stroke_keywords.h"
@@ -54,13 +53,16 @@ static char* push_string(stroke_msg_t *msg, char *string)
 
 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;
-       char buffer[64];
+       char buffer[512];
        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)
        {
@@ -74,7 +76,7 @@ static int send_stroke_msg (stroke_msg_t *msg)
                close(sock);
                return -1;
        }
-       
+
        /* send message */
        if (write(sock, msg, msg->length) != msg->length)
        {
@@ -82,92 +84,68 @@ static int send_stroke_msg (stroke_msg_t *msg)
                close(sock);
                return -1;
        }
-       
+
        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));
        }
-       
+
        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_net, char *other_net,
-                                                 u_int my_netmask, u_int other_netmask)
+                                                 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.ikev2 = 1;
        msg.add_conn.auth_method = 2;
-       msg.add_conn.eap_type = 0;
        msg.add_conn.mode = 1;
        msg.add_conn.mobike = 1;
-       msg.add_conn.force_encap = 0;
-       
-       msg.add_conn.rekey.reauth = 0;
-       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.dpd.delay = 0;
        msg.add_conn.dpd.action = 1;
-       
-       msg.add_conn.p2p.mediation = 0;
-       msg.add_conn.p2p.mediated_by = NULL;
-       msg.add_conn.p2p.peerid = 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.sourceip = NULL;
-       msg.add_conn.me.virtual_ip = 0;
-       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.hostaccess = 0;
-       msg.add_conn.me.tohost = 0;
-       msg.add_conn.me.protocol = 0;
-       msg.add_conn.me.port = 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.sourceip = NULL;
-       msg.add_conn.other.virtual_ip = 0;
-       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.hostaccess = 0;
-       msg.add_conn.other.tohost = 0;
-       msg.add_conn.other.protocol = 0;
-       msg.add_conn.other.port = 0;
-       
+
        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);
@@ -177,7 +155,7 @@ static int del_connection(char *name)
 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);
@@ -187,17 +165,28 @@ static int initiate_connection(char *name)
 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);
 }
 
+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);
@@ -207,7 +196,7 @@ static int route_connection(char *name)
 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);
@@ -217,7 +206,7 @@ static int unroute_connection(char *name)
 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);
@@ -225,6 +214,7 @@ static int show_status(stroke_keyword_t kw, char *connection)
 }
 
 static int list_flags[] = {
+       LIST_PUBKEYS,
        LIST_CERTS,
        LIST_CACERTS,
        LIST_OCSPCERTS,
@@ -234,13 +224,14 @@ static int list_flags[] = {
        LIST_CAINFOS,
        LIST_CRLS,
        LIST_OCSP,
+       LIST_ALGS,
        LIST_ALL
 };
 
 static int list(stroke_keyword_t kw, int utc)
 {
        stroke_msg_t msg;
-       
+
        msg.type = STR_LIST;
        msg.length = offsetof(stroke_msg_t, buffer);
        msg.list.utc = utc;
@@ -261,7 +252,7 @@ static int reread_flags[] = {
 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];
@@ -269,23 +260,36 @@ static int reread(stroke_keyword_t kw)
 }
 
 static int purge_flags[] = {
-       PURGE_OCSP
+       PURGE_OCSP,
+       PURGE_IKE,
 };
 
 static int purge(stroke_keyword_t kw)
 {
        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);
 }
 
+static int leases(stroke_keyword_t kw, char *pool, char *address)
+{
+
+       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.loglevel.type = push_string(&msg, type);
@@ -310,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("           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");
@@ -321,6 +324,9 @@ 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 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");
@@ -331,12 +337,18 @@ static void exit_usage(char *error)
        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);
 }
 
@@ -349,7 +361,7 @@ int main(int argc, char *argv[])
        {
                exit_usage(NULL);
        }
-       
+
        token = in_word_set(argv[1], strlen(argv[1]));
 
        if (token == NULL)
@@ -365,10 +377,9 @@ int main(int argc, char *argv[])
                                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:
@@ -392,6 +403,13 @@ int main(int argc, char *argv[])
                        }
                        res = terminate_connection(argv[2]);
                        break;
+               case STROKE_DOWN_SRCIP:
+                       if (argc < 3)
+                       {
+                               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)
                        {
@@ -411,12 +429,13 @@ int main(int argc, char *argv[])
                        {
                                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;
+               case STROKE_LIST_PUBKEYS:
                case STROKE_LIST_CERTS:
                case STROKE_LIST_CACERTS:
                case STROKE_LIST_OCSPCERTS:
@@ -425,6 +444,7 @@ int main(int argc, char *argv[])
                case STROKE_LIST_CAINFOS:
                case STROKE_LIST_CRLS:
                case STROKE_LIST_OCSP:
+               case STROKE_LIST_ALGS:
                case STROKE_LIST_ALL:
                        res = list(token->kw, argc > 2 && strcmp(argv[2], "--utc") == 0);
                        break;
@@ -438,8 +458,13 @@ int main(int argc, char *argv[])
                        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);
        }