int rk_check_dir(const char *dir, const char *file, char *pattern) { int ret_code = 0; char f_name[PATH_MAX + 2]; struct dirent *entry; struct stat statbuf_local; DIR *dp = NULL; f_name[PATH_MAX + 1] = '\0'; dp = opendir(dir); if (!dp) { return (0); } while ((entry = readdir(dp)) != NULL) { /* Ignore . and .. */ if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) { continue; } /* Create new file + path string */ snprintf(f_name, PATH_MAX + 1, "%s/%s", dir, entry->d_name); /* Check if the read entry matches the provided file name */ if (strncasecmp(file, "r:", 2) == 0) { if (OS_Regex(file + 2, entry->d_name)) { if (rk_check_file(f_name, pattern)) { ret_code = 1; } } } else { /* ... otherwise try without regex */ if (OS_Match2(file, entry->d_name)) { if (rk_check_file(f_name, pattern)) { ret_code = 1; } } } /* Check if file is a directory */ if (lstat(f_name, &statbuf_local) == 0) { if (S_ISDIR(statbuf_local.st_mode)) { if (rk_check_dir(f_name, file, pattern)) { ret_code = 1; } } } } closedir(dp); return (ret_code); }
END_TEST START_TEST(test_fail_regex1) { int i; /* * Please note that all strings are \ escaped */ const char *tests[][3] = { {"abc", "abb", ""}, {"^ab", " ab", ""}, {"test", "tes", ""}, {"abcd", "abc", ""}, {"abbb", "abb", ""}, {"abbbbbbbb", "abbbbbbb", ""}, {"a|b|c| ", "def", ""}, {"lala$", "lalalalalal", ""}, {"^ab$", "abc", ""}, {"zzzz$", "zzzzzzzzzzzz ", ""}, {"^bin$|^shell$", "bina", ""}, {"^bin$|^shell$", "shella", ""}, {"^bin$|^shell$", "ashell", ""}, {"\\w+\\s+\\w+\\d+\\s$", "a aa11 ", ""}, {"^\\s+\\s l", " lala", ""}, {"test123test\\d+", "test123test", ""}, {"test123test\\d+$", "test123test", ""}, {"(lalala", "lalala", ""}, {"test123(\\d)", "test123a", ""}, {"\\(test)", "test", ""}, {"(\\w+)(\\d+)", "1 1", ""}, {NULL,NULL,NULL}, }; for(i=0; tests[i][0] != NULL ; i++) { ck_assert_msg(!OS_Regex(tests[i][0],tests[i][1]), "%s should have OS_Regex false with %s: Ref: %s", tests[i][0], tests[i][1], tests[i][2]); } }
/** int ReadActiveCommands(XML_NODE node, void *d1, void *d2) */ int ReadActiveCommands(XML_NODE node, void *d1, void *d2) { int i = 0; char *tmp_str = NULL; /* Xml values */ char *command_name = "name"; char *command_expect = "expect"; char *command_executable = "executable"; char *timeout_allowed = "timeout_allowed"; ar_command *tmp_command; /* Allocating the active-response command */ tmp_command = calloc(1, sizeof(ar_command)); if(!tmp_command) { merror(MEM_ERROR, ARGV0); return(-1); } tmp_command->name = NULL; tmp_command->expect= 0; tmp_command->executable = NULL; tmp_command->timeout_allowed = 0; /* Searching for the commands */ while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } if(strcmp(node[i]->element, command_name) == 0) { tmp_command->name = strdup(node[i]->content); } else if(strcmp(node[i]->element, command_expect) == 0) { tmp_str = strdup(node[i]->content); } else if(strcmp(node[i]->element, command_executable) == 0) { tmp_command->executable = strdup(node[i]->content); } else if(strcmp(node[i]->element, timeout_allowed) == 0) { if(strcmp(node[i]->content, "yes") == 0) tmp_command->timeout_allowed = 1; else if(strcmp(node[i]->content, "no") == 0) tmp_command->timeout_allowed = 0; else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } if(!tmp_command->name || !tmp_str || !tmp_command->executable) { merror(AR_CMD_MISS, ARGV0); return(-1); } /* Getting the expect */ if(strlen(tmp_str) > 4) { if(OS_Regex("user", tmp_str)) tmp_command->expect |= USERNAME; if(OS_Regex("srcip", tmp_str)) tmp_command->expect |= SRCIP; } free(tmp_str); tmp_str = NULL; /* Adding command to the list */ if(!OSList_AddData(d1, (void *)tmp_command)) { merror(LIST_ADD_ERROR, ARGV0); return(-1); } /* Done over here */ return(0); }
/** int ReadActiveResponses(XML_NODE node, void *d1, void *d2) * Generates a list with all active responses. */ int ReadActiveResponses(XML_NODE node, void *d1, void *d2) { FILE *fp; int i = 0; int r_ar = 0; int l_ar = 0; int rpt = 0; /* Xml options */ char *xml_ar_command = "command"; char *xml_ar_location = "location"; char *xml_ar_agent_id = "agent_id"; char *xml_ar_rules_id = "rules_id"; char *xml_ar_rules_group = "rules_group"; char *xml_ar_level = "level"; char *xml_ar_timeout = "timeout"; char *xml_ar_disabled = "disabled"; char *xml_ar_repeated = "repeated_offenders"; char *tmp_location; /* Currently active response */ active_response *tmp_ar; /* Opening shared ar file */ fp = fopen(DEFAULTARPATH, "a"); if(!fp) { merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH); return(-1); } chmod(DEFAULTARPATH, 0444); /* Allocating for the active-response */ tmp_ar = calloc(1, sizeof(active_response)); if(!tmp_ar) { merror(MEM_ERROR, ARGV0); return(-1); } /* Initializing variables */ tmp_ar->name = NULL; tmp_ar->command = NULL; tmp_ar->location = 0; tmp_ar->timeout = 0; tmp_ar->level = 0; tmp_ar->agent_id = NULL; tmp_ar->rules_id = NULL; tmp_ar->rules_group = NULL; tmp_ar->ar_cmd = NULL; tmp_location = NULL; /* Searching for the commands */ while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Command */ if(strcmp(node[i]->element, xml_ar_command) == 0) { tmp_ar->command = strdup(node[i]->content); } /* Target */ else if(strcmp(node[i]->element, xml_ar_location) == 0) { tmp_location = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_agent_id) == 0) { tmp_ar->agent_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_id) == 0) { tmp_ar->rules_id = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_rules_group) == 0) { tmp_ar->rules_group = strdup(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_level) == 0) { /* Level must be numeric */ if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } tmp_ar->level = atoi(node[i]->content); /* Making sure the level is valid */ if((tmp_ar->level < 0) || (tmp_ar->level > 20)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_timeout) == 0) { tmp_ar->timeout = atoi(node[i]->content); } else if(strcmp(node[i]->element, xml_ar_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) { ar_flag = -1; } else if(strcmp(node[i]->content, "no") == 0) { /* Don't do anything if disabled is set to "no" */ } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_ar_repeated) == 0) { /* Nothing - we deal with it on execd. */ rpt = 1; } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } /* Checking if ar is disabled */ if(ar_flag == -1) { fclose(fp); return(0); } /* Command and location must be there */ if(!tmp_ar->command || !tmp_location) { if(rpt == 1) { fclose(fp); return(0); } merror(AR_MISS, ARGV0); return(-1); } /* analysisd */ if(OS_Regex("AS|analysisd|analysis-server|server", tmp_location)) { tmp_ar->location|= AS_ONLY; } if(OS_Regex("local", tmp_location)) { tmp_ar->location|= REMOTE_AGENT; } if(OS_Regex("defined-agent", tmp_location)) { if(!tmp_ar->agent_id) { merror(AR_DEF_AGENT, ARGV0); return(-1); } tmp_ar->location|= SPECIFIC_AGENT; } if(OS_Regex("all|any", tmp_location)) { tmp_ar->location|=ALL_AGENTS; } /* If we didn't set any value for the location */ if(tmp_ar->location == 0) { merror(AR_INV_LOC, ARGV0, tmp_location); return(-1); } /* cleaning tmp_location */ free(tmp_location); tmp_location = NULL; /* Checking if command name is valid */ { OSListNode *my_commands_node; my_commands_node = OSList_GetFirstNode(d1); while(my_commands_node) { ar_command *my_command; my_command = (ar_command *)my_commands_node->data; if(strcmp(my_command->name, tmp_ar->command) == 0) { tmp_ar->ar_cmd = my_command; break; } my_commands_node = OSList_GetNextNode(d1); } /* Didn't find a valid command */ if(tmp_ar->ar_cmd == NULL) { merror(AR_INV_CMD, ARGV0, tmp_ar->command); return(-1); } } /* Checking if timeout is allowed */ if(tmp_ar->timeout && !tmp_ar->ar_cmd->timeout_allowed) { merror(AR_NO_TIMEOUT, ARGV0, tmp_ar->ar_cmd->name); return(-1); } /* d1 is the active response list */ if(!OSList_AddData(d2, (void *)tmp_ar)) { merror(LIST_ADD_ERROR, ARGV0); return(-1); } /* Setting a unique active response name */ tmp_ar->name = calloc(OS_FLSIZE +1, sizeof(char)); if(!tmp_ar->name) { ErrorExit(MEM_ERROR, ARGV0); } snprintf(tmp_ar->name, OS_FLSIZE, "%s%d", tmp_ar->ar_cmd->name, tmp_ar->timeout); /* Adding to shared file */ fprintf(fp, "%s - %s - %d\n", tmp_ar->name, tmp_ar->ar_cmd->executable, tmp_ar->timeout); /* Setting the configs to start the right queues */ if(tmp_ar->location & AS_ONLY) { l_ar = 1; } if(tmp_ar->location & ALL_AGENTS) { r_ar = 1; } if(tmp_ar->location & REMOTE_AGENT) { r_ar = 1; l_ar = 1; } if(tmp_ar->location & SPECIFIC_AGENT) { r_ar = 1; } /* Setting the configuration for the active response */ if(r_ar && (!(ar_flag & REMOTE_AR))) { ar_flag|= REMOTE_AR; } if(l_ar && (!(ar_flag & LOCAL_AR))) { ar_flag|= LOCAL_AR; } /* Closing shared file for active response */ fclose(fp); /* Done over here */ return(0); }
/** int pt_matches(char *str, char *pattern) * Checks if the specific pattern is present on str. * A pattern can be preceeded by: * =: (for equal) - default - strcasecmp * r: (for ossec regexes) * >: (for strcmp greater) * <: (for strcmp lower) * * Multiple patterns can be specified by using " && " between them. * All of them must match for it to return true. */ int pt_matches(char *str, char *pattern) { int neg = 0; int ret_code = 0; char *tmp_pt = pattern; char *tmp_ret = NULL; /* If string we null, we don't match */ if(str == NULL) { 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 */ tmp_ret = tmp_pt; *tmp_pt = '\0'; tmp_pt += 4; } else { tmp_pt = NULL; } /* Checking for negate values */ neg = 0; ret_code = 0; if(*pattern == '!') { pattern++; neg = 1; } /* Doing strcasecmp */ if(strncasecmp(pattern, "=:", 2) == 0) { pattern += 2; if(strcasecmp(pattern, str) == 0) { ret_code = 1; } } else if(strncasecmp(pattern, "r:", 2) == 0) { pattern += 2; if(OS_Regex(pattern, str)) { debug1("pattern: %s matches %s.",pattern, str); ret_code = 1; } } else if(strncasecmp(pattern, "<:", 2) == 0) { pattern += 2; if(strcmp(pattern, str) < 0) { ret_code = 1; } } else if(strncasecmp(pattern, ">:", 2) == 0) { pattern += 2; if(strcmp(pattern, str) > 0) { ret_code = 1; } } else { #ifdef WIN32 char final_file[2048 +1]; /* Try to get Windows variable */ if(*pattern == '%') { final_file[0] = '\0'; final_file[2048] = '\0'; ExpandEnvironmentStrings(pattern, final_file, 2047); } else { strncpy(final_file, pattern, 2047); } /* Comparing against the expanded variable */ if(strcasecmp(final_file, str) == 0) { ret_code = 1; } #else if(strcasecmp(pattern, str) == 0) { ret_code = 1; } #endif } /* Fixing tmp_ret entry */ if(tmp_ret != NULL) { *tmp_ret = ' '; tmp_ret = NULL; } /* If we have "!", return true if we don't match */ if(neg == 1) { if(ret_code) { ret_code = 0; break; } } else { if(!ret_code) { ret_code = 0; break; } } ret_code = 1; pattern = tmp_pt; } return(ret_code); }
/** main **/ int main(int argc, char **argv) { char *pattern; char msg[OS_MAXSTR +1]; memset(msg, '\0', OS_MAXSTR +1); OSRegex regex; OSMatch matcher; OS_SetName(ARGV0); /* user arguments */ if(argc != 2) { helpmsg(); return(-1); } /* User options */ if(strcmp(argv[1], "-h") == 0) { helpmsg(); return(-1); } os_strdup(argv[1], pattern); if(!OSRegex_Compile(pattern, ®ex, 0)) { printf("pattern does not compile with OSRegex_Compile\n"); return(-1); } if(!OSMatch_Compile(pattern, &matcher, 0)) { printf("pattern does not compile with OSMatch_Compile\n"); return(-1); } while((fgets(msg, OS_MAXSTR, stdin)) != NULL) { /* Removing new line. */ if(msg[strlen(msg) -1] == '\n') msg[strlen(msg) -1] = '\0'; /* Make sure we ignore blank lines. */ if(strlen(msg) < 2) { continue; } if(OSRegex_Execute(msg, ®ex)) printf("+OSRegex_Execute: %s\n",msg); /* else printf("-OSRegex_Execute: \n"); */ if(OS_Regex(pattern, msg)) printf("+OS_Regex : %s\n", msg); /* else printf("-OS_Regex: \n"); */ if(OSMatch_Execute(msg, strlen(msg), &matcher)) printf("+OSMatch_Compile: %s\n", msg); if(OS_Match2(pattern, msg)) printf("+OS_Match2 : %s\n", msg); } return(0); }
END_TEST START_TEST(test_success_regex1) { int i; /* * Please note that all strings are \ escaped */ const char *tests[][3] = { {"abc", "abcd", ""}, {"abcd", "abcd", ""}, {"a", "a", ""}, {"a", "aa", ""}, {"^a", "ab", ""}, {"test", "testa", ""}, {"test", "testest", ""}, {"lalaila", "lalalalaila", ""}, {"abc|cde", "cde", ""}, {"^aa|ee|ii|oo|uu", "dfgdsii", ""}, {"Abc", "abc", ""}, {"ZBE", "zbe", ""}, {"ABC", "ABc", ""}, {"^A", "a", ""}, {"a|E", "abcdef", ""}, {"daniel", "daniel", ""}, {"DANIeL", "daNIel", ""}, {"^abc ", "abc ", ""}, {"ddd|eee|fff|ggg|ggg|hhh|iii", "iii", ""}, {"kwo|fe|fw|wfW|edW|dwDF|WdW|dw|d|^la", "la", ""}, {"^a", "a", ""}, {"^ab$", "ab", ""}, {"c$", "c", ""}, {"c$", "lalalalac", ""}, {"^bin$|^shell$", "bin", ""}, {"^bin$|^shell$", "shell", ""}, {"^bin$|^shell$|^ftp$", "shell", ""}, {"^bin$|^shell$|^ftp$", "ftp", ""}, {"\\s+123", " 123", ""}, {"\\s*123", "123", ""}, {"\\s123", " 123", ""}, {"\\w+\\s+\\w+", "a 1", ""}, {"\\w+\\d+\\w+\\s+", "ab12fb12fd12 ", ""}, {"^\\s*\\w\\s*\\w+", "a l a a", ""}, {"\\w+\\s+\\w+\\d+\\s$", "a aa11 ", ""}, {"^su\\S*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""}, {"^su\\s*: BAD su", "su: BAD SU dcid to root on /dev/ttyp0", ""}, {"^abc\\sabc", "abc abcd", ""}, {"^abc\\s\\s*abc", "abc abcd", ""}, {"^\\s+\\sl", " lala", ""}, {"^\\s*\\sl", " lala", ""}, {"^\\s\\s+l", " lala", ""}, {"^\\s+\\s l", " lala", ""}, {"^\\s*\\s lal\\w$", " lala", ""}, {"test123test\\d+$", "test123test123", ""}, {"^kernel: \\S+ \\.+ SRC=\\S+ DST=\\S+ \\.+ PROTO=\\w+ SPT=\\d+ DPT=\\d+ ", "kernel: IPTABLE IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:00:03:93:db:2e:b4:08:00 SRC=10.4.11.40 DST=255.255.255.255 LEN=180 TOS=0x00 PREC=0x00 TTL=64 ID=4753 PROTO=UDP SPT=49320 DPT=2222 LEN=160", ""}, {"test (\\w+)la", "test abclala", ""}, {"(\\w+) (\\w+)", "wofl wofl", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:469:3] ICMP PING NMAP [Classification: Attempted Information Leak] [Priority: 2]: {ICMP} 10.4.12.26 -> 10.4.10.231", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:408:5] ICMP Echo Reply [Classification: Misc Activity] [Priority: 3]: {ICMP} 10.4.10.231 -> 10.4.12.26", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:162", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1420:11] SNMP trap tcp [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37021 -> 10.4.10.231:162", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:669 -> 10.4.3.20:111", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:590:12] RPC portmap ypserv request UDP [Classification: Decode of an RPC Query] [Priority: 2]: {UDP} 10.4.11.94:670 -> 10.4.3.20:111", ""}, {"^\\S+ [(\\d+:\\d+:\\d+)] \\.+ (\\d+.\\d+.\\d+.\\d+)\\p*\\d* -> (\\d+.\\d+.\\d+.\\d+)\\p*", "snort: [1:1421:11] SNMP AgentX/tcp request [Classification: Attempted Information Leak] [Priority: 2]: {TCP} 10.4.12.26:37020 -> 10.4.10.231:705", ""}, {NULL,NULL,NULL} }; for(i=0; tests[i][0] != NULL ; i++) { ck_assert_msg(OS_Regex(tests[i][0],tests[i][1]), "%s should have OS_Regex true with %s: Ref: %s", tests[i][0], tests[i][1], tests[i][2]); } }