aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon/plugins/stroke/stroke_control.c71
-rw-r--r--src/charon/plugins/stroke/stroke_control.h7
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c17
-rwxr-xr-xsrc/ipsec/ipsec.in15
-rw-r--r--src/stroke/stroke.c21
-rw-r--r--src/stroke/stroke_keywords.h1
-rw-r--r--src/stroke/stroke_keywords.txt1
-rw-r--r--src/stroke/stroke_msg.h8
8 files changed, 141 insertions, 0 deletions
diff --git a/src/charon/plugins/stroke/stroke_control.c b/src/charon/plugins/stroke/stroke_control.c
index 2956b1576..8fdd585e5 100644
--- a/src/charon/plugins/stroke/stroke_control.c
+++ b/src/charon/plugins/stroke/stroke_control.c
@@ -18,6 +18,7 @@
#include "stroke_control.h"
#include <daemon.h>
+#include <processing/jobs/delete_ike_sa_job.h>
typedef struct private_stroke_control_t private_stroke_control_t;
@@ -240,6 +241,75 @@ static void terminate(private_stroke_control_t *this, stroke_msg_t *msg, FILE *o
}
/**
+ * Implementation of stroke_control_t.terminate_srcip.
+ */
+static void terminate_srcip(private_stroke_control_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ host_t *start = NULL, *end = NULL, *vip;
+ chunk_t chunk_start, chunk_end, chunk_vip;
+
+ if (msg->terminate_srcip.start)
+ {
+ start = host_create_from_string(msg->terminate_srcip.start, 0);
+ }
+ if (!start)
+ {
+ DBG1(DBG_CFG, "invalid start address: %s", msg->terminate_srcip.start);
+ return;
+ }
+ chunk_start = start->get_address(start);
+ if (msg->terminate_srcip.end)
+ {
+ end = host_create_from_string(msg->terminate_srcip.end, 0);
+ if (!end)
+ {
+ DBG1(DBG_CFG, "invalid end address: %s", msg->terminate_srcip.end);
+ start->destroy(start);
+ return;
+ }
+ chunk_end = end->get_address(end);
+ }
+
+ enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
+ if (!vip)
+ {
+ continue;
+ }
+ if (!end)
+ {
+ if (!vip->ip_equals(vip, start))
+ {
+ continue;
+ }
+ }
+ else
+ {
+ chunk_vip = vip->get_address(vip);
+ if (chunk_vip.len != chunk_start.len ||
+ chunk_vip.len != chunk_end.len ||
+ memcmp(chunk_vip.ptr, chunk_start.ptr, chunk_vip.len) < 0 ||
+ memcmp(chunk_vip.ptr, chunk_end.ptr, chunk_vip.len) > 0)
+ {
+ continue;
+ }
+ }
+
+ /* schedule delete asynchronously */
+ charon->processor->queue_job(charon->processor, (job_t*)
+ delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE));
+ }
+ enumerator->destroy(enumerator);
+ start->destroy(start);
+ DESTROY_IF(end);
+}
+
+/**
* Implementation of stroke_control_t.route.
*/
static void route(private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
@@ -336,6 +406,7 @@ stroke_control_t *stroke_control_create()
this->public.initiate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))initiate;
this->public.terminate = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate;
+ this->public.terminate_srcip = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))terminate_srcip;
this->public.route = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))route;
this->public.unroute = (void(*)(stroke_control_t*, stroke_msg_t *msg, FILE *out))unroute;
this->public.destroy = (void(*)(stroke_control_t*))destroy;
diff --git a/src/charon/plugins/stroke/stroke_control.h b/src/charon/plugins/stroke/stroke_control.h
index 917679209..926964458 100644
--- a/src/charon/plugins/stroke/stroke_control.h
+++ b/src/charon/plugins/stroke/stroke_control.h
@@ -49,6 +49,13 @@ struct stroke_control_t {
void (*terminate)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
/**
+ * Terminate a connection by peers virtual IP.
+ *
+ * @param msg stroke message
+ */
+ void (*terminate_srcip)(stroke_control_t *this, stroke_msg_t *msg, FILE *out);
+
+ /**
* Route a connection.
*
* @param msg stroke message
diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c
index 92e295a0c..d8ea24e14 100644
--- a/src/charon/plugins/stroke/stroke_socket.c
+++ b/src/charon/plugins/stroke/stroke_socket.c
@@ -215,6 +215,20 @@ static void stroke_terminate(private_stroke_socket_t *this, stroke_msg_t *msg, F
DBG1(DBG_CFG, "received stroke: terminate '%s'", msg->terminate.name);
this->control->terminate(this->control, msg, out);
+}
+
+/**
+ * terminate a connection by peers virtual IP
+ */
+static void stroke_terminate_srcip(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->terminate_srcip.start);
+ pop_string(msg, &msg->terminate_srcip.end);
+ DBG1(DBG_CFG, "received stroke: terminate-srcip %s-%s",
+ msg->terminate_srcip.start, msg->terminate_srcip.end);
+
+ this->control->terminate_srcip(this->control, msg, out);
}
/**
@@ -430,6 +444,9 @@ static job_requeue_t process(stroke_job_context_t *ctx)
case STR_TERMINATE:
stroke_terminate(this, msg, out);
break;
+ case STR_TERMINATE_SRCIP:
+ stroke_terminate_srcip(this, msg, out);
+ break;
case STR_STATUS:
stroke_status(this, msg, out, FALSE);
break;
diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in
index 9cae2475d..6ef2faf55 100755
--- a/src/ipsec/ipsec.in
+++ b/src/ipsec/ipsec.in
@@ -116,6 +116,21 @@ down)
fi
exit "$rc"
;;
+down-srcip)
+ shift
+ if [ "$#" -lt 1 ]
+ then
+ echo "Usage: ipsec down-srcip <start> [<end>]"
+ exit 2
+ fi
+ rc=7
+ if [ -e $IPSEC_CHARON_PID ]
+ then
+ $IPSEC_STROKE down-srcip $*
+ rc="$?"
+ fi
+ exit "$rc"
+ ;;
listalgs|listpubkeys|\listcards|\rereadgroups)
op="$1"
shift
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index 90d99acbc..01537b321 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -158,6 +158,17 @@ static int terminate_connection(char *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;
@@ -284,6 +295,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");
@@ -354,6 +368,13 @@ int main(int argc, char *argv[])
}
res = terminate_connection(argv[2]);
break;
+ case STROKE_DOWNSRCIP:
+ if (argc < 3)
+ {
+ exit_usage("\"down-srcip\" needs start and end address");
+ }
+ res = terminate_connection_srcip(argv[2], argc > 3 ? argv[3] : NULL);
+ break;
case STROKE_ROUTE:
if (argc < 3)
{
diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h
index 7bad0d4d6..b99863178 100644
--- a/src/stroke/stroke_keywords.h
+++ b/src/stroke/stroke_keywords.h
@@ -26,6 +26,7 @@ typedef enum {
STROKE_UNROUTE,
STROKE_UP,
STROKE_DOWN,
+ STROKE_DOWNSRCIP,
STROKE_LOGLEVEL,
STROKE_STATUS,
STROKE_STATUSALL,
diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt
index 672203ca6..dfe03fb6a 100644
--- a/src/stroke/stroke_keywords.txt
+++ b/src/stroke/stroke_keywords.txt
@@ -33,6 +33,7 @@ route, STROKE_ROUTE
unroute, STROKE_UNROUTE
up, STROKE_UP
down, STROKE_DOWN
+down-srcip, STROKE_DOWNSRCIP
loglevel, STROKE_LOGLEVEL
status, STROKE_STATUS
statusall, STROKE_STATUSALL
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 8258fdc7d..40447e37f 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -158,6 +158,8 @@ struct stroke_msg_t {
STR_DEL_CONN,
/* terminate connection */
STR_TERMINATE,
+ /* terminate connection by peers srcip/virtual ip */
+ STR_TERMINATE_SRCIP,
/* show connection status */
STR_STATUS,
/* show verbose connection status */
@@ -187,6 +189,12 @@ struct stroke_msg_t {
struct {
char *name;
} initiate, route, unroute, terminate, status, del_conn, del_ca;
+
+ /* data for STR_TERMINATE_SRCIP */
+ struct {
+ char *start;
+ char *end;
+ } terminate_srcip;
/* data for STR_ADD_CONN */
struct {