diff options
author | Tobias Brunner <tobias@strongswan.org> | 2015-08-17 11:13:37 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2015-08-17 11:13:37 +0200 |
commit | cec1fe8c7d426cadb892730ec338cd5d3107d780 (patch) | |
tree | 57535599e880d96e42100abfecb640396aa2b136 /src | |
parent | cdd7d2b197ba0a7e260e6937f907df599f20b474 (diff) | |
parent | b3d91cc64e1e4a0b7b83aea3d9d0efd15f4749ce (diff) | |
download | strongswan-cec1fe8c7d426cadb892730ec338cd5d3107d780.tar.bz2 strongswan-cec1fe8c7d426cadb892730ec338cd5d3107d780.tar.xz |
Merge branch 'vici-updown'
Documents the ike/child-updown events and adds a ike/child-rekey event
and a new listen() method in the Python VICI bindings to listen for
arbitrary events (similar to the listen_events() method in the Ruby
bindings).
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/plugins/vici/README.md | 59 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/python/LICENSE | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/python/vici/exception.py | 3 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/python/vici/session.py | 138 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/vici_query.c | 85 |
5 files changed, 236 insertions, 51 deletions
diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index db7ce4e76..1273bb8fc 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -738,6 +738,65 @@ information during an active_list-authorities_ command. } } +### ike-updown ### + +The _ike-updown_ event is issued when an IKE_SA is established or terminated. + + { + up = <yes or no> + <IKE_SA config name> = { + <same data as in the list-sas event, but without child-sas section> + } + } + +### ike-rekey ### + +The _ike-rekey_ event is issued when an IKE_SA is rekeyed. + + { + <IKE_SA config name> = { + old = { + <same data as in the list-sas event, but without child-sas section> + } + new = { + <same data as in the list-sas event, but without child-sas section> + } + } + } + +### child-updown ### + +The _child-updown_ event is issued when a CHILD_SA is established or terminated. + + { + up = <yes or no> + <IKE_SA config name> = { + <same data as in the list-sas event, but with only the affected + CHILD_SA in the child-sas section> + } + } + +### child-rekey ### + +The _child-rekey_ event is issued when a CHILD_SA is rekeyed. + + { + <IKE_SA config name> = { + <same data as in the list-sas event, but with the child-sas section + as follows> + child-sas = { + <child-sa-name> = { + old = { + <same data as in the list-sas event> + } + new = { + <same data as in the list-sas event> + } + } + } + } + } + # libvici C client library # libvici is the reference implementation of a C client library implementing diff --git a/src/libcharon/plugins/vici/python/LICENSE b/src/libcharon/plugins/vici/python/LICENSE index 111523ca8..54f2158dc 100644 --- a/src/libcharon/plugins/vici/python/LICENSE +++ b/src/libcharon/plugins/vici/python/LICENSE @@ -1,4 +1,6 @@ Copyright (c) 2015 Björn Schuberg +Copyright (c) 2015 Martin Willi +Copyright (c) 2015 Tobias Brunner Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/libcharon/plugins/vici/python/vici/exception.py b/src/libcharon/plugins/vici/python/vici/exception.py index 36384e556..757ac51a9 100644 --- a/src/libcharon/plugins/vici/python/vici/exception.py +++ b/src/libcharon/plugins/vici/python/vici/exception.py @@ -8,3 +8,6 @@ class SessionException(Exception): class CommandException(Exception): """Command result exception.""" + +class EventUnknownException(Exception): + """Event unknown exception.""" diff --git a/src/libcharon/plugins/vici/python/vici/session.py b/src/libcharon/plugins/vici/python/vici/session.py index dee58699d..283e3d13d 100644 --- a/src/libcharon/plugins/vici/python/vici/session.py +++ b/src/libcharon/plugins/vici/python/vici/session.py @@ -1,7 +1,7 @@ import collections import socket -from .exception import SessionException, CommandException +from .exception import SessionException, CommandException, EventUnknownException from .protocol import Transport, Packet, Message @@ -197,6 +197,16 @@ class Session(object): """ return self.handler.request("get-pools") + def listen(self, event_types): + """Register and listen for the given events. + + :param event_types: event types to register + :type event_types: list + :return: generator for streamed event responses as (event_type, dict) + :rtype: generator + """ + return self.handler.listen(event_types) + class SessionHandler(object): """Handles client command execution requests over vici.""" @@ -215,6 +225,32 @@ class SessionHandler(object): self.transport.send(packet) return Packet.parse(self.transport.receive()) + def _register_unregister(self, event_type, register): + """Register or unregister for the given event. + + :param event_type: event to register + :type event_type: str + :param register: whether to register or unregister + :type register: bool + """ + if register: + packet = Packet.register_event(event_type) + else: + packet = Packet.unregister_event(event_type) + response = self._communicate(packet) + if response.response_type == Packet.EVENT_UNKNOWN: + raise EventUnknownException( + "Unknown event type '{event}'".format(event=event_type) + ) + elif response.response_type != Packet.EVENT_CONFIRM: + raise SessionException( + "Unexpected response type {type}, " + "expected '{confirm}' (EVENT_CONFIRM)".format( + type=response.response_type, + confirm=Packet.EVENT_CONFIRM, + ) + ) + def request(self, command, message=None): """Send request with an optional message. @@ -265,57 +301,37 @@ class SessionHandler(object): if message is not None: message = Message.serialize(message) - # subscribe to event stream - packet = Packet.register_event(event_stream_type) - response = self._communicate(packet) - - if response.response_type != Packet.EVENT_CONFIRM: - raise SessionException( - "Unexpected response type {type}, " - "expected '{confirm}' (EVENT_CONFIRM)".format( - type=response.response_type, - confirm=Packet.EVENT_CONFIRM, - ) - ) - - # issue command, and read any event messages - packet = Packet.request(command, message) - self.transport.send(packet) - exited = False - while True: - response = Packet.parse(self.transport.receive()) - if response.response_type == Packet.EVENT: - if not exited: - try: - yield Message.deserialize(response.payload) - except GeneratorExit: - exited = True - pass + self._register_unregister(event_stream_type, True); + + try: + packet = Packet.request(command, message) + self.transport.send(packet) + exited = False + while True: + response = Packet.parse(self.transport.receive()) + if response.response_type == Packet.EVENT: + if not exited: + try: + yield Message.deserialize(response.payload) + except GeneratorExit: + exited = True + pass + else: + break + + if response.response_type == Packet.CMD_RESPONSE: + command_response = Message.deserialize(response.payload) else: - break - - if response.response_type == Packet.CMD_RESPONSE: - command_response = Message.deserialize(response.payload) - else: - raise SessionException( - "Unexpected response type {type}, " - "expected '{response}' (CMD_RESPONSE)".format( - type=response.response_type, - response=Packet.CMD_RESPONSE + raise SessionException( + "Unexpected response type {type}, " + "expected '{response}' (CMD_RESPONSE)".format( + type=response.response_type, + response=Packet.CMD_RESPONSE + ) ) - ) - # unsubscribe from event stream - packet = Packet.unregister_event(event_stream_type) - response = self._communicate(packet) - if response.response_type != Packet.EVENT_CONFIRM: - raise SessionException( - "Unexpected response type {type}, " - "expected '{confirm}' (EVENT_CONFIRM)".format( - type=response.response_type, - confirm=Packet.EVENT_CONFIRM, - ) - ) + finally: + self._register_unregister(event_stream_type, False); # evaluate command result, if any if "success" in command_response: @@ -325,3 +341,27 @@ class SessionHandler(object): errmsg=command_response["errmsg"] ) ) + + def listen(self, event_types): + """Register and listen for the given events. + + :param event_types: event types to register + :type event_types: list + :return: generator for streamed event responses as (event_type, dict) + :rtype: generator + """ + for event_type in event_types: + self._register_unregister(event_type, True) + + try: + while True: + response = Packet.parse(self.transport.receive()) + if response.response_type == Packet.EVENT: + try: + yield response.event_type, Message.deserialize(response.payload) + except GeneratorExit: + break + + finally: + for event_type in event_types: + self._register_unregister(event_type, False) diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index d94d760b9..e4d0d62f4 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -1031,7 +1031,9 @@ static void manage_commands(private_vici_query_t *this, bool reg) this->dispatcher->manage_event(this->dispatcher, "list-conn", reg); this->dispatcher->manage_event(this->dispatcher, "list-cert", reg); this->dispatcher->manage_event(this->dispatcher, "ike-updown", reg); + this->dispatcher->manage_event(this->dispatcher, "ike-rekey", reg); this->dispatcher->manage_event(this->dispatcher, "child-updown", reg); + this->dispatcher->manage_event(this->dispatcher, "child-rekey", reg); manage_command(this, "list-sas", list_sas, reg); manage_command(this, "list-policies", list_policies, reg); manage_command(this, "list-conns", list_conns, reg); @@ -1054,10 +1056,14 @@ METHOD(listener_t, ike_updown, bool, now = time_monotonic(NULL); b = vici_builder_create(); + + if (up) + { + b->add_kv(b, "up", "yes"); + } + b->begin_section(b, ike_sa->get_name(ike_sa)); list_ike(this, b, ike_sa, now); - b->begin_section(b, "child-sas"); - b->end_section(b); b->end_section(b); this->dispatcher->raise_event(this->dispatcher, @@ -1066,6 +1072,35 @@ METHOD(listener_t, ike_updown, bool, return TRUE; } +METHOD(listener_t, ike_rekey, bool, + private_vici_query_t *this, ike_sa_t *old, ike_sa_t *new) +{ + vici_builder_t *b; + time_t now; + + if (!this->dispatcher->has_event_listeners(this->dispatcher, "ike-rekey")) + { + return TRUE; + } + + now = time_monotonic(NULL); + + b = vici_builder_create(); + b->begin_section(b, old->get_name(old)); + b->begin_section(b, "old"); + list_ike(this, b, old, now); + b->end_section(b); + b->begin_section(b, "new"); + list_ike(this, b, new, now); + b->end_section(b); + b->end_section(b); + + this->dispatcher->raise_event(this->dispatcher, + "ike-rekey", 0, b->finalize(b)); + + return TRUE; +} + METHOD(listener_t, child_updown, bool, private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, bool up) { @@ -1080,6 +1115,11 @@ METHOD(listener_t, child_updown, bool, now = time_monotonic(NULL); b = vici_builder_create(); + if (up) + { + b->add_kv(b, "up", "yes"); + } + b->begin_section(b, ike_sa->get_name(ike_sa)); list_ike(this, b, ike_sa, now); b->begin_section(b, "child-sas"); @@ -1097,6 +1137,45 @@ METHOD(listener_t, child_updown, bool, return TRUE; } +METHOD(listener_t, child_rekey, bool, + private_vici_query_t *this, ike_sa_t *ike_sa, child_sa_t *old, + child_sa_t *new) +{ + vici_builder_t *b; + time_t now; + + if (!this->dispatcher->has_event_listeners(this->dispatcher, "child-rekey")) + { + return TRUE; + } + + now = time_monotonic(NULL); + b = vici_builder_create(); + + b->begin_section(b, ike_sa->get_name(ike_sa)); + list_ike(this, b, ike_sa, now); + b->begin_section(b, "child-sas"); + + b->begin_section(b, old->get_name(old)); + + b->begin_section(b, "old"); + list_child(this, b, old, now); + b->end_section(b); + b->begin_section(b, "new"); + list_child(this, b, new, now); + b->end_section(b); + + b->end_section(b); + + b->end_section(b); + b->end_section(b); + + this->dispatcher->raise_event(this->dispatcher, + "child-rekey", 0, b->finalize(b)); + + return TRUE; +} + METHOD(vici_query_t, destroy, void, private_vici_query_t *this) { @@ -1115,7 +1194,9 @@ vici_query_t *vici_query_create(vici_dispatcher_t *dispatcher) .public = { .listener = { .ike_updown = _ike_updown, + .ike_rekey = _ike_rekey, .child_updown = _child_updown, + .child_rekey = _child_rekey, }, .destroy = _destroy, }, |