X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=src%2Frootcheck%2Fcommon_rcl.c;h=f92dda1187abfedb66198979ea8e8dbc13c177db;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hp=4e746665e189b3b10eba94cec70da8cd3a759869;hpb=789cbc8e52da68eba3517b920ef22e000cf3c9fd;p=ossec-hids.git diff --git a/src/rootcheck/common_rcl.c b/src/rootcheck/common_rcl.c old mode 100755 new mode 100644 index 4e74666..f92dda1 --- a/src/rootcheck/common_rcl.c +++ b/src/rootcheck/common_rcl.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/rootcheck/common_rcl.c, 2011/09/08 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All right reserved. * @@ -8,15 +5,18 @@ * and/or modify it under the terms of the GNU General Public * License (version 2) as published by the FSF - Free Software * Foundation - * - * License details at the LICENSE file included with OSSEC or - * online at: http://www.ossec.net/main/license/ */ - #include "shared.h" #include "rootcheck.h" +/* Prototypes */ +static char *_rkcl_getfp(FILE *fp, char *buf); +static int _rkcl_is_name(const char *buf); +static int _rkcl_get_vars(OSStore *vars, char *nbuf); +static char *_rkcl_get_name(char *buf, char *ref, int *condition); +static char *_rkcl_get_pattern(char *value); +static char *_rkcl_get_value(char *buf, int *type); /* Types of values */ #define RKCL_TYPE_FILE 1 @@ -30,13 +30,10 @@ #define RKCL_COND_INV 0x010 - -/** char *_rkcl_getrootdir() - */ +#ifdef WIN32 char *_rkcl_getrootdir(char *root_dir, int dir_size) { - #ifdef WIN32 - char final_file[2048 +1]; + char final_file[2048 + 1]; char *tmp; final_file[0] = '\0'; @@ -45,744 +42,551 @@ char *_rkcl_getrootdir(char *root_dir, int dir_size) ExpandEnvironmentStrings("%WINDIR%", final_file, 2047); tmp = strchr(final_file, '\\'); - if(tmp) - { + if (tmp) { *tmp = '\0'; strncpy(root_dir, final_file, dir_size); - return(root_dir); + return (root_dir); } - return(NULL); - - #endif - - return(NULL); + return (NULL); } +#endif - - -/** char *_rkcl_getfp: Get next available buffer in file. - */ -char *_rkcl_getfp(FILE *fp, char *buf) +/* Get next available buffer in file */ +static char *_rkcl_getfp(FILE *fp, char *buf) { - while(fgets(buf, OS_SIZE_1024, fp) != NULL) - { + while (fgets(buf, OS_SIZE_1024, fp) != NULL) { char *nbuf; - /* Removing end of line */ + /* Remove end of line */ nbuf = strchr(buf, '\n'); - if(nbuf) - { + if (nbuf) { *nbuf = '\0'; } - /* Assigning buf to be used */ + /* Assign buf to be used */ nbuf = buf; - - /* Excluding commented lines or blanked ones */ - while(*nbuf != '\0') - { - if(*nbuf == ' ' || *nbuf == '\t') - { + /* Exclude commented lines or blanked ones */ + while (*nbuf != '\0') { + if (*nbuf == ' ' || *nbuf == '\t') { nbuf++; continue; - } - else if(*nbuf == '#') - { + } else if (*nbuf == '#') { *nbuf = '\0'; continue; - } - else - { + } else { break; } } - /* Going to next line if empty */ - if(*nbuf == '\0') - { + /* Go to next line if empty */ + if (*nbuf == '\0') { continue; } - return(nbuf); + return (nbuf); } - return(NULL); + return (NULL); } - - -/** int _rkcl_is_name - */ -int _rkcl_is_name(char *buf) +static int _rkcl_is_name(const char *buf) { - if(*buf == '[' && buf[strlen(buf) -1] == ']') - { - return(1); + if (*buf == '[' && buf[strlen(buf) - 1] == ']') { + return (1); } - return(0); + return (0); } - - -/** int _rkcl_get_vars(vars, nbuf) - */ -int _rkcl_get_vars(OSStore *vars, char *nbuf) +static int _rkcl_get_vars(OSStore *vars, char *nbuf) { - char *var_name; char *var_value; char *tmp; /* If not a variable, return 0 */ - if(*nbuf != '$') - { - return(0); + if (*nbuf != '$') { + return (0); } - - /* Removing ; from the end. */ + /* Remove semicolon from the end */ tmp = strchr(nbuf, ';'); - if(tmp) - { + if (tmp) { *tmp = '\0'; + } else { + return (-1); } - else - { - return(-1); - } - - /* Getting value. */ + /* Get value */ tmp = strchr(nbuf, '='); - if(tmp) - { + if (tmp) { *tmp = '\0'; tmp++; + } else { + return (-1); } - else - { - return(-1); - } - - /* Dumping the variable options. */ - os_strdup(nbuf, var_name); + /* Dump the variable options */ os_strdup(tmp, var_value); - - /* Adding entry to the storage */ - OSStore_Put(vars, var_name, var_value); - return(1); + /* Add entry to the storage */ + OSStore_Put(vars, nbuf, var_value); + return (1); } - - -/** int _rkcl_get_name - */ -char *_rkcl_get_name(char *buf, char *ref, int *condition) +static char *_rkcl_get_name(char *buf, char *ref, int *condition) { char *tmp_location; char *tmp_location2; - *condition = 0; - /* Checking if name is valid */ - if(!_rkcl_is_name(buf)) - { - return(NULL); + /* Check if name is valid */ + if (!_rkcl_is_name(buf)) { + return (NULL); } - /* Setting name */ + /* Set name */ buf++; tmp_location = strchr(buf, ']'); - if(!tmp_location) - { - return(NULL); + if (!tmp_location) { + return (NULL); } *tmp_location = '\0'; - - /* Getting condition */ + /* Get condition */ tmp_location++; - if(*tmp_location != ' ' && tmp_location[1] != '[') - { - return(NULL); + if (*tmp_location != ' ' && tmp_location[1] != '[') { + return (NULL); } - tmp_location+=2; + tmp_location += 2; tmp_location2 = strchr(tmp_location, ']'); - if(!tmp_location2) - { - return(NULL); + if (!tmp_location2) { + return (NULL); } *tmp_location2 = '\0'; tmp_location2++; - - /* Getting condition */ - if(strcmp(tmp_location, "all") == 0) - { + /* Get condition */ + if (strcmp(tmp_location, "all") == 0) { *condition |= RKCL_COND_ALL; - } - else if(strcmp(tmp_location,"any") == 0) - { + } else if (strcmp(tmp_location, "any") == 0) { *condition |= RKCL_COND_ANY; - } - else if(strcmp(tmp_location,"any required") == 0) - { + } else if (strcmp(tmp_location, "any required") == 0) { *condition |= RKCL_COND_ANY; *condition |= RKCL_COND_REQ; - } - else if(strcmp(tmp_location, "all required") == 0) - { + } else if (strcmp(tmp_location, "all required") == 0) { *condition |= RKCL_COND_ALL; *condition |= RKCL_COND_REQ; - } - else - { + } else { *condition = RKCL_COND_INV; - return(NULL); + return (NULL); } - - /* Getting reference */ - if(*tmp_location2 != ' ' && tmp_location2[1] != '[') - { - return(NULL); + /* Get reference */ + if (*tmp_location2 != ' ' && tmp_location2[1] != '[') { + return (NULL); } - tmp_location2+=2; + tmp_location2 += 2; tmp_location = strchr(tmp_location2, ']'); - if(!tmp_location) - { - return(NULL); + if (!tmp_location) { + return (NULL); } *tmp_location = '\0'; - /* Copying reference */ + /* Copy reference */ strncpy(ref, tmp_location2, 255); - return(strdup(buf)); + return (strdup(buf)); } - - -/** char *_rkcl_get_pattern(char *value) - */ -char *_rkcl_get_pattern(char *value) +static char *_rkcl_get_pattern(char *value) { - while(*value != '\0') - { - if((*value == ' ') && (value[1] == '-') && - (value[2] == '>') && (value[3] == ' ')) - { + while (*value != '\0') { + if ((*value == ' ') && (value[1] == '-') && + (value[2] == '>') && (value[3] == ' ')) { *value = '\0'; value += 4; - return(value); + return (value); } value++; } - return(NULL); + return (NULL); } - - -/** char *_rkcl_get_value - */ -char *_rkcl_get_value(char *buf, int *type) +static char *_rkcl_get_value(char *buf, int *type) { char *tmp_str; char *value; - /* Zeroing type before using it --make sure return is valid + /* Zero type before using it to make sure return is valid * in case of error. */ *type = 0; value = strchr(buf, ':'); - if(value == NULL) - { - return(NULL); + if (value == NULL) { + return (NULL); } *value = '\0'; value++; tmp_str = strchr(value, ';'); - if(tmp_str == NULL) - { - return(NULL); + if (tmp_str == NULL) { + return (NULL); } *tmp_str = '\0'; - - /* Getting types - removing negate flag (using later) */ - if(*buf == '!') - { + /* Get types - removing negate flag (using later) */ + if (*buf == '!') { buf++; } - if(strcmp(buf, "f") == 0) - { + if (strcmp(buf, "f") == 0) { *type = RKCL_TYPE_FILE; - } - else if(strcmp(buf, "r") == 0) - { + } else if (strcmp(buf, "r") == 0) { *type = RKCL_TYPE_REGISTRY; - } - else if(strcmp(buf, "p") == 0) - { + } else if (strcmp(buf, "p") == 0) { *type = RKCL_TYPE_PROCESS; - } - else if(strcmp(buf, "d") == 0) - { + } else if (strcmp(buf, "d") == 0) { *type = RKCL_TYPE_DIR; - } - else - { - return(NULL); + } else { + return (NULL); } - return(value); + return (value); } - - -/** int rkcl_get_entry: - */ -int rkcl_get_entry(FILE *fp, char *msg, void *p_list_p) +int rkcl_get_entry(FILE *fp, const char *msg, OSList *p_list) { int type = 0, condition = 0; char *nbuf; - char buf[OS_SIZE_1024 +2]; - char root_dir[OS_SIZE_1024 +2]; - char final_file[2048 +1]; - char ref[255 +1]; - + char buf[OS_SIZE_1024 + 2]; + char root_dir[OS_SIZE_1024 + 2]; + char final_file[2048 + 1]; + char ref[255 + 1]; char *value; char *name = NULL; - OSStore *vars; - OSList *p_list = (OSList *)p_list_p; - - /* Cleaning up vars */ + /* Initialize variables */ memset(buf, '\0', sizeof(buf)); memset(root_dir, '\0', sizeof(root_dir)); memset(final_file, '\0', sizeof(final_file)); memset(ref, '\0', sizeof(ref)); - - - - - #ifdef WIN32 - /* Getting Windows rootdir */ - _rkcl_getrootdir(root_dir, sizeof(root_dir) -1); - if(root_dir[0] == '\0') - { +#ifdef WIN32 + /* Get Windows rootdir */ + _rkcl_getrootdir(root_dir, sizeof(root_dir) - 1); + if (root_dir[0] == '\0') { merror(INVALID_ROOTDIR, ARGV0); } - #endif - - - /* Getting variables */ +#endif + /* Get variables */ vars = OSStore_Create(); - - /* We first read all variables -- they must be defined at the top. */ - while(1) - { + /* We first read all variables -- they must be defined at the top */ + while (1) { int rc_code = 0; nbuf = _rkcl_getfp(fp, buf); - if(nbuf == NULL) - { + if (nbuf == NULL) { goto clean_return; } rc_code = _rkcl_get_vars(vars, nbuf); - if(rc_code == 0) - { + if (rc_code == 0) { break; - } - else if(rc_code == -1) - { + } else if (rc_code == -1) { merror(INVALID_RKCL_VAR, ARGV0, nbuf); goto clean_return; } } - - /* Getting first name */ + /* Get first name */ name = _rkcl_get_name(nbuf, ref, &condition); - if(name == NULL || condition == RKCL_COND_INV) - { + if (name == NULL || condition == RKCL_COND_INV) { merror(INVALID_RKCL_NAME, ARGV0, nbuf); goto clean_return; } - - - /* Getting the real entries. */ - do - { + /* Get the real entries */ + do { int g_found = 0; - - /* Getting entry name */ - if(name == NULL) - { - merror(INVALID_RKCL_NAME, ARGV0, "NULL"); - goto clean_return; - } - debug2("%s: DEBUG: Checking entry: '%s'.", ARGV0, name); - - /* Getting each value */ - do - { + /* Get each value */ + do { int negate = 0; int found = 0; value = NULL; nbuf = _rkcl_getfp(fp, buf); - if(nbuf == NULL) - { + if (nbuf == NULL) { break; } - - /* We first try to get the name, looking for new entries */ - if(_rkcl_is_name(nbuf)) - { + /* First try to get the name, looking for new entries */ + if (_rkcl_is_name(nbuf)) { break; } - - /* Getting value to look for */ + /* Get value to look for */ value = _rkcl_get_value(nbuf, &type); - if(value == NULL) - { + if (value == NULL) { merror(INVALID_RKCL_VALUE, ARGV0, nbuf); goto clean_return; } - - /* Getting negate value */ - if(*value == '!') - { + /* Get negate value */ + if (*value == '!') { negate = 1; value++; } - - /* Checking for a file. */ - if(type == RKCL_TYPE_FILE) - { + /* Check for a file */ + if (type == RKCL_TYPE_FILE) { char *pattern = NULL; char *f_value = NULL; - pattern = _rkcl_get_pattern(value); f_value = value; - - /* Getting any variable. */ - if(value[0] == '$') - { - f_value = OSStore_Get(vars, value); - if(!f_value) - { + /* Get any variable */ + if (value[0] == '$') { + f_value = (char *) OSStore_Get(vars, value); + if (!f_value) { merror(INVALID_RKCL_VAR, ARGV0, value); continue; } } - - #ifdef WIN32 - else if(value[0] == '\\') - { +#ifdef WIN32 + else if (value[0] == '\\') { final_file[0] = '\0'; - final_file[sizeof(final_file) -1] = '\0'; + final_file[sizeof(final_file) - 1] = '\0'; - snprintf(final_file, sizeof(final_file) -2, "%s%s", + snprintf(final_file, sizeof(final_file) - 2, "%s%s", root_dir, value); f_value = final_file; - } - else - { + } else { final_file[0] = '\0'; - final_file[sizeof(final_file) -1] = '\0'; + final_file[sizeof(final_file) - 1] = '\0'; ExpandEnvironmentStrings(value, final_file, - sizeof(final_file) -2); + sizeof(final_file) - 2); f_value = final_file; } - #endif - +#endif debug2("%s: DEBUG: Checking file: '%s'.", ARGV0, f_value); - if(rk_check_file(f_value, pattern)) - { + if (rk_check_file(f_value, pattern)) { debug1("%s: DEBUG: found file.", ARGV0); found = 1; } } - #ifdef WIN32 - /* Checking for a registry entry */ - else if(type == RKCL_TYPE_REGISTRY) - { +#ifdef WIN32 + /* Check for a registry entry */ + else if (type == RKCL_TYPE_REGISTRY) { char *entry = NULL; char *pattern = NULL; - - /* Looking for additional entries in the registry + /* Look for additional entries in the registry * and a pattern to match. */ entry = _rkcl_get_pattern(value); - if(entry) - { + if (entry) { pattern = _rkcl_get_pattern(entry); } - - debug2("%s: DEBUG: Checking registry: '%s'.", ARGV0, value); - if(is_registry(value, entry, pattern)) - { + if (is_registry(value, entry, pattern)) { debug2("%s: DEBUG: found registry.", ARGV0); found = 1; } } - #endif - - /* Checking for a directory. */ - else if(type == RKCL_TYPE_DIR) - { +#endif + /* Check for a directory */ + else if (type == RKCL_TYPE_DIR) { char *file = NULL; char *pattern = NULL; char *f_value = NULL; char *dir = NULL; - file = _rkcl_get_pattern(value); - if(file) - { - pattern = _rkcl_get_pattern(file); + if (!file) { + merror(INVALID_RKCL_VAR, ARGV0, value); + continue; } + pattern = _rkcl_get_pattern(file); - /* Getting any variable. */ - if(value[0] == '$') - { - f_value = OSStore_Get(vars, value); - if(!f_value) - { + /* Get any variable */ + if (value[0] == '$') { + f_value = (char *) OSStore_Get(vars, value); + if (!f_value) { merror(INVALID_RKCL_VAR, ARGV0, value); continue; } - } - else - { + } else { f_value = value; } - - /* Checking for multiple, comma separated directories. */ + /* Check for multiple comma separated directories */ dir = f_value; f_value = strchr(dir, ','); - if(f_value) - { + if (f_value) { *f_value = '\0'; } + while (dir) { - while(dir) - { debug2("%s: Checking dir: %s", ARGV0, dir); - if(rk_check_dir(dir, file, pattern)) - { - debug2("%s: DEBUG: Found dir.", ARGV0); - found = 1; + + short is_nfs = IsNFS(dir); + if( is_nfs == 1 && rootcheck.skip_nfs ) { + debug1("%s: DEBUG: rootcheck.skip_nfs enabled and %s is flagged as NFS.", ARGV0, dir); + } + else { + debug2("%s: DEBUG: %s => is_nfs=%d, skip_nfs=%d", ARGV0, dir, is_nfs, rootcheck.skip_nfs); + + if (rk_check_dir(dir, file, pattern)) { + debug2("%s: DEBUG: Found dir.", ARGV0); + found = 1; + } } - if(f_value) - { + if (f_value) { *f_value = ','; f_value++; dir = f_value; f_value = strchr(dir, ','); - if(f_value) - { + if (f_value) { *f_value = '\0'; } - } - else - { + } else { dir = NULL; } } } - - /* Checking for a process. */ - else if(type == RKCL_TYPE_PROCESS) - { + /* Check for a process */ + else if (type == RKCL_TYPE_PROCESS) { debug2("%s: DEBUG: Checking process: '%s'.", ARGV0, value); - if(is_process(value, p_list)) - { + if (is_process(value, p_list)) { debug2("%s: DEBUG: found process.", ARGV0); found = 1; } } - - /* Switching the values if ! is present */ - if(negate) - { - if(found) - { + /* Switch the values if ! is present */ + if (negate) { + if (found) { found = 0; - } - else - { + } else { found = 1; } } - - /** Checking the conditions **/ - if(condition & RKCL_COND_ANY) - { + /* Check the conditions */ + if (condition & RKCL_COND_ANY) { debug2("%s: DEBUG: Condition ANY.", ARGV0); - if(found) - { + if (found) { g_found = 1; } - } - /* Condition for ALL */ - else - { + } else { + /* Condition for ALL */ debug2("%s: DEBUG: Condition ALL.", ARGV0); - if(found && (g_found != -1)) - { + if (found && (g_found != -1)) { g_found = 1; - } - else - { + } else { g_found = -1; } } - }while(value != NULL); + } while (value != NULL); - - /* Alerting if necessary */ - if(g_found == 1) - { + /* Alert if necessary */ + if (g_found == 1) { int j = 0; - char op_msg[OS_SIZE_1024 +1]; + char op_msg[OS_SIZE_1024 + 1]; char **p_alert_msg = rootcheck.alert_msg; - while(1) - { - if(ref[0] != '\0') - { + while (1) { + if (ref[0] != '\0') { snprintf(op_msg, OS_SIZE_1024, "%s %s.%s" - " Reference: %s .",msg, name, - p_alert_msg[j]?p_alert_msg[j]:"\0", - ref); - } - else - { - snprintf(op_msg, OS_SIZE_1024, "%s %s.%s",msg, - name, p_alert_msg[j]?p_alert_msg[j]:"\0"); + " Reference: %s .", msg, name, + p_alert_msg[j] ? p_alert_msg[j] : "\0", + ref); + } else { + snprintf(op_msg, OS_SIZE_1024, "%s %s.%s", msg, + name, p_alert_msg[j] ? p_alert_msg[j] : "\0"); } - if((type == RKCL_TYPE_DIR) || (j == 0)) - { + if ((type == RKCL_TYPE_DIR) || (j == 0)) { notify_rk(ALERT_POLICY_VIOLATION, op_msg); } - if(p_alert_msg[j]) - { + if (p_alert_msg[j]) { free(p_alert_msg[j]); p_alert_msg[j] = NULL; j++; - if(!p_alert_msg[j]) + if (!p_alert_msg[j]) { break; - } - else - { + } + } else { break; } } - } - else - { + } else { int j = 0; - while(rootcheck.alert_msg[j]) - { + while (rootcheck.alert_msg[j]) { free(rootcheck.alert_msg[j]); rootcheck.alert_msg[j] = NULL; j++; } - - /* Checking if this entry is required for the rest of the file. */ - if(condition & RKCL_COND_REQ) - { + /* Check if this entry is required for the rest of the file */ + if (condition & RKCL_COND_REQ) { goto clean_return; } } - - /* Ending if we don't have anything else. */ - if(!nbuf) - { + /* End if we don't have anything else */ + if (!nbuf) { goto clean_return; } - - /* Cleaning up name. */ - if(name) - { + /* Clean up name */ + if (name) { free(name); name = NULL; } - - /* Getting name already read */ + /* Get name already read */ name = _rkcl_get_name(nbuf, ref, &condition); - if(!name) - { + if (!name) { merror(INVALID_RKCL_NAME, ARGV0, nbuf); goto clean_return; } - }while(nbuf != NULL); - + } while (nbuf != NULL); - - /* Cleaning up the memory */ - clean_return: - if(name) - { + /* Clean up memory */ +clean_return: + if (name) { free(name); name = NULL; } - vars = OSStore_Free(vars); - + OSStore_Free(vars); - return(1); + return (1); } - -/* EOF */