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