handle zero size Base64 conversions
[strongswan.git] / src / libcharon / plugins / tnccs_11 / messages / tnccs_error_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_error_msg.h"
17
18 #include <debug.h>
19
20 ENUM(tnccs_error_type_names, TNCCS_ERROR_BATCH_TOO_LONG, TNCCS_ERROR_OTHER,
21 "batch-too-long",
22 "malformed-batch",
23 "invalid-batch-id",
24 "invalid-recipient-type",
25 "internal-error",
26 "other"
27 );
28
29 typedef struct private_tnccs_error_msg_t private_tnccs_error_msg_t;
30
31 /**
32 * Private data of a tnccs_error_msg_t object.
33 *
34 */
35 struct private_tnccs_error_msg_t {
36 /**
37 * Public tnccs_error_msg_t interface.
38 */
39 tnccs_error_msg_t public;
40
41 /**
42 * TNCCS message type
43 */
44 tnccs_msg_type_t type;
45
46 /**
47 * XML-encoded message node
48 */
49 xmlNodePtr node;
50
51 /**
52 * Error type
53 */
54 tnccs_error_type_t error_type;
55
56 /**
57 * Error message
58 */
59 char *error_msg;
60
61 /**
62 * reference count
63 */
64 refcount_t ref;
65 };
66
67 METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
68 private_tnccs_error_msg_t *this)
69 {
70 return this->type;
71 }
72
73 METHOD(tnccs_msg_t, get_node, xmlNodePtr,
74 private_tnccs_error_msg_t *this)
75 {
76 return this->node;
77 }
78
79 METHOD(tnccs_msg_t, get_ref, tnccs_msg_t*,
80 private_tnccs_error_msg_t *this)
81 {
82 ref_get(&this->ref);
83 return &this->public.tnccs_msg_interface;
84 }
85
86 METHOD(tnccs_msg_t, destroy, void,
87 private_tnccs_error_msg_t *this)
88 {
89 if (ref_put(&this->ref))
90 {
91 free(this->error_msg);
92 free(this);
93 }
94 }
95
96 METHOD(tnccs_error_msg_t, get_message, char*,
97 private_tnccs_error_msg_t *this, tnccs_error_type_t *type)
98 {
99 *type = this->error_type;
100
101 return this->error_msg;
102 }
103
104 /**
105 * See header
106 */
107 tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node)
108 {
109 private_tnccs_error_msg_t *this;
110 xmlChar *error_type_name, *error_msg;
111
112 INIT(this,
113 .public = {
114 .tnccs_msg_interface = {
115 .get_type = _get_type,
116 .get_node = _get_node,
117 .get_ref = _get_ref,
118 .destroy = _destroy,
119 },
120 .get_message = _get_message,
121 },
122 .type = TNCCS_MSG_ERROR,
123 .node = node,
124 .error_type = TNCCS_ERROR_OTHER,
125 );
126
127 error_type_name = xmlGetProp(node, (const xmlChar*)"type");
128 if (error_type_name)
129 {
130 this->error_type = enum_from_name(tnccs_error_type_names,
131 (char*)error_type_name);
132 if (this->error_type == -1)
133 {
134 this->error_type = TNCCS_ERROR_OTHER;
135 }
136 xmlFree(error_type_name);
137 }
138
139 error_msg = xmlNodeGetContent(node);
140 if (error_msg)
141 {
142 this->error_msg = strdup((char*)error_msg);
143 xmlFree(error_msg);
144 }
145
146 return &this->public.tnccs_msg_interface;
147 }
148
149 /**
150 * See header
151 */
152 tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg)
153 {
154 private_tnccs_error_msg_t *this;
155 xmlNodePtr n, n2;
156
157 INIT(this,
158 .public = {
159 .tnccs_msg_interface = {
160 .get_type = _get_type,
161 .get_node = _get_node,
162 .get_ref = _get_ref,
163 .destroy = _destroy,
164 },
165 .get_message = _get_message,
166 },
167 .type = TNCCS_MSG_ERROR,
168 .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
169 .error_type = type,
170 .error_msg = strdup(msg),
171 );
172
173 DBG1(DBG_TNC, "%s", msg);
174
175 n = xmlNewNode(NULL, BAD_CAST "Type");
176 xmlNodeSetContent(n, BAD_CAST "00000002");
177 xmlAddChild(this->node, n);
178
179 n = xmlNewNode(NULL, BAD_CAST "XML");
180 xmlAddChild(this->node, n);
181
182 n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
183 xmlNewProp(n2, BAD_CAST "type",
184 BAD_CAST enum_to_name(tnccs_error_type_names, type));
185 xmlNodeSetContent(n2, BAD_CAST msg);
186 xmlAddChild(n, n2);
187
188 return &this->public.tnccs_msg_interface;
189 }