handle zero size Base64 conversions
[strongswan.git] / src / libcharon / plugins / tnccs_11 / messages / tnccs_recommendation_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_recommendation_msg.h"
17 #include "tnccs_error_msg.h"
18
19 #include <debug.h>
20
21 typedef struct private_tnccs_recommendation_msg_t private_tnccs_recommendation_msg_t;
22
23 /**
24 * Private data of a tnccs_recommendation_msg_t object.
25 *
26 */
27 struct private_tnccs_recommendation_msg_t {
28 /**
29 * Public tnccs_recommendation_msg_t interface.
30 */
31 tnccs_recommendation_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 * Action Recommendation
45 */
46 TNC_IMV_Action_Recommendation rec;
47 };
48
49 METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t,
50 private_tnccs_recommendation_msg_t *this)
51 {
52 return this->type;
53 }
54
55 METHOD(tnccs_msg_t, get_node, xmlNodePtr,
56 private_tnccs_recommendation_msg_t *this)
57 {
58 return this->node;
59 }
60
61 METHOD(tnccs_msg_t, destroy, void,
62 private_tnccs_recommendation_msg_t *this)
63 {
64 free(this);
65 }
66
67 METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommendation,
68 private_tnccs_recommendation_msg_t *this)
69 {
70 return this->rec;
71 }
72
73 /**
74 * See header
75 */
76 tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
77 linked_list_t *errors)
78 {
79 private_tnccs_recommendation_msg_t *this;
80 xmlChar *rec_string;
81 char *error_msg, buf[BUF_LEN];
82 tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
83 tnccs_msg_t *msg;
84
85 INIT(this,
86 .public = {
87 .tnccs_msg_interface = {
88 .get_type = _get_type,
89 .get_node = _get_node,
90 .destroy = _destroy,
91 },
92 .get_recommendation = _get_recommendation,
93 },
94 .type = TNCCS_MSG_RECOMMENDATION,
95 .node = node,
96 );
97
98 rec_string = xmlGetProp(node, (const xmlChar*)"type");
99 if (!rec_string)
100 {
101 error_msg = "type property in TNCCS-Recommendation is missing";
102 goto fatal;
103 }
104 else if (streq((char*)rec_string, "allow"))
105 {
106 this->rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW;
107 }
108 else if (streq((char*)rec_string, "isolate"))
109 {
110 this->rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE;
111 }
112 else if (streq((char*)rec_string, "none"))
113 {
114 this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS;
115 }
116 else
117 {
118 error_msg = buf;
119 snprintf(buf, BUF_LEN, "unsupported type property value '%s' "
120 "in TNCCS-Recommendation", rec_string);
121 xmlFree(rec_string);
122 goto fatal;
123 }
124 xmlFree(rec_string);
125
126 return &this->public.tnccs_msg_interface;
127
128 fatal:
129 msg = tnccs_error_msg_create(error_type, error_msg);
130 errors->insert_last(errors, msg);
131 _destroy(this);
132 return NULL;
133 }
134
135 /**
136 * See header
137 */
138 tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec)
139 {
140 private_tnccs_recommendation_msg_t *this;
141 xmlNodePtr n, n2;
142 char *rec_string;
143
144 INIT(this,
145 .public = {
146 .tnccs_msg_interface = {
147 .get_type = _get_type,
148 .get_node = _get_node,
149 .destroy = _destroy,
150 },
151 .get_recommendation = _get_recommendation,
152 },
153 .type = TNCCS_MSG_RECOMMENDATION,
154 .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"),
155 .rec = rec,
156 );
157
158 /* add the message type number in hex */
159 n = xmlNewNode(NULL, BAD_CAST "Type");
160 xmlNodeSetContent(n, BAD_CAST "00000001");
161 xmlAddChild(this->node, n);
162
163 n = xmlNewNode(NULL, BAD_CAST "XML");
164 xmlAddChild(this->node, n);
165
166 switch (rec)
167 {
168 case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
169 rec_string = "allow";
170 break;
171 case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
172 rec_string = "isolate";
173 break;
174 case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
175 case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
176 default:
177 rec_string = "none";
178 }
179
180 n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
181 xmlNodeSetContent(n2, BAD_CAST rec_string);
182 xmlAddChild(n, n2);
183
184 return &this->public.tnccs_msg_interface;
185 }