implemented configuration query and IKE_SA initiation in XML interface

This commit is contained in:
Martin Willi 2007-11-13 11:56:52 +00:00
parent e36f5f3fd3
commit 30a68d715b
2 changed files with 324 additions and 46 deletions

View File

@ -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; iterator_t *iterator;
linked_list_t *list;
traffic_selector_t *ts; traffic_selector_t *ts;
xmlTextWriterWriteFormatElement(writer, "spi", "%lx",
htonl(child->get_spi(child, local))); xmlTextWriterStartElement(writer, element);
xmlTextWriterStartElement(writer, "networks");
list = child->get_traffic_selectors(child, local);
iterator = list->create_iterator(list, TRUE); iterator = list->create_iterator(list, TRUE);
while (iterator->iterate(iterator, (void**)&ts)) while (iterator->iterate(iterator, (void**)&ts))
{ {
@ -170,6 +168,19 @@ static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool loca
xmlTextWriterEndElement(writer); xmlTextWriterEndElement(writer);
} }
/**
* 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 * write a child_sa_t
*/ */
@ -283,6 +294,87 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
xmlTextWriterEndElement(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 * 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, static void request_control_terminate(xmlTextReaderPtr reader,
xmlTextWriterPtr writer, bool ike) xmlTextWriterPtr writer, bool ike)
{ {
while (xmlTextReaderRead(reader))
{
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
{
if (streq(xmlTextReaderConstName(reader), "id"))
{
if (xmlTextReaderRead(reader) && if (xmlTextReaderRead(reader) &&
xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
{ {
const char *str; const char *str;
u_int32_t id; u_int32_t id;
status_t status;
str = xmlTextReaderConstValue(reader); str = xmlTextReaderConstValue(reader);
if (str == NULL || !(id = atoi(str))) if (str == NULL || !(id = atoi(str)))
{ {
DBG1(DBG_CFG, "error parsing XML id string"); DBG1(DBG_CFG, "error parsing XML id string");
break; return;
} }
DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id); DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id);
/* <log> */
xmlTextWriterStartElement(writer, "log");
if (ike) if (ike)
{ {
charon->interfaces->terminate_ike(charon->interfaces, status = charon->interfaces->terminate_ike(
id, interface_manager_cb_empty, NULL); charon->interfaces, id,
(interface_manager_cb_t)xml_callback, writer);
} }
else else
{ {
charon->interfaces->terminate_child(charon->interfaces, status = charon->interfaces->terminate_child(
id, interface_manager_cb_empty, NULL); 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)
{
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
{
while (iterator->iterate(iterator, (void**)&child))
{
if (streq(child->get_name(child), str))
{
child->get_ref(child);
break; 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); request_query_ikesa(reader, writer);
break; break;
} }
if (streq(xmlTextReaderConstName(reader), "configlist"))
{
request_query_config(reader, writer);
break;
}
} }
} }
/* </query> */ /* </query> */
@ -369,6 +532,16 @@ static void request_control(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
request_control_terminate(reader, writer, FALSE); request_control_terminate(reader, writer, FALSE);
break; 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> */ /* </control> */

View File

@ -36,6 +36,9 @@
<optional> <optional>
<ref name="QueryRequestIkesa"/> <ref name="QueryRequestIkesa"/>
</optional> </optional>
<optional>
<ref name="QueryRequestConfig"/>
</optional>
<!-- others --> <!-- others -->
</element> </element>
</optional> </optional>
@ -47,6 +50,12 @@
<optional> <optional>
<ref name="ControlRequestChildTerminate"/> <ref name="ControlRequestChildTerminate"/>
</optional> </optional>
<optional>
<ref name="ControlRequestIkeInitiate"/>
</optional>
<optional>
<ref name="ControlRequestChildInitiate"/>
</optional>
<!-- others --> <!-- others -->
</element> </element>
</optional> </optional>
@ -59,14 +68,26 @@
<choice> <choice>
<element name="error"> <element name="error">
<attribute name="code"> <attribute name="code">
<data type="string"/> <data type="nonNegativeInteger"/>
</attribute> </attribute>
<data type="string"/>
</element> </element>
<group> <group>
<optional> <optional>
<element name="query"> <element name="query">
<optional> <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> </optional>
<!-- others --> <!-- others -->
</element> </element>
@ -79,7 +100,7 @@
</element> </element>
</start> </start>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- IKE SA query --> <!-- Query -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<define name="QueryRequestIkesa"> <define name="QueryRequestIkesa">
<element name="ikesalist"> <element name="ikesalist">
@ -175,30 +196,102 @@
<define name="childEnd"> <define name="childEnd">
<element name="spi"> <element name="spi">
<element name="networks"> <element name="networks">
<ref name="networks">
</element>
</define>
<define name="QueryRequestConfig">
<element name="configlist">
<empty/>
</element>
</define>
<define name="QueryResponseConfig">
<element name="configlist">
<zeroOrMore> <zeroOrMore>
<element name="network"> <element name="peerconfig">
<optional> <element name="name">
<attribute name="protocol"/> <data type="string"/>
</optional> </element>
<optional> <element name="local">
<attribute name="port"/> <ref name="identification"/>
</optional> </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> </element>
</zeroOrMore> </zeroOrMore>
</element> </element>
</define> </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"> <define name="ControlRequestIkeTerminate">
<element name="ikesaterminate"> <element name="ikesaterminate">
<element name="id">
<data type="positiveInteger"/> <data type="positiveInteger"/>
</element> </element>
</element>
</define> </define>
<define name="ControlRequestChildTerminate"> <define name="ControlRequestChildTerminate">
<element name="childsaterminate"> <element name="childsaterminate">
<element name="id">
<data type="positiveInteger"/> <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> </element>
</define> </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> <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> </data>
</define> </define>
<define name="networks">
<zeroOrMore>
<element name="network">
<optional>
<attribute name="protocol"/>
</optional>
<optional>
<attribute name="port"/>
</optional>
</element>
</zeroOrMore>
</define>
</grammar> </grammar>