aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/control/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/control/interfaces')
-rw-r--r--src/charon/control/interfaces/xml_interface.c237
-rw-r--r--src/charon/control/interfaces/xml_interface.xml133
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>