updated XML interface to new schema
This commit is contained in:
@@ -39,8 +39,6 @@
|
||||
#include <daemon.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
|
||||
static struct sockaddr_un socket_addr = { AF_UNIX, "/var/run/charon.xml"};
|
||||
|
||||
|
||||
typedef struct private_xml_interface_t private_xml_interface_t;
|
||||
|
||||
@@ -65,27 +63,231 @@ struct private_xml_interface_t {
|
||||
callback_job_t *job;
|
||||
};
|
||||
|
||||
ENUM(ike_sa_state_lower_names, IKE_CREATED, IKE_DELETING,
|
||||
"created",
|
||||
"connecting",
|
||||
"established",
|
||||
"rekeying",
|
||||
"deleting",
|
||||
);
|
||||
|
||||
/**
|
||||
* process a getRequest message
|
||||
* write a bool into element
|
||||
*/
|
||||
static void process_get(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
|
||||
static void write_bool(xmlTextWriterPtr writer, char *element, bool val)
|
||||
{
|
||||
if (/* <GetResponse> */
|
||||
xmlTextWriterStartElement(writer, "GetResponse") < 0 ||
|
||||
/* <Status Code="200"><Message/></Status> */
|
||||
xmlTextWriterStartElement(writer, "Status") < 0 ||
|
||||
xmlTextWriterWriteAttribute(writer, "Code", "200") < 0 ||
|
||||
xmlTextWriterStartElement(writer, "Message") < 0 ||
|
||||
xmlTextWriterEndElement(writer) < 0 ||
|
||||
xmlTextWriterEndElement(writer) < 0 ||
|
||||
/* <ConnectionList/> */
|
||||
xmlTextWriterStartElement(writer, "ConnectionList") < 0 ||
|
||||
xmlTextWriterEndElement(writer) < 0 ||
|
||||
/* </GetResponse> */
|
||||
xmlTextWriterEndElement(writer) < 0)
|
||||
xmlTextWriterWriteElement(writer, element, val ? "true" : "false");
|
||||
}
|
||||
|
||||
/**
|
||||
* write a identification_t into element
|
||||
*/
|
||||
static void write_id(xmlTextWriterPtr writer, char *element, identification_t *id)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, element);
|
||||
switch (id->get_type(id))
|
||||
{
|
||||
DBG1(DBG_CFG, "error writing XML document (GetResponse)");
|
||||
{
|
||||
char *type = "";
|
||||
while (TRUE)
|
||||
{
|
||||
case ID_IPV4_ADDR:
|
||||
type = "ipv4";
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
type = "ipv6";
|
||||
break;
|
||||
case ID_FQDN:
|
||||
type = "fqdn";
|
||||
break;
|
||||
case ID_RFC822_ADDR:
|
||||
type = "email";
|
||||
break;
|
||||
case ID_DER_ASN1_DN:
|
||||
type = "asn1dn";
|
||||
break;
|
||||
case ID_DER_ASN1_GN:
|
||||
type = "asn1gn";
|
||||
break;
|
||||
}
|
||||
xmlTextWriterWriteAttribute(writer, "type", type);
|
||||
xmlTextWriterWriteFormatString(writer, "%D", id);
|
||||
break;
|
||||
}
|
||||
case ID_ANY:
|
||||
xmlTextWriterWriteAttribute(writer, "type", "any");
|
||||
break;
|
||||
default:
|
||||
/* TODO: base64 keyid */
|
||||
xmlTextWriterWriteAttribute(writer, "type", "keyid");
|
||||
break;
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* write a host_t address into an element
|
||||
*/
|
||||
static void write_address(xmlTextWriterPtr writer, char *element, host_t *host)
|
||||
{
|
||||
xmlTextWriterStartElement(writer, element);
|
||||
xmlTextWriterWriteAttribute(writer, "type",
|
||||
host->get_family(host) == AF_INET ? "ipv4" : "ipv6");
|
||||
if (host->is_anyaddr(host))
|
||||
{ /* do not use %any for XML */
|
||||
xmlTextWriterWriteFormatString(writer, "%s",
|
||||
host->get_family(host) == AF_INET ? "0.0.0.0" : "::");
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlTextWriterWriteFormatString(writer, "%H", host);
|
||||
}
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* process a ikesalist query request message
|
||||
*/
|
||||
static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
ike_sa_t *ike_sa;
|
||||
|
||||
/* <ikesalist> */
|
||||
xmlTextWriterStartElement(writer, "ikesalist");
|
||||
|
||||
iterator = charon->ike_sa_manager->create_iterator(charon->ike_sa_manager);
|
||||
while (iterator->iterate(iterator, (void**)&ike_sa))
|
||||
{
|
||||
ike_sa_id_t *id;
|
||||
host_t *local, *remote;
|
||||
iterator_t *children;
|
||||
child_sa_t *child_sa;
|
||||
|
||||
id = ike_sa->get_id(ike_sa);
|
||||
|
||||
xmlTextWriterStartElement(writer, "ikesa");
|
||||
xmlTextWriterWriteFormatElement(writer, "id", "%d",
|
||||
ike_sa->get_unique_id(ike_sa));
|
||||
xmlTextWriterWriteFormatElement(writer, "status", "%N",
|
||||
ike_sa_state_lower_names, ike_sa->get_state(ike_sa));
|
||||
xmlTextWriterWriteElement(writer, "role",
|
||||
id->is_initiator(id) ? "initiator" : "responder");
|
||||
xmlTextWriterWriteElement(writer, "peerconfig", ike_sa->get_name(ike_sa));
|
||||
|
||||
/* <local> */
|
||||
local = ike_sa->get_my_host(ike_sa);
|
||||
xmlTextWriterStartElement(writer, "local");
|
||||
xmlTextWriterWriteFormatElement(writer, "spi", "%.16llx",
|
||||
id->is_initiator(id) ? id->get_initiator_spi(id)
|
||||
: id->get_responder_spi(id));
|
||||
write_id(writer, "identification", ike_sa->get_my_id(ike_sa));
|
||||
write_address(writer, "address", local);
|
||||
xmlTextWriterWriteFormatElement(writer, "port", "%d",
|
||||
local->get_port(local));
|
||||
if (ike_sa->supports_extension(ike_sa, EXT_NATT))
|
||||
{
|
||||
write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_HERE));
|
||||
}
|
||||
/* </local> */
|
||||
|
||||
/* <remote> */
|
||||
remote = ike_sa->get_other_host(ike_sa);
|
||||
xmlTextWriterStartElement(writer, "remote");
|
||||
xmlTextWriterWriteFormatElement(writer, "spi", "%.16llx",
|
||||
id->is_initiator(id) ? id->get_responder_spi(id)
|
||||
: id->get_initiator_spi(id));
|
||||
write_id(writer, "identification", ike_sa->get_other_id(ike_sa));
|
||||
write_address(writer, "address", remote);
|
||||
xmlTextWriterWriteFormatElement(writer, "port", "%d",
|
||||
remote->get_port(remote));
|
||||
if (ike_sa->supports_extension(ike_sa, EXT_NATT))
|
||||
{
|
||||
write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_THERE));
|
||||
}
|
||||
/* </remote> */
|
||||
|
||||
/* <childsalist> */
|
||||
xmlTextWriterStartElement(writer, "childsalist");
|
||||
children = ike_sa->create_child_sa_iterator(ike_sa);
|
||||
while (children->iterate(children, (void**)&child_sa))
|
||||
{
|
||||
/* TODO: Children */
|
||||
}
|
||||
children->destroy(children);
|
||||
/* </childsalist> */
|
||||
xmlTextWriterEndElement(writer);
|
||||
|
||||
/* </ikesa> */
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* </ikesalist> */
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* process a query request
|
||||
*/
|
||||
static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
|
||||
{
|
||||
/* <query> */
|
||||
xmlTextWriterStartElement(writer, "query");
|
||||
while (xmlTextReaderRead(reader))
|
||||
{
|
||||
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
if (streq(xmlTextReaderConstName(reader), "ikesalist"))
|
||||
{
|
||||
request_query_ikesa(reader, writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* </query> */
|
||||
xmlTextWriterEndElement(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* process a request message
|
||||
*/
|
||||
static void request(xmlTextReaderPtr reader, char *id, int fd)
|
||||
{
|
||||
xmlTextWriterPtr writer;
|
||||
|
||||
writer = xmlNewTextWriter(xmlOutputBufferCreateFd(fd, NULL));
|
||||
if (writer == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "opening SMP XML writer failed");
|
||||
return;
|
||||
}
|
||||
|
||||
xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
|
||||
/* <message xmlns="http://www.strongswan.org/smp/1.0"
|
||||
id="id" type="response"> */
|
||||
xmlTextWriterStartElement(writer, "message");
|
||||
xmlTextWriterWriteAttribute(writer, "xmlns",
|
||||
"http://www.strongswan.org/smp/1.0");
|
||||
xmlTextWriterWriteAttribute(writer, "id", id);
|
||||
xmlTextWriterWriteAttribute(writer, "type", "response");
|
||||
|
||||
while (xmlTextReaderRead(reader))
|
||||
{
|
||||
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
if (streq(xmlTextReaderConstName(reader), "query"))
|
||||
{
|
||||
request_query(reader, writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* </message> and close document */
|
||||
xmlTextWriterEndDocument(writer);
|
||||
xmlFreeTextWriter(writer);
|
||||
/* write a newline to indicate end of xml */
|
||||
write(fd, "\n", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,11 +299,13 @@ static job_requeue_t process(int *fdp)
|
||||
char buffer[4096];
|
||||
size_t len;
|
||||
xmlTextReaderPtr reader;
|
||||
xmlTextWriterPtr writer;
|
||||
char *id = NULL, *type = NULL;
|
||||
|
||||
pthread_cleanup_push((void*)close, (void*)fd);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
len = read(fd, buffer, sizeof(buffer));
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
pthread_cleanup_pop(0);
|
||||
if (len <= 0)
|
||||
{
|
||||
close(fd);
|
||||
@@ -116,65 +320,32 @@ static job_requeue_t process(int *fdp)
|
||||
return JOB_REQUEUE_FAIR;;
|
||||
}
|
||||
|
||||
writer = xmlNewTextWriter(xmlOutputBufferCreateFd(fd, NULL));
|
||||
if (writer == NULL)
|
||||
{
|
||||
xmlFreeTextReader(reader);
|
||||
DBG1(DBG_CFG, "opening SMP XML writer failed");
|
||||
return JOB_REQUEUE_FAIR;;
|
||||
}
|
||||
|
||||
/* create the standard message parts */
|
||||
if (xmlTextWriterStartDocument(writer, NULL, NULL, NULL) < 0 ||
|
||||
/* <SMPMessage xmlns="http://www.strongswan.org/smp/1.0"> */
|
||||
xmlTextWriterStartElement(writer, "SMPMessage") < 0 ||
|
||||
xmlTextWriterWriteAttribute(writer, "xmlns",
|
||||
"http://www.strongswan.org/smp/1.0") < 0 ||
|
||||
/* <Body> */
|
||||
xmlTextWriterStartElement(writer, "Body") < 0)
|
||||
{
|
||||
xmlFreeTextReader(reader);
|
||||
xmlFreeTextWriter(writer);
|
||||
DBG1(DBG_CFG, "creating SMP XML message failed");
|
||||
return JOB_REQUEUE_FAIR;;
|
||||
}
|
||||
|
||||
while (TRUE)
|
||||
/* read message type and id */
|
||||
while (xmlTextReaderRead(reader))
|
||||
{
|
||||
switch (xmlTextReaderRead(reader))
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
|
||||
{
|
||||
if (streq(xmlTextReaderConstName(reader), "GetRequest"))
|
||||
{
|
||||
process_get(reader, writer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case 0:
|
||||
/* end of XML */
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_CFG, "parsing SMP XML message failed");
|
||||
break;
|
||||
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT &&
|
||||
streq(xmlTextReaderConstName(reader), "message"))
|
||||
{
|
||||
id = xmlTextReaderGetAttribute(reader, "id");
|
||||
type = xmlTextReaderGetAttribute(reader, "type");
|
||||
break;
|
||||
}
|
||||
xmlFreeTextReader(reader);
|
||||
break;
|
||||
}
|
||||
/* write </Body></SMPMessage> and close document */
|
||||
if (xmlTextWriterEndDocument(writer) < 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "completing SMP XML message failed");
|
||||
}
|
||||
xmlFreeTextWriter(writer);
|
||||
|
||||
/* write a newline to indicate end of xml */
|
||||
write(fd, "\n", 1);
|
||||
return JOB_REQUEUE_FAIR;;
|
||||
/* process message */
|
||||
if (id && type)
|
||||
{
|
||||
if (streq(type, "request"))
|
||||
{
|
||||
request(reader, id, fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* response(reader, id) */
|
||||
}
|
||||
}
|
||||
xmlFreeTextReader(reader);
|
||||
return JOB_REQUEUE_FAIR;;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,13 +377,16 @@ static job_requeue_t dispatch(private_xml_interface_t *this)
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
|
||||
struct sockaddr_un unix_addr = { AF_UNIX, "/var/run/charon.xml"};
|
||||
|
||||
/**
|
||||
* Implementation of itnerface_t.destroy.
|
||||
*/
|
||||
static void destroy(private_xml_interface_t *this)
|
||||
{
|
||||
this->job->cancel(this->job);
|
||||
unlink(socket_addr.sun_path);
|
||||
close(this->socket);
|
||||
//unlink(unix_addr.sun_path);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -222,12 +396,13 @@ static void destroy(private_xml_interface_t *this)
|
||||
interface_t *interface_create()
|
||||
{
|
||||
private_xml_interface_t *this = malloc_thing(private_xml_interface_t);
|
||||
mode_t old;
|
||||
//mode_t old;
|
||||
struct sockaddr_in tcp_addr;
|
||||
|
||||
this->public.interface.destroy = (void (*)(interface_t*))destroy;
|
||||
|
||||
/* set up unix socket */
|
||||
this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
this->socket = socket(AF_INET, SOCK_STREAM, 0);//socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (this->socket == -1)
|
||||
{
|
||||
DBG1(DBG_CFG, "could not create XML socket");
|
||||
@@ -235,6 +410,19 @@ interface_t *interface_create()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&tcp_addr, 0, sizeof(tcp_addr));
|
||||
tcp_addr.sin_family = AF_INET;
|
||||
tcp_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
tcp_addr.sin_port = htons(4502);
|
||||
if (bind(this->socket, (struct sockaddr*)&tcp_addr, sizeof(tcp_addr)) < 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "could not bind XML socket: %s", strerror(errno));
|
||||
close(this->socket);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
old = umask(~S_IRWXU);
|
||||
if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
|
||||
{
|
||||
@@ -243,9 +431,9 @@ interface_t *interface_create()
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
umask(old);
|
||||
umask(old);*/
|
||||
|
||||
if (listen(this->socket, 0) < 0)
|
||||
if (listen(this->socket, 5) < 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "could not listen on XML socket: %s", strerror(errno));
|
||||
close(this->socket);
|
||||
|
||||
@@ -931,7 +931,7 @@ static int print(FILE *stream, const struct printf_info *info,
|
||||
case ID_FQDN:
|
||||
{
|
||||
proper = sanitize_chunk(this->encoded);
|
||||
written = fprintf(stream, "@%.*s", proper.len, proper.ptr);
|
||||
written = fprintf(stream, "%.*s", proper.len, proper.ptr);
|
||||
chunk_free(&proper);
|
||||
return written;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user