diff options
-rw-r--r-- | src/charon/plugins/stroke/stroke_control.c | 71 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_control.h | 7 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_socket.c | 17 | ||||
-rwxr-xr-x | src/ipsec/ipsec.in | 15 | ||||
-rw-r--r-- | src/stroke/stroke.c | 21 | ||||
-rw-r--r-- | src/stroke/stroke_keywords.h | 1 | ||||
-rw-r--r-- | src/stroke/stroke_keywords.txt | 1 | ||||
-rw-r--r-- | src/stroke/stroke_msg.h | 8 |
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 { |