Branch data Line data Source code
1 : : /**
2 : : * @file utils.c
3 : : *
4 : : * @brief General/Generic functions for the fwknop server.
5 : : *
6 : : * Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
7 : : * Copyright (C) 2009-2014 fwknop developers and contributors. For a full
8 : : * list of contributors, see the file 'CREDITS'.
9 : : *
10 : : * License (GNU General Public License):
11 : : *
12 : : * This program is free software; you can redistribute it and/or
13 : : * modify it under the terms of the GNU General Public License
14 : : * as published by the Free Software Foundation; either version 2
15 : : * of the License, or (at your option) any later version.
16 : : *
17 : : * This program is distributed in the hope that it will be useful,
18 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : : * GNU General Public License for more details.
21 : : *
22 : : * You should have received a copy of the GNU General Public License
23 : : * along with this program; if not, write to the Free Software
24 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 : : * USA
26 : : */
27 : :
28 : : #include "fwknopd_common.h"
29 : : #include "utils.h"
30 : : #include "log_msg.h"
31 : : #include "replay_cache.h"
32 : : #include "config_init.h"
33 : : #include "fw_util.h"
34 : :
35 : : #include <stdarg.h>
36 : :
37 : : #define ASCII_LEN 16
38 : :
39 : : /* Generic hex dump function.
40 : : */
41 : : void
42 : 109 : hex_dump(const unsigned char *data, const int size)
43 : : {
44 : 109 : int ln=0, i=0, j=0;
45 : 109 : char ascii_str[ASCII_LEN+1] = {0};
46 : :
47 [ + + ]: 18163 : for(i=0; i<size; i++)
48 : : {
49 [ + + ]: 18054 : if((i % ASCII_LEN) == 0)
50 : : {
51 : : printf(" %s\n 0x%.4x: ", ascii_str, i);
52 : : memset(ascii_str, 0x0, ASCII_LEN-1);
53 : 1221 : j = 0;
54 : : }
55 : :
56 : 18054 : printf("%.2x ", data[i]);
57 : :
58 [ + + ]: 18054 : ascii_str[j++] = (data[i] < 0x20 || data[i] > 0x7e) ? '.' : data[i];
59 : :
60 [ + + ]: 18054 : if(j == 8)
61 : : printf(" ");
62 : : }
63 : :
64 : : /* Remainder...
65 : : */
66 : 109 : ln = strlen(ascii_str);
67 [ + - ]: 109 : if(ln > 0)
68 : : {
69 [ + + ]: 1591 : for(i=0; i < ASCII_LEN-ln; i++)
70 : : printf(" ");
71 [ + + ]: 109 : if(ln < 8)
72 : : printf(" ");
73 : :
74 : : printf(" %s\n\n", ascii_str);
75 : : }
76 : 109 : return;
77 : : }
78 : :
79 : : /* Basic directory/binary checks (stat() and whether the path is actually
80 : : * a directory or an executable).
81 : : */
82 : : static int
83 : 90 : is_valid_path(const char *path, const int file_type)
84 : : {
85 : : #if HAVE_STAT
86 : : struct stat st;
87 : :
88 : : /* If we are unable to stat the given path, then return with error.
89 : : */
90 [ + + ]: 90 : if(stat(path, &st) != 0)
91 : : {
92 : 5 : log_msg(LOG_ERR, "[-] unable to stat() path: %s: %s",
93 : 5 : path, strerror(errno));
94 : 5 : return(0);
95 : : }
96 : :
97 [ + + ]: 85 : if(file_type == IS_DIR)
98 : : {
99 [ + - ]: 76 : if(!S_ISDIR(st.st_mode))
100 : : return(0);
101 : : }
102 [ + - ]: 9 : else if(file_type == IS_EXE)
103 : : {
104 [ + + ]: 9 : if(!S_ISREG(st.st_mode) || ! (st.st_mode & S_IXUSR))
105 : : return(0);
106 : : }
107 : : else
108 : : return(0);
109 : :
110 : : #endif /* HAVE_STAT */
111 : :
112 : 84 : return(1);
113 : : }
114 : :
115 : : int
116 : 79 : is_valid_dir(const char *path)
117 : : {
118 : 79 : return is_valid_path(path, IS_DIR);
119 : : }
120 : :
121 : : int
122 : 11 : is_valid_exe(const char *path)
123 : : {
124 : 11 : return is_valid_path(path, IS_EXE);
125 : : }
126 : :
127 : : int
128 : 16502 : verify_file_perms_ownership(const char *file)
129 : : {
130 : : #if HAVE_STAT
131 : : struct stat st;
132 : :
133 : : /* Every file that fwknopd deals with should be owned
134 : : * by the user and permissions set to 600 (user read/write)
135 : : */
136 [ + - ]: 16502 : if((stat(file, &st)) == 0)
137 : : {
138 : : /* Make sure it is a regular file
139 : : */
140 [ + + ]: 16502 : if(S_ISREG(st.st_mode) != 1 && S_ISLNK(st.st_mode) != 1)
141 : : {
142 : 1 : log_msg(LOG_WARNING,
143 : : "[-] file: %s is not a regular file or symbolic link.",
144 : : file
145 : : );
146 : 1 : return 0;
147 : : }
148 : :
149 [ + + ]: 16501 : if((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != (S_IRUSR|S_IWUSR))
150 : : {
151 : 264 : log_msg(LOG_WARNING,
152 : : "[-] file: %s permissions should only be user read/write (0600, -rw-------)",
153 : : file
154 : : );
155 : : /* when we start in enforcing this instead of just warning
156 : : * the user
157 : : res = 0;
158 : : */
159 : : }
160 : :
161 [ + + ]: 16501 : if(st.st_uid != getuid())
162 : : {
163 : 12308 : log_msg(LOG_WARNING, "[-] file: %s not owned by current effective user id",
164 : : file);
165 : : /* when we start in enforcing this instead of just warning
166 : : * the user
167 : : res = 0;
168 : : */
169 : : }
170 : : }
171 : : else
172 : : {
173 : : /* if the path doesn't exist, just return, but otherwise something
174 : : * went wrong
175 : : */
176 [ # # ]: 0 : if(errno != ENOENT)
177 : : {
178 : 0 : log_msg(LOG_ERR, "[-] stat() against file: %s returned: %s",
179 : : file, strerror(errno));
180 : 0 : return 0;
181 : : }
182 : : }
183 : :
184 : : #endif
185 : :
186 : : return 1;
187 : : }
188 : :
189 : : void
190 : 10259 : chop_char(char *str, const char chop)
191 : : {
192 [ + - ][ + - ]: 10259 : if(str != NULL && str[0] != 0x0 && str[strlen(str)-1] == chop)
[ + + ]
193 : 10247 : str[strlen(str)-1] = 0x0;
194 : 10259 : return;
195 : : }
196 : :
197 : : void
198 : 10259 : chop_newline(char *str)
199 : : {
200 : 10259 : chop_char(str, 0x0a);
201 : 10259 : return;
202 : : }
203 : :
204 : 761 : void chop_spaces(char *str)
205 : : {
206 : : int i;
207 [ + - ][ + - ]: 761 : if (str != NULL && str[0] != 0x0)
208 : : {
209 [ + - ]: 1568 : for (i=strlen(str)-1; i > 0; i--)
210 : : {
211 [ + + ]: 1568 : if(str[i] != 0x20)
212 : : break;
213 : 807 : str[i] = 0x0;
214 : : }
215 : : }
216 : 761 : return;
217 : : }
218 : :
219 : : void
220 : 11718 : truncate_partial_line(char *str)
221 : : {
222 : 11718 : int i, have_newline=0;
223 : :
224 [ + + ][ + - ]: 11718 : if(str != NULL && str[0] != 0x0)
225 : : {
226 [ + + ]: 615441 : for (i=0; i < strlen(str); i++)
227 : : {
228 [ + + ]: 615429 : if(str[i] == 0x0a)
229 : : {
230 : : have_newline = 1;
231 : : break;
232 : : }
233 : : }
234 : :
235 : : /* Don't zero out any data unless there is at least
236 : : * one newline
237 : : */
238 [ + + ]: 11641 : if(have_newline)
239 : : {
240 [ + - ]: 12739 : for (i=strlen(str)-1; i > 0; i--)
241 : : {
242 [ + + ]: 12739 : if(str[i] == 0x0a)
243 : : break;
244 : 1110 : str[i] = 0x0;
245 : : }
246 : : }
247 : : }
248 : 11718 : return;
249 : : }
250 : :
251 : : /* Simple test to see if a string only contains digits
252 : : */
253 : : int
254 : 761 : is_digits(const char * const str)
255 : : {
256 : : int i;
257 [ + - ][ + - ]: 761 : if (str != NULL && str[0] != 0x0)
258 : : {
259 [ + + ]: 4437 : for (i=0; i<strlen(str); i++)
260 : : {
261 [ + + ]: 3703 : if(!isdigit(str[i]))
262 : : return 0;
263 : 3676 : i++;
264 : : }
265 : : }
266 : : return 1;
267 : : }
268 : :
269 : : static int
270 : 139129 : add_argv(char **argv_new, int *argc_new,
271 : : const char *new_arg, const fko_srv_options_t * const opts)
272 : : {
273 : 139129 : int buf_size = 0;
274 : :
275 [ + + ]: 139129 : if(opts->verbose > 3)
276 : 1554 : log_msg(LOG_INFO, "[+] add_argv() + arg: %s", new_arg);
277 : :
278 : 139129 : buf_size = strlen(new_arg) + 1;
279 : 139129 : argv_new[*argc_new] = calloc(1, buf_size);
280 : :
281 [ - + ]: 139129 : if(argv_new[*argc_new] == NULL)
282 : : {
283 : 0 : log_msg(LOG_INFO, "[*] Memory allocation error.");
284 : : return 0;
285 : : }
286 : 139129 : strlcpy(argv_new[*argc_new], new_arg, buf_size);
287 : :
288 : 139129 : *argc_new += 1;
289 : :
290 [ + + ]: 139129 : if(*argc_new >= MAX_CMDLINE_ARGS-1)
291 : : {
292 : 2 : log_msg(LOG_ERR, "[*] max command line args exceeded.");
293 : : return 0;
294 : : }
295 : :
296 : 139127 : argv_new[*argc_new] = NULL;
297 : :
298 : : return 1;
299 : : }
300 : :
301 : : int
302 : 13086 : strtoargv(const char * const args_str, char **argv_new, int *argc_new,
303 : : const fko_srv_options_t * const opts)
304 : : {
305 : 13086 : int current_arg_ctr = 0, i;
306 : 13086 : char arg_tmp[MAX_LINE_LEN] = {0};
307 : :
308 [ + + ]: 1203510 : for (i=0; i < (int)strlen(args_str); i++)
309 : : {
310 [ + + ]: 1190426 : if (!isspace(args_str[i]))
311 : : {
312 : 1051320 : arg_tmp[current_arg_ctr] = args_str[i];
313 : 1051320 : current_arg_ctr++;
314 : : }
315 : : else
316 : : {
317 [ + + ]: 139106 : if(current_arg_ctr > 0)
318 : : {
319 : 126049 : arg_tmp[current_arg_ctr] = '\0';
320 [ + + ]: 126049 : if (add_argv(argv_new, argc_new, arg_tmp, opts) != 1)
321 : : {
322 : 2 : free_argv(argv_new, argc_new);
323 : 2 : return 0;
324 : : }
325 : : current_arg_ctr = 0;
326 : : }
327 : : }
328 : : }
329 : :
330 : : /* pick up the last argument in the string
331 : : */
332 [ + + ]: 13084 : if(current_arg_ctr > 0)
333 : : {
334 : 13080 : arg_tmp[current_arg_ctr] = '\0';
335 [ - + ]: 13080 : if (add_argv(argv_new, argc_new, arg_tmp, opts) != 1)
336 : : {
337 : 0 : free_argv(argv_new, argc_new);
338 : 0 : return 0;
339 : : }
340 : : }
341 : : return 1;
342 : : }
343 : :
344 : : void
345 : 13042 : free_argv(char **argv_new, int *argc_new)
346 : : {
347 : : int i;
348 : :
349 [ + - ][ + - ]: 13042 : if(argv_new == NULL || *argv_new == NULL)
350 : : return;
351 : :
352 [ + + ]: 151754 : for (i=0; i < *argc_new; i++)
353 : : {
354 [ + - ]: 138712 : if(argv_new[i] == NULL)
355 : : break;
356 : : else
357 : 138712 : free(argv_new[i]);
358 : : }
359 : : return;
360 : : }
361 : :
362 : : void
363 : 5835 : clean_exit(fko_srv_options_t *opts, unsigned int fw_cleanup_flag, unsigned int exit_status)
364 : : {
365 : : #if HAVE_LIBFIU
366 [ + + ]: 5835 : if(opts->config[CONF_FAULT_INJECTION_TAG] != NULL)
367 : : {
368 : 35 : fiu_disable(opts->config[CONF_FAULT_INJECTION_TAG]);
369 : : }
370 : : #endif
371 : :
372 [ + + ][ + + ]: 5835 : if(!opts->test && (fw_cleanup_flag == FW_CLEANUP))
373 : 439 : fw_cleanup(opts);
374 : :
375 : : #if USE_FILE_CACHE
376 : 5793 : free_replay_list(opts);
377 : : #endif
378 : :
379 : 5793 : free_logging();
380 : 5793 : free_configs(opts);
381 : 5793 : exit(exit_status);
382 : : }
383 : :
384 : : /***EOF***/
|