X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Frootcheck%2Fcommon.c;h=eec625a74c43ba2d1791badf5cd6d24fbf75027d;hp=67ae1802212f9f7518d93d046be87bc2e6ee04bb;hb=6ef2f786c6c8ead94841b5f93baf9f43421f08c8;hpb=914feba5d54f979cd5d7e69c349c3d01f630042a diff --git a/src/rootcheck/common.c b/src/rootcheck/common.c index 67ae180..eec625a 100755 --- a/src/rootcheck/common.c +++ b/src/rootcheck/common.c @@ -1,21 +1,22 @@ -/* @(#) $Id: common.c,v 1.25 2009/06/24 18:53:07 dcid Exp $ */ +/* @(#) $Id: ./src/rootcheck/common.c, 2011/09/08 dcid Exp $ + */ /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public - * License (version 3) as published by the FSF - Free Software + * License (version 2) as published by the FSF - Free Software * Foundation * - * License details at the LICENSE file included with OSSEC or + * License details at the LICENSE file included with OSSEC or * online at: http://www.ossec.net/main/license/ . */ - + #include "shared.h" #include "rootcheck.h" -#include "os_regex/os_regex.h" +#include "os_regex/os_regex.h" @@ -59,7 +60,7 @@ int rk_check_dir(char *dir, char *file, char *pattern) { /* Just ignore . and .. */ if((strcmp(entry->d_name,".") == 0) || - (strcmp(entry->d_name,"..") == 0)) + (strcmp(entry->d_name,"..") == 0)) { continue; } @@ -68,7 +69,7 @@ int rk_check_dir(char *dir, char *file, char *pattern) /* Creating new file + path string */ snprintf(f_name, PATH_MAX +1, "%s/%s",dir, entry->d_name); - + /* Checking if the read entry, matches the provided file name. */ if(strncasecmp(file, "r:", 2) == 0) { @@ -80,7 +81,7 @@ int rk_check_dir(char *dir, char *file, char *pattern) } } } - + /* Trying without regex. */ else { @@ -93,7 +94,7 @@ int rk_check_dir(char *dir, char *file, char *pattern) } } - + /* Checking if file is a directory */ if(lstat(f_name, &statbuf_local) == 0) { @@ -119,11 +120,13 @@ int rk_check_dir(char *dir, char *file, char *pattern) int rk_check_file(char *file, char *pattern) { char *split_file; - + int full_negate = 0; + int pt_result = 0; + FILE *fp; char buf[OS_SIZE_2048 +1]; - - + + /* If string is null, we don't match */ if(file == NULL) { @@ -143,7 +146,7 @@ int rk_check_file(char *file, char *pattern) /* Getting each file */ do { - + /* If we don't have a pattern, just check if the file/dir is there */ if(pattern == NULL) @@ -165,7 +168,7 @@ int rk_check_file(char *file, char *pattern) while(rootcheck.alert_msg[i] && (i < 255)) i++; - + if(!rootcheck.alert_msg[i]) os_strdup(_b_msg, rootcheck.alert_msg[i]); @@ -175,11 +178,14 @@ int rk_check_file(char *file, char *pattern) else { + full_negate = pt_check_negate(pattern); /* Checking for a content in the file */ + debug1("checking file: %s", file); fp = fopen(file, "r"); if(fp) { + debug1(" starting new file: %s", file); buf[OS_SIZE_2048] = '\0'; while(fgets(buf, OS_SIZE_2048, fp) != NULL) { @@ -204,8 +210,13 @@ int rk_check_file(char *file, char *pattern) /* Matched */ - if(pt_matches(buf, pattern)) + pt_result = pt_matches(buf, pattern); + debug1("Buf == \"%s\"", buf); + debug1("Pattern == \"%s\"", pattern); + debug1("pt_result == %d and full_negate == %d", pt_result, full_negate); + if((pt_result == 1 && full_negate == 0) ) { + debug1("alerting file %s on line %s", file, buf); int i = 0; char _b_msg[OS_SIZE_1024 +1]; @@ -217,7 +228,7 @@ int rk_check_file(char *file, char *pattern) _b_msg[OS_SIZE_1024] = '\0'; snprintf(_b_msg, OS_SIZE_1024, " File: %s.", file); - + /* Already present. */ if(_is_str_in_array(rootcheck.alert_msg, _b_msg)) { @@ -232,9 +243,45 @@ int rk_check_file(char *file, char *pattern) return(1); } + else if((pt_result == 0 && full_negate == 1) ) + { + /* found a full+negate match so no longer need to search + * break out of loop and amke sure the full negate does + * not alertin + */ + debug1("found a complete match for full_negate"); + full_negate = 0; + break; + } } fclose(fp); + + if(full_negate == 1) + { + debug1("full_negate alerting - file %s",file); + int i = 0; + char _b_msg[OS_SIZE_1024 +1]; + + /* Generating the alert itself. */ + _b_msg[OS_SIZE_1024] = '\0'; + snprintf(_b_msg, OS_SIZE_1024, " File: %s.", + file); + + /* Already present. */ + if(_is_str_in_array(rootcheck.alert_msg, _b_msg)) + { + return(1); + } + + while(rootcheck.alert_msg[i] && (i < 255)) + i++; + + if(!rootcheck.alert_msg[i]) + os_strdup(_b_msg, rootcheck.alert_msg[i]); + + return(1); + } } } @@ -247,8 +294,8 @@ int rk_check_file(char *file, char *pattern) split_file++; } } - - + + }while(split_file); @@ -256,6 +303,49 @@ int rk_check_file(char *file, char *pattern) } +/** int pt_check_negate(char *pattern) + * Checks if the patterns is all negate values and if so returns 1 + * else return 0 + */ +int pt_check_negate(char *pattern) +{ + char *mypattern = NULL; + os_strdup(pattern, mypattern); + char *tmp_pt = mypattern; + char *tmp_pattern = mypattern; + char *tmp_ret = NULL; + + + while(tmp_pt != NULL) + { + /* We first look for " && " */ + tmp_pt = strchr(tmp_pattern, ' '); + if(tmp_pt && tmp_pt[1] == '&' && tmp_pt[2] == '&' && tmp_pt[3] == ' ') + { + /* Marking pointer to clean it up */ + tmp_ret = tmp_pt; + + *tmp_pt = '\0'; + tmp_pt += 4; + } + else + { + tmp_pt = NULL; + } + + if(*tmp_pattern != '!') + { + free(mypattern); + return 0; + } + + tmp_pattern = tmp_pt; + } + + debug1("pattern: %s is fill_negate",pattern); + free(mypattern); + return(1); +} /** int pt_matches(char *str, char *pattern) * Checks if the specific pattern is present on str. @@ -263,7 +353,7 @@ int rk_check_file(char *file, char *pattern) * =: (for equal) - default - strcasecmp * r: (for ossec regexes) * >: (for strcmp greater) - * <: (for strcmp lower) + * <: (for strcmp lower) * * Multiple patterns can be specified by using " && " between them. * All of them must match for it to return true. @@ -281,16 +371,16 @@ int pt_matches(char *str, char *pattern) { return(0); } - + while(tmp_pt != NULL) { /* We first look for " && " */ tmp_pt = strchr(pattern, ' '); if(tmp_pt && tmp_pt[1] == '&' && tmp_pt[2] == '&' && tmp_pt[3] == ' ') { - /* Marking pointer to clean it up */ + /* Marking pointer to clean it up */ tmp_ret = tmp_pt; - + *tmp_pt = '\0'; tmp_pt += 4; } @@ -308,7 +398,7 @@ int pt_matches(char *str, char *pattern) pattern++; neg = 1; } - + /* Doing strcasecmp */ if(strncasecmp(pattern, "=:", 2) == 0) @@ -324,6 +414,7 @@ int pt_matches(char *str, char *pattern) pattern += 2; if(OS_Regex(pattern, str)) { + debug1("pattern: %s matches %s.",pattern, str); ret_code = 1; } } @@ -347,7 +438,7 @@ int pt_matches(char *str, char *pattern) { #ifdef WIN32 char final_file[2048 +1]; - + /* Try to get Windows variable */ if(*pattern == '%') { @@ -366,7 +457,7 @@ int pt_matches(char *str, char *pattern) { ret_code = 1; } - + #else if(strcasecmp(pattern, str) == 0) { @@ -383,7 +474,7 @@ int pt_matches(char *str, char *pattern) tmp_ret = NULL; } - + /* If we have "!", return true if we don't match */ if(neg == 1) { @@ -401,7 +492,7 @@ int pt_matches(char *str, char *pattern) break; } } - + ret_code = 1; pattern = tmp_pt; } @@ -417,8 +508,22 @@ int pt_matches(char *str, char *pattern) */ char *normalize_string(char *str) { - int str_sz = strlen(str) -1; - + unsigned int str_sz = strlen(str); + // return zero-length str as is + if (str_sz == 0) { + return str; + } else { + str_sz--; + } + // remove trailing spaces + while(str[str_sz] == ' ' || str[str_sz] == '\t') + { + if(str_sz == 0) + break; + + str[str_sz--] = '\0'; + } + // ignore leading spaces while(*str != '\0') { if(*str == ' ' || *str == '\t') @@ -431,17 +536,13 @@ char *normalize_string(char *str) } } - while(str[str_sz] == ' ' || str[str_sz] == '\t') - { - str[str_sz] = '\0'; - str_sz--; - } - return(str); } + + /** int isfile_ondir(char *file, char *dir) * Checks is 'file' is present on 'dir' using readdir */ @@ -450,7 +551,7 @@ int isfile_ondir(char *file, char *dir) DIR *dp = NULL; struct dirent *entry; dp = opendir(dir); - + if(!dp) return(0); @@ -462,7 +563,7 @@ int isfile_ondir(char *file, char *dir) return(1); } } - + closedir(dp); return(0); } @@ -475,19 +576,19 @@ int isfile_ondir(char *file, char *dir) int is_file(char *file_name) { int ret = 0; - + struct stat statbuf; FILE *fp = NULL; DIR *dp = NULL; #ifndef WIN32 - + char curr_dir[1024]; - + char *file_dirname; char *file_basename; - + curr_dir[1023] = '\0'; @@ -504,7 +605,7 @@ int is_file(char *file_name) return(0); } - + /* If file_basename == file_name, then the file * only has one slash at the beginning. */ @@ -565,7 +666,7 @@ int is_file(char *file_name) ret = 1; } } - + #else dp = opendir(file_name); if(dp) @@ -573,10 +674,10 @@ int is_file(char *file_name) closedir(dp); ret = 1; } - + #endif /* WIN32 */ - + /* Trying other calls */ if( (stat(file_name, &statbuf) < 0) && #ifndef WIN32 @@ -590,7 +691,7 @@ int is_file(char *file_name) /* must close it over here */ if(fp) fclose(fp); - + return(1); } @@ -625,7 +726,7 @@ int del_plist(void *p_list_p) { free(pinfo->p_path); } - + free(l_node->data); if(p_node) @@ -681,7 +782,7 @@ int is_process(char *value, void *p_list_p) char _b_msg[OS_SIZE_1024 +1]; _b_msg[OS_SIZE_1024] = '\0'; - + snprintf(_b_msg, OS_SIZE_1024, " Process: %s.", pinfo->p_path); @@ -690,7 +791,7 @@ int is_process(char *value, void *p_list_p) { return(1); } - + while(rootcheck.alert_msg[i] && (i< 255)) i++; @@ -706,7 +807,7 @@ int is_process(char *value, void *p_list_p) return(0); } - - + + /* EOF */