removed superfluous whitespace
[strongswan.git] / src / libcharon / plugins / tnccs_20 / messages / pb_pa_message.c
1 /*
2 * Copyright (C) 2010 Sansar Choinyanbuu
3 * Copyright (C) 2010 Andreas Steffen
4 *
5 * HSR Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "pb_pa_message.h"
19
20 #include <tls_writer.h>
21 #include <tls_reader.h>
22 #include <debug.h>
23
24 typedef struct private_pb_pa_message_t private_pb_pa_message_t;
25
26 /**
27 * PB-PA message
28 *
29 * 0 1 2 3
30 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Flags | PA Message Vendor ID |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | PA Subtype |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | Posture Collector Identifier | Posture Validator Identifier |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | PA Message Body (Variable Length) |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 */
41
42 #define PA_FLAG_NONE 0x00
43 #define PA_FLAG_EXCL (1<<7)
44
45 #define PB_PA_HEADER_SIZE 12
46
47 /**
48 * Private data of a pb_pa_message_t object.
49 *
50 */
51 struct private_pb_pa_message_t {
52 /**
53 * Public pb_pa_message_t interface.
54 */
55 pb_pa_message_t public;
56
57 /**
58 * PB-TNC message type
59 */
60 pb_tnc_msg_type_t type;
61
62 /**
63 * Exclusive flag
64 */
65 bool excl;
66
67 /**
68 * PA Message Vendor ID
69 */
70 u_int32_t vendor_id;
71
72 /**
73 * PA Subtype
74 */
75 u_int32_t subtype;
76
77 /**
78 * Posture Validator Identifier
79 */
80 u_int16_t collector_id;
81
82 /**
83 * Posture Validator Identifier
84 */
85 u_int16_t validator_id;
86
87 /**
88 * PA Message Body
89 */
90 chunk_t msg_body;
91
92 /**
93 * Encoded message
94 */
95 chunk_t encoding;
96 };
97
98 METHOD(pb_tnc_message_t, get_type, pb_tnc_msg_type_t,
99 private_pb_pa_message_t *this)
100 {
101 return this->type;
102 }
103
104 METHOD(pb_tnc_message_t, get_encoding, chunk_t,
105 private_pb_pa_message_t *this)
106 {
107 return this->encoding;
108 }
109
110 METHOD(pb_tnc_message_t, build, void,
111 private_pb_pa_message_t *this)
112 {
113 chunk_t msg_header;
114 tls_writer_t *writer;
115
116 /* build message header */
117 writer = tls_writer_create(PB_PA_HEADER_SIZE);
118 writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
119 writer->write_uint24(writer, this->vendor_id);
120 writer->write_uint32(writer, this->subtype);
121 writer->write_uint16(writer, this->collector_id);
122 writer->write_uint16(writer, this->validator_id);
123 msg_header = writer->get_buf(writer);
124
125 /* create encoding by concatenating message header and message body */
126 free(this->encoding.ptr);
127 this->encoding = chunk_cat("cc", msg_header, this->msg_body);
128 writer->destroy(writer);
129 }
130
131 METHOD(pb_tnc_message_t, process, status_t,
132 private_pb_pa_message_t *this)
133 {
134 u_int8_t flags;
135 size_t msg_body_len;
136 tls_reader_t *reader;
137
138 if (this->encoding.len < PB_PA_HEADER_SIZE)
139 {
140 DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
141 pb_tnc_msg_type_names, PB_MSG_PA, PB_PA_HEADER_SIZE);
142 return FAILED;
143 }
144
145 /* process message header */
146 reader = tls_reader_create(this->encoding);
147 reader->read_uint8 (reader, &flags);
148 reader->read_uint24(reader, &this->vendor_id);
149 reader->read_uint32(reader, &this->subtype);
150 reader->read_uint16(reader, &this->collector_id);
151 reader->read_uint16(reader, &this->validator_id);
152 this->excl = ((flags & PA_FLAG_EXCL) != PA_FLAG_NONE);
153
154 /* process message body */
155 msg_body_len = reader->remaining(reader);
156 if (msg_body_len)
157 {
158 reader->read_data(reader, msg_body_len, &this->msg_body);
159 this->msg_body = chunk_clone(this->msg_body);
160 }
161 reader->destroy(reader);
162 return SUCCESS;
163 }
164
165 METHOD(pb_tnc_message_t, destroy, void,
166 private_pb_pa_message_t *this)
167 {
168 free(this->encoding.ptr);
169 free(this->msg_body.ptr);
170 free(this);
171 }
172
173 METHOD(pb_pa_message_t, get_vendor_id, u_int32_t,
174 private_pb_pa_message_t *this, u_int32_t *subtype)
175 {
176 *subtype = this->subtype;
177 return this->vendor_id;
178 }
179
180 METHOD(pb_pa_message_t, get_collector_id, u_int16_t,
181 private_pb_pa_message_t *this)
182 {
183 return this->collector_id;
184 }
185
186 METHOD(pb_pa_message_t, get_validator_id, u_int16_t,
187 private_pb_pa_message_t *this)
188 {
189 return this->validator_id;
190 }
191
192 METHOD(pb_pa_message_t, get_body, chunk_t,
193 private_pb_pa_message_t *this)
194 {
195 return this->msg_body;
196 }
197
198 METHOD(pb_pa_message_t, get_exclusive_flag, bool,
199 private_pb_pa_message_t *this)
200 {
201 return this->excl;
202 }
203
204 METHOD(pb_pa_message_t, set_exclusive_flag, void,
205 private_pb_pa_message_t *this, bool excl)
206 {
207 this->excl = excl;
208 }
209
210 /**
211 * See header
212 */
213 pb_tnc_message_t *pb_pa_message_create_from_data(chunk_t data)
214 {
215 private_pb_pa_message_t *this;
216
217 INIT(this,
218 .public = {
219 .pb_interface = {
220 .get_type = _get_type,
221 .get_encoding = _get_encoding,
222 .process = _process,
223 .destroy = _destroy,
224 },
225 .get_vendor_id = _get_vendor_id,
226 .get_collector_id = _get_collector_id,
227 .get_validator_id = _get_validator_id,
228 .get_body = _get_body,
229 .get_exclusive_flag = _get_exclusive_flag,
230 .set_exclusive_flag = _set_exclusive_flag,
231 },
232 .type = PB_MSG_PA,
233 .encoding = chunk_clone(data),
234 );
235
236 return &this->public.pb_interface;
237 }
238
239 /**
240 * See header
241 */
242 pb_tnc_message_t *pb_pa_message_create(u_int32_t vendor_id, u_int32_t subtype,
243 u_int16_t collector_id,
244 u_int16_t validator_id,
245 chunk_t msg_body)
246 {
247 private_pb_pa_message_t *this;
248
249 INIT(this,
250 .public = {
251 .pb_interface = {
252 .get_type = _get_type,
253 .get_encoding = _get_encoding,
254 .build = _build,
255 .process = _process,
256 .destroy = _destroy,
257 },
258 .get_vendor_id = _get_vendor_id,
259 .get_collector_id = _get_collector_id,
260 .get_validator_id = _get_validator_id,
261 .get_body = _get_body,
262 .get_exclusive_flag = _get_exclusive_flag,
263 .set_exclusive_flag = _set_exclusive_flag,
264 },
265 .type = PB_MSG_PA,
266 .vendor_id = vendor_id,
267 .subtype = subtype,
268 .collector_id = collector_id,
269 .validator_id = validator_id,
270 .msg_body = chunk_clone(msg_body),
271 );
272
273 return &this->public.pb_interface;
274 }