-/* @(#) $Id: ./src/config/active-response.c, 2011/09/08 dcid Exp $
- */
-
/* Copyright (C) 2009 Trend Micro Inc.
* All right reserved.
*
* Foundation
*/
+#ifndef WIN32
+#include <sys/types.h>
+#include <grp.h>
+#endif
#include "shared.h"
#include "os_xml/os_xml.h"
#include "os_regex/os_regex.h"
-
#include "active-response.h"
+#include "config.h"
+/* Global variables */
+int ar_flag = 0;
-/** int ReadActiveResponses(XML_NODE node, void *d1, void *d2)
- * Generates a list with all active responses.
- */
+
+/* Generate a list with all active responses */
int ReadActiveResponses(XML_NODE node, void *d1, void *d2)
{
+ OSList *l1 = (OSList *) d1;
+ OSList *l2 = (OSList *) 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";
+ const char *xml_ar_command = "command";
+ const char *xml_ar_location = "location";
+ const char *xml_ar_agent_id = "agent_id";
+ const char *xml_ar_rules_id = "rules_id";
+ const char *xml_ar_rules_group = "rules_group";
+ const char *xml_ar_level = "level";
+ const char *xml_ar_timeout = "timeout";
+ const char *xml_ar_disabled = "disabled";
+ const char *xml_ar_repeated = "repeated_offenders";
char *tmp_location;
-
/* Currently active response */
active_response *tmp_ar;
-
- /* Opening shared ar file */
+ /* Open shared ar file */
fp = fopen(DEFAULTARPATH, "a");
- if(!fp)
- {
- merror(FOPEN_ERROR, ARGV0, DEFAULTARPATH);
- return(-1);
+ if (!fp) {
+ merror(FOPEN_ERROR, __local_name, DEFAULTARPATH, errno, strerror(errno));
+ return (-1);
}
- chmod(DEFAULTARPATH, 0440);
+#ifndef WIN32
+ struct group *os_group;
+ if ((os_group = getgrnam(USER)) == NULL) {
+ merror("Could not get ossec gid.");
+ fclose(fp);
+ return (-1);
+ }
- /* Allocating for the active-response */
- tmp_ar = calloc(1, sizeof(active_response));
- if(!tmp_ar)
- {
- merror(MEM_ERROR, ARGV0);
- return(-1);
+ if ((chown(DEFAULTARPATH, (uid_t) - 1, os_group->gr_gid)) == -1) {
+ merror("Could not change the group to ossec: %d", errno);
+ fclose(fp);
+ return (-1);
+ }
+#endif
+
+ if ((chmod(DEFAULTARPATH, 0440)) == -1) {
+ merror("Could not chmod to 0440: %d", errno);
+ fclose(fp);
+ return (-1);
}
- /* Initializing variables */
+ /* Allocate for the active-response */
+ tmp_ar = (active_response *) calloc(1, sizeof(active_response));
+ if (!tmp_ar) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ fclose(fp);
+ return (-1);
+ }
+
+ /* Initialize variables */
tmp_ar->name = NULL;
tmp_ar->command = NULL;
tmp_ar->location = 0;
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);
+ /* Search for the commands */
+ while (node[i]) {
+ if (!node[i]->element) {
+ merror(XML_ELEMNULL, __local_name);
+ goto error_invalid;
+ } else if (!node[i]->content) {
+ merror(XML_VALUENULL, __local_name, node[i]->element);
+ goto error_invalid;
}
/* Command */
- if(strcmp(node[i]->element, xml_ar_command) == 0)
- {
+ 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)
- {
+ else if (strcmp(node[i]->element, xml_ar_location) == 0) {
+ free(tmp_location);
tmp_location = strdup(node[i]->content);
- }
- else if(strcmp(node[i]->element, xml_ar_agent_id) == 0)
- {
+ } 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)
- {
+ } 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)
- {
+ } 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)
- {
+ } 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);
+ if (!OS_StrIsNum(node[i]->content)) {
+ merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
+ goto error_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);
+ /* Make sure the level is valid */
+ if ((tmp_ar->level < 0) || (tmp_ar->level > 20)) {
+ merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
+ goto error_invalid;
}
- }
- else if(strcmp(node[i]->element, xml_ar_timeout) == 0)
- {
+ } 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)
- {
+ } 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)
- {
+ } else if (strcmp(node[i]->content, "no") == 0) {
/* Don't do anything if disabled is set to "no" */
+ } else {
+ merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
+ goto error_invalid;
}
- 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. */
+ } 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);
+ } else {
+ merror(XML_INVELEM, __local_name, node[i]->element);
+ goto error_invalid;
}
i++;
}
- /* Checking if ar is disabled */
- if(ar_flag == -1)
- {
+ /* Check if ar is disabled */
+ if (ar_flag == -1) {
+ /* reset ar_flag, the next ar command may not be disabled */
+ ar_flag = 0;
+ debug1("active response command '%s' is disabled", tmp_ar->command);
fclose(fp);
- return(0);
+ free(tmp_ar);
+ free(tmp_location);
+ return (0);
}
/* Command and location must be there */
- if(!tmp_ar->command || !tmp_location)
- {
- if(rpt == 1)
- {
- fclose(fp);
- return(0);
+ if (!tmp_ar->command || !tmp_location) {
+ debug1("command or location missing");
+ fclose(fp);
+ free(tmp_ar);
+ free(tmp_location);
+
+ if (rpt == 1) {
+ return (0);
}
- merror(AR_MISS, ARGV0);
- return(-1);
+ merror(AR_MISS, __local_name);
+ return (-1);
}
/* analysisd */
- if(OS_Regex("AS|analysisd|analysis-server|server", tmp_location))
- {
- tmp_ar->location|= AS_ONLY;
+ 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("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);
+ if (OS_Regex("defined-agent", tmp_location)) {
+ if (!tmp_ar->agent_id) {
+ debug1("'defined-agent' agent_id not defined");
+ merror(AR_DEF_AGENT, __local_name);
+ fclose(fp);
+ free(tmp_ar);
+ free(tmp_location);
+ return (-1);
}
- tmp_ar->location|= SPECIFIC_AGENT;
+ tmp_ar->location |= SPECIFIC_AGENT;
}
- if(OS_Regex("all|any", tmp_location))
- {
- tmp_ar->location|=ALL_AGENTS;
+ 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);
+ if (tmp_ar->location == 0) {
+ debug1("no location defined");
+ merror(AR_INV_LOC, __local_name, tmp_location);
+ fclose(fp);
+ free(tmp_ar);
+ free(tmp_location);
+ return (-1);
}
-
- /* cleaning tmp_location */
+ /* Clean tmp_location */
free(tmp_location);
tmp_location = NULL;
-
- /* Checking if command name is valid */
+ /* Check if command name is valid */
{
OSListNode *my_commands_node;
- my_commands_node = OSList_GetFirstNode(d1);
- while(my_commands_node)
- {
+ my_commands_node = OSList_GetFirstNode(l1);
+ 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)
- {
+ if (strcmp(my_command->name, tmp_ar->command) == 0) {
tmp_ar->ar_cmd = my_command;
break;
}
- my_commands_node = OSList_GetNextNode(d1);
+ my_commands_node = OSList_GetNextNode(l1);
}
/* Didn't find a valid command */
- if(tmp_ar->ar_cmd == NULL)
- {
- merror(AR_INV_CMD, ARGV0, tmp_ar->command);
- return(-1);
+ if (tmp_ar->ar_cmd == NULL) {
+ debug1("invalid command");
+ merror(AR_INV_CMD, __local_name, tmp_ar->command);
+ fclose(fp);
+ free(tmp_ar);
+ 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);
+ /* Check if timeout is allowed */
+ if (tmp_ar->timeout && !tmp_ar->ar_cmd->timeout_allowed) {
+ debug1("timeout is not allowed");
+ merror(AR_NO_TIMEOUT, __local_name, tmp_ar->ar_cmd->name);
+ fclose(fp);
+ free(tmp_ar);
+ return (-1);
}
/* d1 is the active response list */
- if(!OSList_AddData(d2, (void *)tmp_ar))
- {
- merror(LIST_ADD_ERROR, ARGV0);
- return(-1);
+ if (!OSList_AddData(l2, (void *)tmp_ar)) {
+ merror(LIST_ADD_ERROR, __local_name);
+ fclose(fp);
+ free(tmp_ar);
+ 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);
+ /* Set a unique active response name */
+ tmp_ar->name = (char *) calloc(OS_FLSIZE + 1, sizeof(char));
+ if (!tmp_ar->name) {
+ ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno));
}
snprintf(tmp_ar->name, OS_FLSIZE, "%s%d",
- tmp_ar->ar_cmd->name,
- tmp_ar->timeout);
-
+ tmp_ar->ar_cmd->name,
+ tmp_ar->timeout);
- /* Adding to shared file */
+ /* Add to shared file */
+ debug1("writing command '%s' to '%s'", tmp_ar->command, DEFAULTARPATH);
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)
- {
+ /* Set the configs to start the right queues */
+ if (tmp_ar->location & AS_ONLY) {
l_ar = 1;
}
- if(tmp_ar->location & ALL_AGENTS)
- {
+ if (tmp_ar->location & ALL_AGENTS) {
r_ar = 1;
}
- if(tmp_ar->location & REMOTE_AGENT)
- {
+ if (tmp_ar->location & REMOTE_AGENT) {
r_ar = 1;
l_ar = 1;
}
- if(tmp_ar->location & SPECIFIC_AGENT)
- {
+ 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;
+ /* Set 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;
+ if (l_ar && (!(ar_flag & LOCAL_AR))) {
+ ar_flag |= LOCAL_AR;
}
- /* Closing shared file for active response */
+ /* Close shared file for active response */
fclose(fp);
/* Done over here */
- return(0);
-}
+ return (0);
+error_invalid:
+ /* In case of an error clean up first*/
+ fclose(fp);
+ free(tmp_ar);
+ free(tmp_location);
+ return (OS_INVALID);
+}
-/** int ReadActiveCommands(XML_NODE node, void *d1, void *d2)
- */
-int ReadActiveCommands(XML_NODE node, void *d1, void *d2)
+int ReadActiveCommands(XML_NODE node, void *d1, __attribute__((unused)) void *d2)
{
+ OSList *l1 = (OSList *) d1;
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";
+ const char *command_name = "name";
+ const char *command_expect = "expect";
+ const char *command_executable = "executable";
+ const 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);
+ /* Allocate the active-response command */
+ tmp_command = (ar_command *) calloc(1, sizeof(ar_command));
+ if (!tmp_command) {
+ merror(MEM_ERROR, __local_name, errno, strerror(errno));
+ return (-1);
}
tmp_command->name = NULL;
- tmp_command->expect= 0;
+ 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);
+ /* Search for the commands */
+ while (node[i]) {
+ if (!node[i]->element) {
+ merror(XML_ELEMNULL, __local_name);
+ free(tmp_str);
+ free(tmp_command);
+ return (OS_INVALID);
+ } else if (!node[i]->content) {
+ merror(XML_VALUENULL, __local_name, node[i]->element);
+ free(tmp_str);
+ free(tmp_command);
+ 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)
- {
+ if (strcmp(node[i]->element, command_name) == 0) {
tmp_command->name = strdup(node[i]->content);
- }
- else if(strcmp(node[i]->element, command_expect) == 0)
- {
+ } else if (strcmp(node[i]->element, command_expect) == 0) {
+ free(tmp_str);
tmp_str = strdup(node[i]->content);
- }
- else if(strcmp(node[i]->element, command_executable) == 0)
- {
+ } 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)
+ } 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)
+ } 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_VALUEERR, __local_name, node[i]->element, node[i]->content);
+ free(tmp_str);
+ free(tmp_command);
+ return (OS_INVALID);
}
- }
- else
- {
- merror(XML_INVELEM, ARGV0, node[i]->element);
- return(OS_INVALID);
+ } else {
+ merror(XML_INVELEM, __local_name, node[i]->element);
+ free(tmp_str);
+ free(tmp_command);
+ return (OS_INVALID);
}
i++;
}
- if(!tmp_command->name || !tmp_str || !tmp_command->executable)
- {
- merror(AR_CMD_MISS, ARGV0);
- return(-1);
+ if (!tmp_command->name || !tmp_str || !tmp_command->executable) {
+ merror(AR_CMD_MISS, __local_name);
+ free(tmp_str);
+ free(tmp_command);
+ return (-1);
}
-
- /* Getting the expect */
- if(strlen(tmp_str) >= 4)
- {
- if(OS_Regex("user", tmp_str))
+ /* Get the expect */
+ if (strlen(tmp_str) >= 4) {
+ if (OS_Regex("user", tmp_str)) {
tmp_command->expect |= USERNAME;
- if(OS_Regex("srcip", tmp_str))
+ }
+ if (OS_Regex("srcip", tmp_str)) {
tmp_command->expect |= SRCIP;
+ }
+ if (OS_Regex("filename", tmp_str)) {
+ tmp_command->expect |= FILENAME;
+ }
}
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);
+ /* Add command to the list */
+ if (!OSList_AddData(l1, (void *)tmp_command)) {
+ merror(LIST_ADD_ERROR, __local_name);
+ free(tmp_command);
+ return (-1);
}
-
- /* Done over here */
- return(0);
+ return (0);
}
-
-/* EOF */