new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_execd / win_execd.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 #ifdef WIN32
11
12 #include "shared.h"
13 #include "list_op.h"
14 #include "os_regex/os_regex.h"
15 #include "os_net/os_net.h"
16 #include "execd.h"
17
18 #ifdef ARGV0
19 #undef ARGV0
20 #endif
21
22 #define ARGV0 "ossec-execd"
23
24 /* Timeout list */
25 OSList *timeout_list;
26 OSListNode *timeout_node;
27
28
29 int WinExecd_Start()
30 {
31     int c;
32     int test_config = 0;
33     char *cfg = DEFAULTCPATH;
34
35     /* Read config */
36     if ((c = ExecdConfig(cfg)) < 0) {
37         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
38     }
39
40     /* Exit if test_config */
41     if (test_config) {
42         return (0);
43     }
44
45     /* Active response disabled */
46     if (c == 1) {
47         verbose(EXEC_DISABLED, ARGV0);
48         return (0);
49     }
50
51     /* Create list for timeout */
52     timeout_list = OSList_Create();
53     if (!timeout_list) {
54         ErrorExit(LIST_ERROR, ARGV0);
55     }
56
57     /* Start up message */
58     verbose(STARTUP_MSG, ARGV0, getpid());
59
60     return (1);
61 }
62
63 void WinTimeoutRun(int curr_time)
64 {
65     /* Check if there is any timed out command to execute */
66     timeout_node = OSList_GetFirstNode(timeout_list);
67     while (timeout_node) {
68         timeout_data *list_entry;
69
70         list_entry = (timeout_data *)timeout_node->data;
71
72         /* Timed out */
73         if ((curr_time - list_entry->time_of_addition) >
74                 list_entry->time_to_block) {
75             ExecCmd_Win32(list_entry->command[0]);
76
77             /* Delete currently node - already sets the pointer to next */
78             OSList_DeleteCurrentlyNode(timeout_list);
79             timeout_node = OSList_GetCurrentlyNode(timeout_list);
80
81             /* Clear the memory */
82             FreeTimeoutEntry(list_entry);
83         }
84
85         else {
86             timeout_node = OSList_GetNextNode(timeout_list);
87         }
88     }
89 }
90
91 void WinExecdRun(char *exec_msg)
92 {
93     time_t curr_time;
94
95     int i, j;
96     int timeout_value;
97     int added_before = 0;
98
99     char **timeout_args;
100
101     char *tmp_msg = NULL;
102     char *name;
103     char *command;
104     char *cmd_user;
105     char *cmd_ip;
106     char buffer[OS_MAXSTR + 1];
107
108     timeout_data *timeout_entry;
109
110     /* Current time */
111     curr_time = time(0);
112
113     /* Get application name */
114     name = exec_msg;
115
116     /* Zero the name */
117     tmp_msg = strchr(exec_msg, ' ');
118     if (!tmp_msg) {
119         merror(EXECD_INV_MSG, ARGV0, exec_msg);
120         return;
121     }
122     *tmp_msg = '\0';
123     tmp_msg++;
124
125     /* Get user */
126     cmd_user = tmp_msg;
127     tmp_msg = strchr(tmp_msg, ' ');
128     if (!tmp_msg) {
129         merror(EXECD_INV_MSG, ARGV0, cmd_user);
130         return;
131     }
132     *tmp_msg = '\0';
133     tmp_msg++;
134
135     /* Get IP */
136     cmd_ip = tmp_msg;
137     tmp_msg = strchr(tmp_msg, ' ');
138     if (!tmp_msg) {
139         merror(EXECD_INV_MSG, ARGV0, cmd_ip);
140         return;
141     }
142     *tmp_msg = '\0';
143     tmp_msg++;
144
145     /* Get the command to execute (valid name) */
146     command = GetCommandbyName(name, &timeout_value);
147     if (!command) {
148         ReadExecConfig();
149         command = GetCommandbyName(name, &timeout_value);
150         if (!command) {
151             merror(EXEC_INV_NAME, ARGV0, name);
152             return;
153         }
154     }
155
156     /* Command not present */
157     if (command[0] == '\0') {
158         return;
159     }
160
161     /* Allocate memory for the timeout argument */
162     os_calloc(MAX_ARGS + 2, sizeof(char *), timeout_args);
163
164     /* Add initial variables to the timeout cmd */
165     snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"",
166              command, DELETE_ENTRY, cmd_user, cmd_ip, tmp_msg);
167     os_strdup(buffer, timeout_args[0]);
168     timeout_args[1] = NULL;
169
170     /* Get size for the strncmp */
171     i = 0, j = 0;
172     while (buffer[i] != '\0') {
173         if (buffer[i] == ' ') {
174             j++;
175         }
176
177         i++;
178         if (j == 4) {
179             break;
180         }
181     }
182
183     /* Check if this command was already executed */
184     timeout_node = OSList_GetFirstNode(timeout_list);
185     added_before = 0;
186
187     while (timeout_node) {
188         timeout_data *list_entry;
189
190         list_entry = (timeout_data *)timeout_node->data;
191         if (strncmp(list_entry->command[0], timeout_args[0], i) == 0) {
192             /* Means we executed this command before
193              * and we don't need to add it again
194              */
195             added_before = 1;
196
197             /* Update the timeout */
198             list_entry->time_of_addition = curr_time;
199             break;
200         }
201
202         /* Continue with the next entry in timeout list */
203         timeout_node = OSList_GetNextNode(timeout_list);
204     }
205
206     /* If it wasn't added before, do it now */
207     if (!added_before) {
208         snprintf(buffer, OS_MAXSTR, "\"%s\" %s \"%s\" \"%s\" \"%s\"", command,
209                  ADD_ENTRY, cmd_user, cmd_ip, tmp_msg);
210         /* Execute command */
211         ExecCmd_Win32(buffer);
212
213         /* We don't need to add to the list if the timeout_value == 0 */
214         if (timeout_value) {
215             /* Create the timeout entry */
216             os_calloc(1, sizeof(timeout_data), timeout_entry);
217             timeout_entry->command = timeout_args;
218             timeout_entry->time_of_addition = curr_time;
219             timeout_entry->time_to_block = timeout_value;
220
221             /* Add command to the timeout list */
222             if (!OSList_AddData(timeout_list, timeout_entry)) {
223                 merror(LIST_ADD_ERROR, ARGV0);
224                 FreeTimeoutEntry(timeout_entry);
225             }
226         }
227
228         /* If no timeout, we still need to free it in here */
229         else {
230             char **ss_ta = timeout_args;
231             while (*timeout_args) {
232                 os_free(*timeout_args);
233                 *timeout_args = NULL;
234                 timeout_args++;
235             }
236             os_free(ss_ta);
237         }
238     }
239
240     /* We didn't add it to the timeout list */
241     else {
242         char **ss_ta = timeout_args;
243
244         /* Clear the timeout arguments */
245         while (*timeout_args) {
246             os_free(*timeout_args);
247             *timeout_args = NULL;
248             timeout_args++;
249         }
250
251         os_free(ss_ta);
252     }
253 }
254
255 #endif /* WIN32 */
256