Return to tnc_ifmap_soap_msg.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / tnc_ifmap |
1.1 misho 1: /* 2: * Copyright (C) 2013 Andreas Steffen 3: * HSR Hochschule fuer Technik Rapperswil 4: * 5: * This program is free software; you can redistribute it and/or modify it 6: * under the terms of the GNU General Public License as published by the 7: * Free Software Foundation; either version 2 of the License, or (at your 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. 9: * 10: * This program is distributed in the hope that it will be useful, but 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13: * for more details. 14: */ 15: 16: #include "tnc_ifmap_soap_msg.h" 17: #include "tnc_ifmap_http.h" 18: 19: #include <utils/debug.h> 20: 21: #define SOAP_NS "http://www.w3.org/2003/05/soap-envelope" 22: 23: typedef struct private_tnc_ifmap_soap_msg_t private_tnc_ifmap_soap_msg_t; 24: 25: /** 26: * Private data of an tnc_ifmap_soap_msg_t object. 27: */ 28: struct private_tnc_ifmap_soap_msg_t { 29: 30: /** 31: * Public tnc_ifmap_soap_msg_t interface. 32: */ 33: tnc_ifmap_soap_msg_t public; 34: 35: /** 36: * HTTP POST request builder and response processing 37: */ 38: tnc_ifmap_http_t *http; 39: 40: /** 41: * TLS socket 42: */ 43: tls_socket_t *tls; 44: 45: /** 46: * XML Document 47: */ 48: xmlDocPtr doc; 49: 50: }; 51: 52: /** 53: * Find a child node with a given name 54: */ 55: static xmlNodePtr find_child(xmlNodePtr parent, const xmlChar* name) 56: { 57: xmlNodePtr child; 58: 59: child = parent->xmlChildrenNode; 60: while (child) 61: { 62: if (xmlStrcmp(child->name, name) == 0) 63: { 64: return child; 65: } 66: child = child->next; 67: } 68: 69: DBG1(DBG_TNC, "child node \"%s\" not found", name); 70: return NULL; 71: } 72: 73: METHOD(tnc_ifmap_soap_msg_t, post, bool, 74: private_tnc_ifmap_soap_msg_t *this, xmlNodePtr request, char *result_name, 75: xmlNodePtr *result) 76: { 77: xmlDocPtr doc; 78: xmlNodePtr env, body, cur, response; 79: xmlNsPtr ns; 80: xmlChar *xml_str, *errorCode, *errorString; 81: int xml_len, len, written; 82: chunk_t xml, http; 83: char buf[4096] = { 0 }; 84: status_t status; 85: 86: DBG2(DBG_TNC, "sending ifmap %s", request->name); 87: 88: /* Generate XML Document containing SOAP Envelope */ 89: doc = xmlNewDoc("1.0"); 90: env =xmlNewNode(NULL, "Envelope"); 91: ns = xmlNewNs(env, SOAP_NS, "env"); 92: xmlSetNs(env, ns); 93: xmlDocSetRootElement(doc, env); 94: 95: /* Add SOAP Body containing IF-MAP request */ 96: body = xmlNewNode(ns, "Body"); 97: xmlAddChild(body, request); 98: xmlAddChild(env, body); 99: 100: /* Convert XML Document into a character string */ 101: xmlDocDumpFormatMemory(doc, &xml_str, &xml_len, 1); 102: xmlFreeDoc(doc); 103: DBG3(DBG_TNC, "%.*s", xml_len, xml_str); 104: xml = chunk_create(xml_str, xml_len); 105: 106: /* Send SOAP-XML request via HTTPS POST */ 107: do 108: { 109: status = this->http->build(this->http, &xml, &http); 110: if (status == FAILED) 111: { 112: break; 113: } 114: written = this->tls->write(this->tls, http.ptr, http.len); 115: free(http.ptr); 116: if (written != http.len) 117: { 118: status = FAILED; 119: break; 120: } 121: } 122: while (status == NEED_MORE); 123: 124: xmlFree(xml_str); 125: if (status != SUCCESS) 126: { 127: return FALSE; 128: } 129: 130: /* Receive SOAP-XML response via [chunked] HTTPS */ 131: xml = chunk_empty; 132: do 133: { 134: /* reduce size so the buffer is null-terminated */ 135: len = this->tls->read(this->tls, buf, sizeof(buf)-1, TRUE); 136: if (len <= 0) 137: { 138: return FALSE; 139: } 140: http = chunk_create(buf, len); 141: 142: status = this->http->process(this->http, &http, &xml); 143: if (status == FAILED) 144: { 145: free(xml.ptr); 146: return FALSE; 147: } 148: } 149: while (status == NEED_MORE); 150: 151: DBG3(DBG_TNC, "parsing XML message %B", &xml); 152: this->doc = xmlParseMemory(xml.ptr, xml.len); 153: free(xml.ptr); 154: 155: if (!this->doc) 156: { 157: DBG1(DBG_TNC, "failed to parse XML message"); 158: return FALSE; 159: } 160: 161: /* check out XML document */ 162: cur = xmlDocGetRootElement(this->doc); 163: if (!cur) 164: { 165: DBG1(DBG_TNC, "empty XML message"); 166: return FALSE; 167: } 168: 169: /* get XML Document type is a SOAP Envelope */ 170: if (xmlStrcmp(cur->name, "Envelope")) 171: { 172: DBG1(DBG_TNC, "XML message does not contain a SOAP Envelope"); 173: return FALSE; 174: } 175: 176: /* get SOAP Body */ 177: cur = find_child(cur, "Body"); 178: if (!cur) 179: { 180: return FALSE; 181: } 182: 183: /* get IF-MAP response */ 184: response = find_child(cur, "response"); 185: if (!response) 186: { 187: return FALSE; 188: } 189: 190: /* get IF-MAP result */ 191: cur = find_child(response, result_name); 192: if (!cur) 193: { 194: cur = find_child(response, "errorResult"); 195: if (cur) 196: { 197: DBG1(DBG_TNC, "received errorResult"); 198: 199: errorCode = xmlGetProp(cur, "errorCode"); 200: if (errorCode) 201: { 202: DBG1(DBG_TNC, " %s", errorCode); 203: xmlFree(errorCode); 204: } 205: 206: cur = find_child(cur, "errorString"); 207: if (cur) 208: { 209: errorString = xmlNodeGetContent(cur); 210: if (errorString) 211: { 212: DBG1(DBG_TNC, " %s", errorString); 213: xmlFree(errorString); 214: } 215: } 216: } 217: return FALSE; 218: } 219: 220: if (result) 221: { 222: *result = cur; 223: } 224: return TRUE; 225: } 226: 227: METHOD(tnc_ifmap_soap_msg_t, destroy, void, 228: private_tnc_ifmap_soap_msg_t *this) 229: { 230: this->http->destroy(this->http); 231: if (this->doc) 232: { 233: xmlFreeDoc(this->doc); 234: } 235: free(this); 236: } 237: 238: /** 239: * See header 240: */ 241: tnc_ifmap_soap_msg_t *tnc_ifmap_soap_msg_create(char *uri, chunk_t user_pass, 242: tls_socket_t *tls) 243: { 244: private_tnc_ifmap_soap_msg_t *this; 245: 246: INIT(this, 247: .public = { 248: .post = _post, 249: .destroy = _destroy, 250: }, 251: .http = tnc_ifmap_http_create(uri, user_pass), 252: .tls = tls, 253: ); 254: 255: return &this->public; 256: } 257: