-/* @(#) $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"
{
/* Just ignore . and .. */
if((strcmp(entry->d_name,".") == 0) ||
- (strcmp(entry->d_name,"..") == 0))
+ (strcmp(entry->d_name,"..") == 0))
{
continue;
}
/* 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)
{
}
}
}
-
+
/* Trying without regex. */
else
{
}
}
-
+
/* Checking if file is a directory */
if(lstat(f_name, &statbuf_local) == 0)
{
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)
{
/* Getting each file */
do
{
-
+
/* If we don't have a pattern, just check if the file/dir is there */
if(pattern == NULL)
while(rootcheck.alert_msg[i] && (i < 255))
i++;
-
+
if(!rootcheck.alert_msg[i])
os_strdup(_b_msg, rootcheck.alert_msg[i]);
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)
{
/* 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];
_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);
}
+ 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);
+ }
}
}
split_file++;
}
}
-
-
+
+
}while(split_file);
}
+/** 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.
* =: (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.
{
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;
}
pattern++;
neg = 1;
}
-
+
/* Doing strcasecmp */
if(strncasecmp(pattern, "=:", 2) == 0)
pattern += 2;
if(OS_Regex(pattern, str))
{
+ debug1("pattern: %s matches %s.",pattern, str);
ret_code = 1;
}
}
{
#ifdef WIN32
char final_file[2048 +1];
-
+
/* Try to get Windows variable */
if(*pattern == '%')
{
{
ret_code = 1;
}
-
+
#else
if(strcasecmp(pattern, str) == 0)
{
tmp_ret = NULL;
}
-
+
/* If we have "!", return true if we don't match */
if(neg == 1)
{
break;
}
}
-
+
ret_code = 1;
pattern = tmp_pt;
}
*/
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')
}
}
- 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
*/
DIR *dp = NULL;
struct dirent *entry;
dp = opendir(dir);
-
+
if(!dp)
return(0);
return(1);
}
}
-
+
closedir(dp);
return(0);
}
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';
return(0);
}
-
+
/* If file_basename == file_name, then the file
* only has one slash at the beginning.
*/
ret = 1;
}
}
-
+
#else
dp = opendir(file_name);
if(dp)
closedir(dp);
ret = 1;
}
-
+
#endif /* WIN32 */
-
+
/* Trying other calls */
if( (stat(file_name, &statbuf) < 0) &&
#ifndef WIN32
/* must close it over here */
if(fp)
fclose(fp);
-
+
return(1);
}
{
free(pinfo->p_path);
}
-
+
free(l_node->data);
if(p_node)
char _b_msg[OS_SIZE_1024 +1];
_b_msg[OS_SIZE_1024] = '\0';
-
+
snprintf(_b_msg, OS_SIZE_1024, " Process: %s.",
pinfo->p_path);
{
return(1);
}
-
+
while(rootcheck.alert_msg[i] && (i< 255))
i++;
return(0);
}
-
-
+
+
/* EOF */