1 /* @(#) $Id: common.c,v 1.25 2009/06/24 18:53:07 dcid Exp $ */
3 /* Copyright (C) 2009 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 3) as published by the FSF - Free Software
11 * License details at the LICENSE file included with OSSEC or
12 * online at: http://www.ossec.net/main/license/ .
17 #include "rootcheck.h"
18 #include "os_regex/os_regex.h"
22 /** Checks if the specified string is already in the array.
24 int _is_str_in_array(char **ar, char *str)
28 if(strcmp(*ar, str) == 0)
39 /** int rk_check_dir(char *dir, char *file, char *pattern)
41 int rk_check_dir(char *dir, char *file, char *pattern)
44 char f_name[PATH_MAX +2];
46 struct stat statbuf_local;
50 f_name[PATH_MAX +1] = '\0';
58 while((entry = readdir(dp)) != NULL)
60 /* Just ignore . and .. */
61 if((strcmp(entry->d_name,".") == 0) ||
62 (strcmp(entry->d_name,"..") == 0))
68 /* Creating new file + path string */
69 snprintf(f_name, PATH_MAX +1, "%s/%s",dir, entry->d_name);
72 /* Checking if the read entry, matches the provided file name. */
73 if(strncasecmp(file, "r:", 2) == 0)
75 if(OS_Regex(file +2, entry->d_name))
77 if(rk_check_file(f_name, pattern))
84 /* Trying without regex. */
87 if(OS_Match2(file, entry->d_name))
89 if(rk_check_file(f_name, pattern))
97 /* Checking if file is a directory */
98 if(lstat(f_name, &statbuf_local) == 0)
100 if(S_ISDIR(statbuf_local.st_mode))
102 if(rk_check_dir(f_name, file, pattern))
117 /** int rk_check_file(char *value, char *pattern)
119 int rk_check_file(char *file, char *pattern)
124 char buf[OS_SIZE_2048 +1];
127 /* If string is null, we don't match */
134 /* Checking if the file is divided */
135 split_file = strchr(file, ',');
143 /* Getting each file */
148 /* If we don't have a pattern, just check if the file/dir is there */
154 char _b_msg[OS_SIZE_1024 +1];
156 _b_msg[OS_SIZE_1024] = '\0';
157 snprintf(_b_msg, OS_SIZE_1024, " File: %s.",
160 /* Already present. */
161 if(_is_str_in_array(rootcheck.alert_msg, _b_msg))
166 while(rootcheck.alert_msg[i] && (i < 255))
169 if(!rootcheck.alert_msg[i])
170 os_strdup(_b_msg, rootcheck.alert_msg[i]);
178 /* Checking for a content in the file */
179 fp = fopen(file, "r");
183 buf[OS_SIZE_2048] = '\0';
184 while(fgets(buf, OS_SIZE_2048, fp) != NULL)
188 /* Removing end of line */
189 nbuf = strchr(buf, '\n');
197 /* Removing end of line */
198 nbuf = strchr(buf, '\r');
207 if(pt_matches(buf, pattern))
210 char _b_msg[OS_SIZE_1024 +1];
213 /* Closing the file before dealing with the alert. */
216 /* Generating the alert itself. */
217 _b_msg[OS_SIZE_1024] = '\0';
218 snprintf(_b_msg, OS_SIZE_1024, " File: %s.",
221 /* Already present. */
222 if(_is_str_in_array(rootcheck.alert_msg, _b_msg))
227 while(rootcheck.alert_msg[i] && (i < 255))
230 if(!rootcheck.alert_msg[i])
231 os_strdup(_b_msg, rootcheck.alert_msg[i]);
244 split_file = strchr(split_file, ',');
260 /** int pt_matches(char *str, char *pattern)
261 * Checks if the specific pattern is present on str.
262 * A pattern can be preceeded by:
263 * =: (for equal) - default - strcasecmp
264 * r: (for ossec regexes)
265 * >: (for strcmp greater)
266 * <: (for strcmp lower)
268 * Multiple patterns can be specified by using " && " between them.
269 * All of them must match for it to return true.
271 int pt_matches(char *str, char *pattern)
275 char *tmp_pt = pattern;
276 char *tmp_ret = NULL;
279 /* If string we null, we don't match */
285 while(tmp_pt != NULL)
287 /* We first look for " && " */
288 tmp_pt = strchr(pattern, ' ');
289 if(tmp_pt && tmp_pt[1] == '&' && tmp_pt[2] == '&' && tmp_pt[3] == ' ')
291 /* Marking pointer to clean it up */
303 /* Checking for negate values */
313 /* Doing strcasecmp */
314 if(strncasecmp(pattern, "=:", 2) == 0)
317 if(strcasecmp(pattern, str) == 0)
322 else if(strncasecmp(pattern, "r:", 2) == 0)
325 if(OS_Regex(pattern, str))
330 else if(strncasecmp(pattern, "<:", 2) == 0)
333 if(strcmp(pattern, str) < 0)
338 else if(strncasecmp(pattern, ">:", 2) == 0)
341 if(strcmp(pattern, str) > 0)
349 char final_file[2048 +1];
351 /* Try to get Windows variable */
354 final_file[0] = '\0';
355 final_file[2048] = '\0';
357 ExpandEnvironmentStrings(pattern, final_file, 2047);
361 strncpy(final_file, pattern, 2047);
364 /* Comparing against the expanded variable */
365 if(strcasecmp(final_file, str) == 0)
371 if(strcasecmp(pattern, str) == 0)
379 /* Fixing tmp_ret entry */
387 /* If we have "!", return true if we don't match */
414 /** char *normalize_string
415 * Normalizes a string, removing white spaces and tabs
416 * from the begining and the end of it.
418 char *normalize_string(char *str)
420 int str_sz = strlen(str) -1;
424 if(*str == ' ' || *str == '\t')
434 while(str[str_sz] == ' ' || str[str_sz] == '\t')
445 /** int isfile_ondir(char *file, char *dir)
446 * Checks is 'file' is present on 'dir' using readdir
448 int isfile_ondir(char *file, char *dir)
451 struct dirent *entry;
457 while((entry = readdir(dp)) != NULL)
459 if(strcmp(entry->d_name, file) == 0)
472 /* is_file: Check if the file is present
473 * by different attempts (to try to avoid syscall hidding).
475 int is_file(char *file_name)
492 curr_dir[1023] = '\0';
494 if(!getcwd(curr_dir, 1022))
499 /* Getting dir name */
500 file_basename = strrchr(file_name, '/');
503 merror("%s: RK: Invalid file name: %s!", ARGV0, file_name);
508 /* If file_basename == file_name, then the file
509 * only has one slash at the beginning.
511 if(file_basename != file_name)
513 /* Dir name and base name are now set */
514 *file_basename = '\0';
516 file_dirname = file_name;
519 if(chdir(file_dirname) == 0)
521 if(chdir(file_basename) == 0)
525 /* Checking errno (if file exists, but it is not
528 else if(errno == ENOTDIR)
533 /** Trying open dir **/
534 dp = opendir(file_basename);
540 else if(errno == ENOTDIR)
545 /* Returning to the previous directory */
551 *file_basename = '/';
556 if(chdir(file_name) == 0)
560 /* Returning to the previous directory */
563 else if(errno == ENOTDIR)
570 dp = opendir(file_name);
580 /* Trying other calls */
581 if( (stat(file_name, &statbuf) < 0) &&
583 (access(file_name, F_OK) < 0) &&
585 ((fp = fopen(file_name, "r")) == NULL))
590 /* must close it over here */
599 /* del_plist:. Deletes the process list
601 int del_plist(void *p_list_p)
603 OSList *p_list = (OSList *)p_list_p;
605 OSListNode *p_node = NULL;
612 l_node = OSList_GetFirstNode(p_list);
617 pinfo = (Proc_Info *)l_node->data;
638 l_node = OSList_GetNextNode(p_list);
654 /* is_process: Check is a process is running.
656 int is_process(char *value, void *p_list_p)
658 OSList *p_list = (OSList *)p_list_p;
670 l_node = OSList_GetFirstNode(p_list);
675 pinfo = (Proc_Info *)l_node->data;
677 /* Checking if value matches */
678 if(pt_matches(pinfo->p_path, value))
681 char _b_msg[OS_SIZE_1024 +1];
683 _b_msg[OS_SIZE_1024] = '\0';
685 snprintf(_b_msg, OS_SIZE_1024, " Process: %s.",
688 /* Already present. */
689 if(_is_str_in_array(rootcheck.alert_msg, _b_msg))
694 while(rootcheck.alert_msg[i] && (i< 255))
697 if(!rootcheck.alert_msg[i])
698 os_strdup(_b_msg, rootcheck.alert_msg[i]);
703 l_node = OSList_GetNextNode(p_list);