diff options
Diffstat (limited to 'src/charon/control/interfaces')
-rw-r--r-- | src/charon/control/interfaces/xml_interface.c | 237 | ||||
-rw-r--r-- | src/charon/control/interfaces/xml_interface.xml | 133 |
2 files changed, 324 insertions, 46 deletions
diff --git a/src/charon/control/interfaces/xml_interface.c b/src/charon/control/interfaces/xml_interface.c index 7a44c03fb..a3be5703d 100644 --- a/src/charon/control/interfaces/xml_interface.c +++ b/src/charon/control/interfaces/xml_interface.c @@ -146,17 +146,15 @@ static void write_address(xmlTextWriterPtr writer, char *element, host_t *host) } /** - * write a childEnd + * write networks element */ -static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local) +static void write_networks(xmlTextWriterPtr writer, char *element, + linked_list_t *list) { iterator_t *iterator; - linked_list_t *list; traffic_selector_t *ts; - xmlTextWriterWriteFormatElement(writer, "spi", "%lx", - htonl(child->get_spi(child, local))); - xmlTextWriterStartElement(writer, "networks"); - list = child->get_traffic_selectors(child, local); + + xmlTextWriterStartElement(writer, element); iterator = list->create_iterator(list, TRUE); while (iterator->iterate(iterator, (void**)&ts)) { @@ -171,6 +169,19 @@ static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool loca } /** + * write a childEnd + */ +static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local) +{ + linked_list_t *list; + + xmlTextWriterWriteFormatElement(writer, "spi", "%lx", + htonl(child->get_spi(child, local))); + list = child->get_traffic_selectors(child, local); + write_networks(writer, "networks", list); +} + +/** * write a child_sa_t */ static void write_child(xmlTextWriterPtr writer, child_sa_t *child) @@ -283,6 +294,87 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer xmlTextWriterEndElement(writer); } +/** + * process a configlist query request message + */ +static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr writer) +{ + iterator_t *iterator; + peer_cfg_t *peer_cfg; + + /* <configlist> */ + xmlTextWriterStartElement(writer, "configlist"); + + iterator = charon->backends->create_iterator(charon->backends); + while (iterator->iterate(iterator, (void**)&peer_cfg)) + { + iterator_t *children; + child_cfg_t *child_cfg; + ike_cfg_t *ike_cfg; + linked_list_t *list; + + /* <peerconfig> */ + xmlTextWriterStartElement(writer, "peerconfig"); + xmlTextWriterWriteElement(writer, "name", peer_cfg->get_name(peer_cfg)); + write_id(writer, "local", peer_cfg->get_my_id(peer_cfg)); + write_id(writer, "remote", peer_cfg->get_other_id(peer_cfg)); + + /* <ikeconfig> */ + ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); + xmlTextWriterStartElement(writer, "ikeconfig"); + write_address(writer, "local", ike_cfg->get_my_host(ike_cfg)); + write_address(writer, "remote", ike_cfg->get_other_host(ike_cfg)); + xmlTextWriterEndElement(writer); + /* </ikeconfig> */ + + /* <childconfiglist> */ + xmlTextWriterStartElement(writer, "childconfiglist"); + children = peer_cfg->create_child_cfg_iterator(peer_cfg); + while (children->iterate(children, (void**)&child_cfg)) + { + /* <childconfig> */ + xmlTextWriterStartElement(writer, "childconfig"); + xmlTextWriterWriteElement(writer, "name", + child_cfg->get_name(child_cfg)); + list = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); + write_networks(writer, "local", list); + list->destroy_offset(list, offsetof(traffic_selector_t, destroy)); + list = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); + write_networks(writer, "remote", list); + list->destroy_offset(list, offsetof(traffic_selector_t, destroy)); + xmlTextWriterEndElement(writer); + /* </childconfig> */ + } + children->destroy(children); + /* </childconfiglist> */ + xmlTextWriterEndElement(writer); + /* </peerconfig> */ + xmlTextWriterEndElement(writer); + } + iterator->destroy(iterator); + /* </configlist> */ + xmlTextWriterEndElement(writer); +} + +/** + * callback which logs to a XML writer + */ +static bool xml_callback(xmlTextWriterPtr writer, signal_t signal, level_t level, + ike_sa_t* ike_sa, char* format, va_list args) +{ + if (level <= 1) + { + /* <item> */ + xmlTextWriterStartElement(writer, "item"); + xmlTextWriterWriteFormatAttribute(writer, "level", "%d", level); + xmlTextWriterWriteFormatAttribute(writer, "source", "%N", signal_names, signal); + xmlTextWriterWriteFormatAttribute(writer, "thread", "%u", pthread_self()); + xmlTextWriterWriteVFormatString(writer, format, args); + xmlTextWriterEndElement(writer); + /* </item> */ + } + return TRUE; +} /** * process a *terminate control request message @@ -290,39 +382,105 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer static void request_control_terminate(xmlTextReaderPtr reader, xmlTextWriterPtr writer, bool ike) { - while (xmlTextReaderRead(reader)) - { - if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) + if (xmlTextReaderRead(reader) && + xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) + { + const char *str; + u_int32_t id; + status_t status; + + str = xmlTextReaderConstValue(reader); + if (str == NULL || !(id = atoi(str))) + { + DBG1(DBG_CFG, "error parsing XML id string"); + return; + } + DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id); + + /* <log> */ + xmlTextWriterStartElement(writer, "log"); + if (ike) + { + status = charon->interfaces->terminate_ike( + charon->interfaces, id, + (interface_manager_cb_t)xml_callback, writer); + } + else + { + status = charon->interfaces->terminate_child( + charon->interfaces, id, + (interface_manager_cb_t)xml_callback, writer); + } + /* </log> */ + xmlTextWriterEndElement(writer); + xmlTextWriterWriteFormatElement(writer, "status", "%d", status); + } +} + +/** + * process a *initiate control request message + */ +static void request_control_initiate(xmlTextReaderPtr reader, + xmlTextWriterPtr writer, bool ike) +{ + if (xmlTextReaderRead(reader) && + xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) + { + const char *str; + status_t status = FAILED; + peer_cfg_t *peer; + child_cfg_t *child = NULL; + iterator_t *iterator; + + str = xmlTextReaderConstValue(reader); + if (str == NULL) { - if (streq(xmlTextReaderConstName(reader), "id")) + DBG1(DBG_CFG, "error parsing XML config name string"); + return; + } + DBG1(DBG_CFG, "initiating %s_SA %s", ike ? "IKE" : "CHILD", str); + + /* <log> */ + xmlTextWriterStartElement(writer, "log"); + peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str); + if (peer) + { + iterator = peer->create_child_cfg_iterator(peer); + if (ike) + { + if (!iterator->iterate(iterator, (void**)&child)) + { + child = NULL; + } + child->get_ref(child); + } + else { - if (xmlTextReaderRead(reader) && - xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) - { - const char *str; - u_int32_t id; - - str = xmlTextReaderConstValue(reader); - if (str == NULL || !(id = atoi(str))) + while (iterator->iterate(iterator, (void**)&child)) + { + if (streq(child->get_name(child), str)) { - DBG1(DBG_CFG, "error parsing XML id string"); + child->get_ref(child); break; } - DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id); - if (ike) - { - charon->interfaces->terminate_ike(charon->interfaces, - id, interface_manager_cb_empty, NULL); - } - else - { - charon->interfaces->terminate_child(charon->interfaces, - id, interface_manager_cb_empty, NULL); - } - break; + child = NULL; } } + iterator->destroy(iterator); + if (child) + { + status = charon->interfaces->initiate(charon->interfaces, + peer, child, (interface_manager_cb_t)xml_callback, + writer); + } + else + { + peer->destroy(peer); + } } + /* </log> */ + xmlTextWriterEndElement(writer); + xmlTextWriterWriteFormatElement(writer, "status", "%d", status); } } @@ -342,6 +500,11 @@ static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer) request_query_ikesa(reader, writer); break; } + if (streq(xmlTextReaderConstName(reader), "configlist")) + { + request_query_config(reader, writer); + break; + } } } /* </query> */ @@ -369,6 +532,16 @@ static void request_control(xmlTextReaderPtr reader, xmlTextWriterPtr writer) request_control_terminate(reader, writer, FALSE); break; } + if (streq(xmlTextReaderConstName(reader), "ikesainitiate")) + { + request_control_initiate(reader, writer, TRUE); + break; + } + if (streq(xmlTextReaderConstName(reader), "childsainitiate")) + { + request_control_initiate(reader, writer, FALSE); + break; + } } } /* </control> */ diff --git a/src/charon/control/interfaces/xml_interface.xml b/src/charon/control/interfaces/xml_interface.xml index 7eaf4ed8a..66a51117e 100644 --- a/src/charon/control/interfaces/xml_interface.xml +++ b/src/charon/control/interfaces/xml_interface.xml @@ -36,6 +36,9 @@ <optional> <ref name="QueryRequestIkesa"/> </optional> + <optional> + <ref name="QueryRequestConfig"/> + </optional> <!-- others --> </element> </optional> @@ -47,6 +50,12 @@ <optional> <ref name="ControlRequestChildTerminate"/> </optional> + <optional> + <ref name="ControlRequestIkeInitiate"/> + </optional> + <optional> + <ref name="ControlRequestChildInitiate"/> + </optional> <!-- others --> </element> </optional> @@ -59,14 +68,26 @@ <choice> <element name="error"> <attribute name="code"> - <data type="string"/> + <data type="nonNegativeInteger"/> </attribute> + <data type="string"/> </element> <group> <optional> <element name="query"> <optional> - <ref name="ikesalist"/> + <ref name="QueryResponseIkesa"/> + </optional> + <optional> + <ref name="QueryResponseConfig"/> + </optional> + <!-- others --> + </element> + </optional> + <optional> + <element name="control"> + <optional> + <ref name="ControlResponse"/> </optional> <!-- others --> </element> @@ -79,7 +100,7 @@ </element> </start> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> - <!-- IKE SA query --> + <!-- Query --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <define name="QueryRequestIkesa"> <element name="ikesalist"> @@ -175,30 +196,102 @@ <define name="childEnd"> <element name="spi"> <element name="networks"> + <ref name="networks"> + </element> + </define> + <define name="QueryRequestConfig"> + <element name="configlist"> + <empty/> + </element> + </define> + <define name="QueryResponseConfig"> + <element name="configlist"> <zeroOrMore> - <element name="network"> - <optional> - <attribute name="protocol"/> - </optional> - <optional> - <attribute name="port"/> - </optional> + <element name="peerconfig"> + <element name="name"> + <data type="string"/> + </element> + <element name="local"> + <ref name="identification"/> + </element> + <element name="remote"> + <ref name="identification"/> + </element> + <element name="ikeconfig"> + <ref name="ikeconfig"/> + </element> + <element name="childconfiglist"> + <zeroOrMore> + <element name="childconfig"> + <ref name="childconfig"/> + </element> + </zeroOrMore> + </element> </element> </zeroOrMore> </element> </define> + <define name="ikeconfig"> + <element name="local"> + <ref name="address"/> + </element> + <element name="remote"> + <ref name="address"/> + </element> + </define> + <define name="childconfig"> + <element name="name"> + <data type="string"/> + </element> + <element name="local"> + <ref name="networks"> + </element> + <element name="remote"> + <ref name="networks"> + </element> + </define> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> + <!-- Control --> + <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <define name="ControlRequestIkeTerminate"> <element name="ikesaterminate"> - <element name="id"> <data type="positiveInteger"/> - </element> </element> </define> <define name="ControlRequestChildTerminate"> <element name="childsaterminate"> - <element name="id"> <data type="positiveInteger"/> - </element> + </element> + </define> + <define name="ControlRequestIkeInitiate"> + <element name="ikesainitiate"> + <data type="string"/> + </element> + </define> + <define name="ControlRequestChildInitiate"> + <element name="childsainitiate"> + <data type="string"/> + </element> + </define> + <define name="QueryResponse"> + <element name="status"> + <data type="nonNegativeInteger"/> + </element> + <element name="log"> + <zeroOrMore> + <element name="item"> + <attribute name="level"> + <data type="nonNegativeInteger"> + </attribute> + <attribute name="thread"> + <data type="nonNegativeInteger"> + </attribute> + <attribute name="source"> + <data type="string"> + </attribute> + <data type="string"/> + <element> + </zeroOrMore> </element> </define> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> @@ -292,4 +385,16 @@ <param name="pattern">[a-zA-Z0-9_\-\.]+@(([a-z0-9\-](\.[a-z0-9\-]+)*)|(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))</param> </data> </define> + <define name="networks"> + <zeroOrMore> + <element name="network"> + <optional> + <attribute name="protocol"/> + </optional> + <optional> + <attribute name="port"/> + </optional> + </element> + </zeroOrMore> + </define> </grammar> |