new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / alerts / exec.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include "shared.h"
11 #include "rules.h"
12 #include "alerts.h"
13 #include "config.h"
14 #include "active-response.h"
15 #include "os_net/os_net.h"
16 #include "os_regex/os_regex.h"
17 #include "os_execd/execd.h"
18 #include "eventinfo.h"
19
20
21 void OS_Exec(int execq, int arq, const Eventinfo *lf, const active_response *ar)
22 {
23     char exec_msg[OS_SIZE_1024 + 1];
24     const char *ip;
25     const char *user;
26     char *filename = NULL;
27
28     ip = user = "-";
29
30     /* Clean the IP */
31     if (lf->srcip && (ar->ar_cmd->expect & SRCIP)) {
32         if (strncmp(lf->srcip, "::ffff:", 7) == 0) {
33             ip = lf->srcip + 7;
34         } else {
35             ip = lf->srcip;
36         }
37
38         /* Check if IP is to be ignored */
39         if (Config.allow_list) {
40             if (OS_IPFoundList(ip, Config.allow_list)) {
41                 return;
42             }
43         }
44
45         /* Check if it is a hostname */
46         if (Config.hostname_allow_list) {
47             size_t srcip_size;
48             char **wl;
49
50             srcip_size = strlen(ip);
51
52             wl = Config.hostname_allow_list;
53             while (*wl) {
54                 if (strncmp(*wl, ip, srcip_size) == 0) {
55                     return;
56                 }
57                 wl++;
58             }
59         }
60     }
61
62     /* Get username */
63     if (lf->dstuser && (ar->ar_cmd->expect & USERNAME)) {
64         user = lf->dstuser;
65     }
66
67     /* Get filename */
68     if (lf->filename && (ar->ar_cmd->expect & FILENAME)) {
69         filename = os_shell_escape(lf->filename);
70     }
71
72     /* Active Response on the server
73      * The response must be here if the ar->location is set to AS
74      * or the ar->location is set to local (REMOTE_AGENT) and the
75      * event location is from here.
76      */
77     if ((ar->location & AS_ONLY) ||
78             ((ar->location & REMOTE_AGENT) && (lf->location[0] != '(')) ) {
79         if (!(Config.ar & LOCAL_AR)) {
80             goto cleanup;
81         }
82
83         snprintf(exec_msg, OS_SIZE_1024,
84                  "%s %s %s %ld.%ld %d %s %s",
85                  ar->name,
86                  user,
87                  ip,
88                  (long int)lf->time,
89                  __crt_ftell,
90                  lf->generated_rule->sigid,
91                  lf->location,
92                  filename ? filename : "-");
93         if (execq < 1) {
94             merror("%s: Error communicating with execd (q < 1).", ARGV0);
95         }
96
97         if (OS_SendUnix(execq, exec_msg, 0) < 0) {
98             merror("%s: Error communicating with execd.", ARGV0);
99         }
100     }
101
102     /* Active Response to the forwarder */
103     else if ((Config.ar & REMOTE_AR)) {
104         int rc;
105         /* If lf->location start with a ( was generated by remote agent and its
106          * ID is included in lf->location if missing then it must have been
107          * generated by the local analysisd, so prepend a false id tag */
108         if (lf->location[0] == '(') {
109             snprintf(exec_msg, OS_SIZE_1024,
110                      "%s %c%c%c %s %s %s %s %ld.%ld %d %s %s",
111                      lf->location,
112                      (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C,
113                      (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C,
114                      (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C,
115                      ar->agent_id != NULL ? ar->agent_id : "(null)",
116                      ar->name,
117                      user,
118                      ip,
119                      (long int)lf->time,
120                      __crt_ftell,
121                      lf->generated_rule->sigid,
122                      lf->location,
123                      filename);
124         } else {
125             snprintf(exec_msg, OS_SIZE_1024,
126                      "(local_source) %s %c%c%c %s %s %s %s %ld.%ld %d %s %s",
127                      lf->location,
128                      (ar->location & ALL_AGENTS) ? ALL_AGENTS_C : NONE_C,
129                      (ar->location & REMOTE_AGENT) ? REMOTE_AGENT_C : NONE_C,
130                      (ar->location & SPECIFIC_AGENT) ? SPECIFIC_AGENT_C : NONE_C,
131                      ar->agent_id != NULL ? ar->agent_id : "(null)",
132                      ar->name,
133                      user,
134                      ip,
135                      (long int)lf->time,
136                      __crt_ftell,
137                      lf->generated_rule->sigid,
138                      lf->location,
139                      filename);
140         }
141
142         if ((rc = OS_SendUnix(arq, exec_msg, 0)) < 0) {
143             if (rc == OS_SOCKBUSY) {
144                 merror("%s: AR socket busy.", ARGV0);
145             } else {
146                 merror("%s: AR socket error (shutdown?).", ARGV0);
147             }
148             merror("%s: Error communicating with ar queue (%d).", ARGV0, rc);
149         }
150     }
151
152     cleanup:
153
154     /* Clean up Memory */
155     free(filename);
156
157     return;
158 }
159