cleaned up XML code in tnccs-11 plugin
[strongswan.git] / src / libcharon / plugins / tnccs_11 / messages / tnccs_reason_strings_msg.c
1 /*
2 * Copyright (C) 2006 Mike McCauley (mikem@open.com.au)
3 * Copyright (C) 2010 Andreas Steffen, 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 "tnccs_reason_strings_msg.h"
17 #include "tnccs_error_msg.h"
18
19 #include <utils/debug.h>
20
21 typedef struct private_tnccs_reason_strings_msg_t private_tnccs_reason_strings_msg_t;
22
23 /**
24 * Private data of a tnccs_reason_strings_msg_t object.
25 *
26 */
27 struct private_tnccs_reason_strings_msg_t {
28 /**
29 * Public tnccs_reason_strings_msg_t interface.
30 */
31 tnccs_reason_strings_msg_t public;
32
33 /**
34 * TNCCS message type
35 */
36 tnccs_msg_type_t type;
37
38 /**
39 * XML-encoded message node
40 */
41 xmlNodePtr node;
42
43 /**
44 * Reason String
45 */
46 chunk_t reason;
47
48 /**
49 * Reason Language
50 */
51 chunk_t language;
52 };
53
54 METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
55 private_tnccs_reason_strings_msg_t *this)
56 {
57 return this->type;
58 }
59
60 METHOD(tnccs_msg_t, get_node, xmlNodePtr,
61 private_tnccs_reason_strings_msg_t *this)
62 {
63 return this->node;
64 }
65
66 METHOD(tnccs_msg_t, destroy, void,
67 private_tnccs_reason_strings_msg_t *this)
68 {
69 free(this->reason.ptr);
70 free(this->language.ptr);
71 free(this);
72 }
73
74 METHOD(tnccs_reason_strings_msg_t, get_reason, chunk_t,
75 private_tnccs_reason_strings_msg_t *this, chunk_t *language)
76 {
77 *language = this->language;
78
79 return this->reason;
80 }
81
82 /**
83 * See header
84 */
85 tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
86 linked_list_t *errors)
87 {
88 private_tnccs_reason_strings_msg_t *this;
89 char *error_msg, *lang_string, *reason_string;
90 tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
91 tnccs_msg_t *msg;
92 xmlNodePtr child;
93
94 INIT(this,
95 .public = {
96 .tnccs_msg_interface = {
97 .get_type = _get_type,
98 .get_node = _get_node,
99 .destroy = _destroy,
100 },
101 .get_reason = _get_reason,
102 },
103 .type = TNCCS_MSG_REASON_STRINGS,
104 .node = node,
105 );
106
107 if (xmlStrcmp(node->name, "TNCCS-ReasonStrings"))
108 {
109 error_msg = "TNCCS-ReasonStrings tag expected";
110 goto fatal;
111 }
112
113 child = node->xmlChildrenNode;
114 while (child)
115 {
116 if (xmlIsBlankNode(child))
117 {
118 child = child->next;
119 continue;
120 }
121 if (xmlStrcmp(child->name, "ReasonString"))
122 {
123 error_msg = "ReasonString tag expected";
124 goto fatal;
125 }
126 break;
127 }
128
129 lang_string = xmlGetProp(child, "lang");
130 if (!lang_string)
131 {
132 lang_string = strdup("");
133 }
134 this->language = chunk_clone(chunk_from_str(lang_string));
135 xmlFree(lang_string);
136
137 reason_string = xmlNodeGetContent(child);
138 this->reason = chunk_clone(chunk_from_str(reason_string));
139 xmlFree(reason_string);
140
141 return &this->public.tnccs_msg_interface;
142
143 fatal:
144 msg = tnccs_error_msg_create(error_type, error_msg);
145 errors->insert_last(errors, msg);
146 destroy(this);
147 return NULL;
148 }
149
150 /**
151 * See header
152 */
153 tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language)
154 {
155 private_tnccs_reason_strings_msg_t *this;
156 xmlNodePtr n, n2, n3;
157
158 INIT(this,
159 .public = {
160 .tnccs_msg_interface = {
161 .get_type = _get_type,
162 .get_node = _get_node,
163 .destroy = _destroy,
164 },
165 .get_reason = _get_reason,
166 },
167 .type = TNCCS_MSG_REASON_STRINGS,
168 .node = xmlNewNode(NULL, "TNCC-TNCS-Message"),
169 .reason = chunk_create_clone(malloc(reason.len + 1), reason),
170 .language = chunk_create_clone(malloc(language.len + 1), language),
171 );
172
173 /* add NULL termination for XML string representation */
174 this->reason.ptr[this->reason.len] = '\0';
175 this->language.ptr[this->language.len] = '\0';
176
177 /* add the message type number in hex */
178 n = xmlNewNode(NULL, "Type");
179 xmlNodeSetContent(n, "00000004");
180 xmlAddChild(this->node, n);
181
182 n = xmlNewNode(NULL, "XML");
183 xmlAddChild(this->node, n);
184
185 n2 = xmlNewNode(NULL, enum_to_name(tnccs_msg_type_names, this->type));
186
187 /* could add multiple reasons here, if we had them */
188
189 n3 = xmlNewNode(NULL, "ReasonString");
190 xmlNewProp(n3, "xml:lang", this->language.ptr);
191 xmlNodeSetContent(n3, this->reason.ptr);
192 xmlAddChild(n2, n3);
193 xmlAddChild(n, n2);
194
195 return &this->public.tnccs_msg_interface;
196 }