1 /*****
2 *
3 * Copyright (C) 2008-2015 CS-SI. All Rights Reserved.
4 * Author: Yoann Vandoorselaere <yoann.v@prelude-ids.com>
5 *
6 * This file is part of the Prelude library.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 *****/
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "prelude.h"
28 #include "idmef-message-helpers.h"
29
30
31 /**
32 * idmef_message_set_value:
33 * @message: Pointer to an #idmef_message_t object.
34 * @path: Path to be set within @message.
35 * @value: Value to associate @message[@path] with.
36 *
37 * This function will set the @path member within @message to the
38 * provided @value.
39 *
40 * Returns: 0 on success, or a negative value if an error occured.
41 */
idmef_message_set_value(idmef_message_t * message,const char * path,idmef_value_t * value)42 int idmef_message_set_value(idmef_message_t *message, const char *path, idmef_value_t *value)
43 {
44 int ret;
45 idmef_path_t *ip;
46
47 ret = idmef_path_new_fast(&ip, path);
48 if ( ret < 0 )
49 return ret;
50
51 ret = idmef_path_set(ip, message, value);
52 idmef_path_destroy(ip);
53
54 return ret;
55 }
56
57
58
59 /**
60 * idmef_message_get_value:
61 * @message: Pointer to an #idmef_message_t object.
62 * @path: Path to retrieve the value from within @message.
63 * @value: Pointer where the result should be stored.
64 *
65 * Retrieve the value stored within @path of @message and store it
66 * in the user provided @value.
67 *
68 * Returns: A positive value in case @path was successfully retrieved
69 * 0 if the path is empty, or a negative value if an error occured.
70 */
idmef_message_get_value(idmef_message_t * message,const char * path,idmef_value_t ** value)71 int idmef_message_get_value(idmef_message_t *message, const char *path, idmef_value_t **value)
72 {
73 int ret;
74 idmef_path_t *ip;
75
76 ret = idmef_path_new_fast(&ip, path);
77 if ( ret < 0 )
78 return ret;
79
80 ret = idmef_path_get(ip, message, value);
81 idmef_path_destroy(ip);
82
83 return ret;
84 }
85
86
87
88 /**
89 * idmef_message_set_string:
90 * @message: Pointer to an #idmef_message_t object.
91 * @path: Path to be set within @message.
92 * @value: Value to associate @message[@path] with.
93 *
94 * This function will set the @path member within @message to the
95 * provided @value, which will be converted to the corresponding
96 * @path value type.
97 *
98 * Example:
99 * idmef_message_set_string(message, "alert.classification.text", "MyText");
100 * idmef_message_set_string(message, "alert.source(0).service.port", "1024");
101 *
102 * Returns: 0 on success, or a negative value if an error occured.
103 */
idmef_message_set_string(idmef_message_t * message,const char * path,const char * value)104 int idmef_message_set_string(idmef_message_t *message, const char *path, const char *value)
105 {
106 int ret;
107 idmef_value_t *iv;
108 prelude_string_t *str;
109
110 ret = prelude_string_new_dup(&str, value);
111 if ( ret < 0 )
112 return ret;
113
114 ret = idmef_value_new_string(&iv, str);
115 if ( ret < 0 ) {
116 prelude_string_destroy(str);
117 return ret;
118 }
119
120 ret = idmef_message_set_value(message, path, iv);
121 idmef_value_destroy(iv);
122
123 return ret;
124 }
125
126
127
128 /**
129 * idmef_message_get_string:
130 * @message: Pointer to an #idmef_message_t object.
131 * @path: Path to retrieve the string from within @message.
132 * @result: Pointer where the result should be stored.
133 *
134 * Retrieve the string stored within @path of @message and store it
135 * in the user provided @result.
136 *
137 * The caller is responssible for freeing @result.
138 *
139 * Returns: A positive value in case @path was successfully retrieved
140 * 0 if the path is empty, or a negative value if an error occured.
141 */
idmef_message_get_string(idmef_message_t * message,const char * path,char ** result)142 int idmef_message_get_string(idmef_message_t *message, const char *path, char **result)
143 {
144 int ret;
145 idmef_value_t *iv;
146 prelude_string_t *str;
147
148 ret = idmef_message_get_value(message, path, &iv);
149 if ( ret <= 0 )
150 return ret;
151
152 if ( idmef_value_get_type(iv) != IDMEF_VALUE_TYPE_STRING ) {
153 ret = _idmef_value_cast(iv, IDMEF_VALUE_TYPE_STRING, 0);
154 if ( ret < 0 )
155 goto err;
156 }
157
158 if ( ! (str = idmef_value_get_string(iv)) ) {
159 ret = -1;
160 goto err;
161 }
162
163 if ( prelude_string_is_empty(str) ) {
164 *result = NULL;
165 return 0;
166 }
167
168 *result = strdup(prelude_string_get_string(str));
169 ret = prelude_string_get_len(str);
170
171 err:
172 idmef_value_destroy(iv);
173 return ret;
174 }
175
176
177
178 /**
179 * idmef_message_set_number:
180 * @message: Pointer to an #idmef_message_t object.
181 * @path: Path to be set within @message.
182 * @number: Value to associate @message[@path] with.
183 *
184 * This function will set the @path member within @message to the
185 * provided @value, which will be converted to the @path value type.
186 *
187 * Example:
188 * idmef_message_set_number(message, "alert.assessment.confidence.confidence", 0.123456);
189 * idmef_message_set_number(message, "alert.source(0).service.port", 1024);
190 *
191 * Returns: 0 on success, or a negative value if an error occured.
192 */
idmef_message_set_number(idmef_message_t * message,const char * path,double number)193 int idmef_message_set_number(idmef_message_t *message, const char *path, double number)
194 {
195 int ret;
196 idmef_value_t *iv;
197
198 ret = idmef_value_new_double(&iv, number);
199 if ( ret < 0 )
200 return ret;
201
202 ret = idmef_message_set_value(message, path, iv);
203 idmef_value_destroy(iv);
204
205 return ret;
206
207 }
208
209
210 /**
211 * idmef_message_get_number:
212 * @message: Pointer to an #idmef_message_t object.
213 * @path: Path to retrieve the number from within @message.
214 * @result: Pointer where the result should be stored.
215 *
216 * Retrieve the number stored within @path of @message and store it
217 * in the user provided @result.
218 *
219 * Returns: A positive value in case @path was successfully retrieved
220 * 0 if the path is empty, or a negative value if an error occured.
221 */
idmef_message_get_number(idmef_message_t * message,const char * path,double * result)222 int idmef_message_get_number(idmef_message_t *message, const char *path, double *result)
223 {
224 int ret;
225 idmef_value_t *iv;
226
227 ret = idmef_message_get_value(message, path, &iv);
228 if ( ret <= 0 )
229 return ret;
230
231 if ( idmef_value_get_type(iv) != IDMEF_VALUE_TYPE_DOUBLE ) {
232 ret = _idmef_value_cast(iv, IDMEF_VALUE_TYPE_DOUBLE, 0);
233 if ( ret < 0 )
234 goto err;
235 }
236
237 ret = 1;
238 *result = idmef_value_get_double(iv);
239
240 err:
241 idmef_value_destroy(iv);
242 return ret;
243 }
244
245
246 /**
247 * idmef_message_set_data:
248 * @message: Pointer to an #idmef_message_t object.
249 * @path: Path to be set within @message.
250 * @data: Pointer to data to associate @message[@path] with.
251 * @size: Size of the data pointed to by @data.
252 *
253 * This function will set the @path member within @message to the
254 * provided @data of size @size.
255 *
256 * Returns: 0 on success, or a negative value if an error occured.
257 */
idmef_message_set_data(idmef_message_t * message,const char * path,const unsigned char * data,size_t size)258 int idmef_message_set_data(idmef_message_t *message, const char *path, const unsigned char *data, size_t size)
259 {
260 int ret;
261 idmef_data_t *id;
262 idmef_value_t *iv;
263
264 ret = idmef_data_new_byte_string_dup(&id, data, size);
265 if ( ret < 0 )
266 return ret;
267
268 ret = idmef_value_new_data(&iv, id);
269 if ( ret < 0 ) {
270 idmef_data_destroy(id);
271 return ret;
272 }
273
274 ret = idmef_message_set_value(message, path, iv);
275 idmef_value_destroy(iv);
276
277 return ret;
278 }
279
280
idmef_message_get_data(idmef_message_t * message,const char * path,unsigned char ** data,size_t * size)281 int idmef_message_get_data(idmef_message_t *message, const char *path, unsigned char **data, size_t *size)
282 {
283 int ret;
284 idmef_data_t *dp;
285 idmef_value_t *iv;
286
287 ret = idmef_message_get_value(message, path, &iv);
288 if ( ret <= 0 )
289 return ret;
290
291 if ( idmef_value_get_type(iv) != IDMEF_VALUE_TYPE_DATA || ! (dp = idmef_value_get_data(iv)) ) {
292 ret = -1;
293 goto err;
294 }
295
296 *size = idmef_data_get_len(dp);
297 *data = malloc(*size);
298 if ( ! *data ) {
299 ret = -1;
300 goto err;
301 }
302
303 memcpy(*data, idmef_data_get_data(dp), *size);
304
305 err:
306 idmef_value_destroy(iv);
307 return ret;
308 }
309