new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / win32 / ui / common.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights 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 "os_win32ui.h"
12 #include "../os_win.h"
13 #include "os_xml/os_xml.h"
14 #include "os_net/os_net.h"
15 #include "validate_op.h"
16
17
18 /* Generate server info (for the main status) */
19 int gen_server_info(HWND hwnd)
20 {
21     memset(ui_server_info, '\0', 2048 + 1);
22     snprintf(ui_server_info, 2048,
23              "Agent: %s (%s)  -  %s\r\n\r\n"
24              "Status: %s",
25              config_inst.agentname,
26              config_inst.agentid,
27              config_inst.agentip,
28              config_inst.status);
29
30     /* Initialize top */
31     if (config_inst.version) {
32         SetDlgItemText(hwnd, UI_SERVER_TOP, config_inst.version);
33         SetDlgItemText(hwnd, UI_SERVER_INFO, ui_server_info);
34     }
35
36     /* Initialize auth key */
37     SetDlgItemText(hwnd, UI_SERVER_AUTH, config_inst.key);
38
39     /* Initialize server IP */
40     SetDlgItemText(hwnd, UI_SERVER_TEXT, config_inst.server);
41
42     /* Set status data */
43     SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"http://www.ossec.net");
44     if (config_inst.install_date) {
45         SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)config_inst.install_date);
46     }
47
48     return (0);
49 }
50
51 /* Read the first line of a specific file  --must free after */
52 char *cat_file(char *file, FILE *fp2)
53 {
54     FILE *fp;
55
56     if (!fp2) {
57         fp = fopen(file, "r");
58     } else {
59         fp = fp2;
60     }
61
62     if (fp) {
63         char buf[1024 + 1];
64         char *ret = NULL;
65
66         buf[1024] = '\0';
67         if (fgets(buf, 1024, fp) != NULL) {
68             ret = strchr(buf, '\n');
69             if (ret) {
70                 *ret = '\0';
71             }
72             ret = strchr(buf, '\r');
73             if (ret) {
74                 *ret = '\0';
75             }
76
77             ret = strdup(buf);
78         }
79
80         if (!fp2) {
81             fclose(fp);
82         }
83         return (ret);
84     }
85
86     return (NULL);
87 }
88
89
90 /* Check if a file exists */
91 int is_file(char *file)
92 {
93     FILE *fp;
94     fp = fopen(file, "r");
95     if (fp) {
96         fclose(fp);
97         return (1);
98     }
99     return (0);
100 }
101
102 /* Clear configuration */
103 void config_clear()
104 {
105     if (config_inst.version) {
106         free(config_inst.version);
107     }
108
109     if (config_inst.key) {
110         free(config_inst.key);
111     }
112
113     if (config_inst.agentid) {
114         free(config_inst.agentid);
115     }
116
117     if (config_inst.server) {
118         free(config_inst.server);
119     }
120
121     if (config_inst.install_date) {
122         free(config_inst.install_date);
123     }
124
125     /* Initialize config instance */
126     config_inst.dir = NULL;
127     config_inst.key = FL_NOKEY;
128     config_inst.server = strdup(FL_NOSERVER);
129     config_inst.config = NULL;
130
131     config_inst.agentid = NULL;
132     config_inst.agentname = NULL;
133     config_inst.agentip = NULL;
134
135     config_inst.version = NULL;
136     config_inst.install_date = NULL;
137     config_inst.status = ST_UNKNOWN;
138     config_inst.msg_sent = 0;
139 }
140
141 /* Initialize the config */
142 void init_config()
143 {
144     /* Initialize config instance */
145     config_inst.dir = NULL;
146     config_inst.key = FL_NOKEY;
147     config_inst.server = NULL;
148     config_inst.config = NULL;
149
150     config_inst.agentid = NULL;
151     config_inst.agentname = NULL;
152     config_inst.agentip = NULL;
153
154     config_inst.version = NULL;
155     config_inst.install_date = NULL;
156     config_inst.status = ST_UNKNOWN;
157     config_inst.msg_sent = 0;
158     config_inst.admin_access = 1;
159
160     /* Check if ui is on the right path and has the proper permissions */
161     if (!is_file(CONFIG)) {
162         if (chdir(DEFDIR)) {
163             config_inst.admin_access = 0;
164         }
165
166         if (!is_file(CONFIG)) {
167             config_inst.admin_access = 0;
168         }
169     }
170 }
171
172 /* Read ossec config */
173 int config_read(__attribute__((unused)) HWND hwnd)
174 {
175     char *tmp_str;
176     char *delim = " - ";
177
178     /* Clear config */
179     config_clear();
180
181     /* Get OSSEC status */
182     if (CheckServiceRunning()) {
183         config_inst.status = ST_RUNNING;
184     } else {
185         config_inst.status = ST_STOPPED;
186     }
187
188     /* Get version/install date */
189     config_inst.version = cat_file(VERSION_FILE, NULL);
190     if (config_inst.version) {
191         config_inst.install_date = strstr(config_inst.version, delim);
192         if (config_inst.install_date) {
193             *config_inst.install_date = '\0';
194             config_inst.install_date += strlen(delim);
195         }
196     }
197
198     /* Get number of messages sent */
199     tmp_str = cat_file(SENDER_FILE, NULL);
200     if (tmp_str) {
201         unsigned long int tmp_val = 0;
202         char *to_free = tmp_str;
203
204         tmp_val = atol(tmp_str);
205         if (tmp_val) {
206             config_inst.msg_sent = tmp_val * 9999;
207
208             tmp_str = strchr(tmp_str, ':');
209             if (tmp_str) {
210                 tmp_str++;
211                 tmp_val = atol(tmp_str);
212                 config_inst.msg_sent += tmp_val;
213             }
214         }
215
216         free(to_free);
217     }
218
219     /* Get agent ID, name and IP */
220     tmp_str = cat_file(AUTH_FILE, NULL);
221     if (tmp_str) {
222         /* Get base 64 */
223         config_inst.key = encode_base64(strlen(tmp_str), tmp_str);
224         if (config_inst.key == NULL) {
225             config_inst.key = FL_NOKEY;
226         }
227
228         /* Get ID */
229         config_inst.agentid = tmp_str;
230
231         tmp_str = strchr(tmp_str, ' ');
232         if (tmp_str) {
233             *tmp_str = '\0';
234             tmp_str++;
235
236             /* Get name */
237             config_inst.agentname = tmp_str;
238             tmp_str = strchr(tmp_str, ' ');
239             if (tmp_str) {
240                 *tmp_str = '\0';
241                 tmp_str++;
242
243                 /* Get IP */
244                 config_inst.agentip = tmp_str;
245
246                 tmp_str = strchr(tmp_str, ' ');
247                 if (tmp_str) {
248                     *tmp_str = '\0';
249                 }
250             }
251         }
252     }
253
254     if (config_inst.agentip == NULL) {
255         config_inst.agentid = strdup(ST_NOTSET);
256         config_inst.agentname = strdup("Auth key not imported.");
257         config_inst.agentip = ST_NOTSET;
258
259         config_inst.status = ST_MISSING_IMPORT;
260     }
261
262     /* Get server IP */
263     if (!get_ossec_server()) {
264         if (strcmp(config_inst.status, ST_MISSING_IMPORT) == 0) {
265             config_inst.status = ST_MISSING_ALL;
266         } else {
267             config_inst.status = ST_MISSING_SERVER;
268         }
269     }
270
271     return (0);
272 }
273
274 /* Get OSSEC Server IP */
275 int get_ossec_server()
276 {
277     OS_XML xml;
278     char *str = NULL;
279
280     /* Definitions */
281     const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL};
282     const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL};
283
284     /* Read XML */
285     if (OS_ReadXML(CONFIG, &xml) < 0) {
286         return (0);
287     }
288
289     /* We need to remove the entry for the server */
290     if (config_inst.server) {
291         free(config_inst.server);
292         config_inst.server = NULL;
293     }
294     config_inst.server_type = 0;
295
296     /* Get IP */
297     str = OS_GetOneContentforElement(&xml, xml_serverip);
298     if (str && (OS_IsValidIP(str, NULL) == 1)) {
299         config_inst.server_type = SERVER_IP_USED;
300         config_inst.server = str;
301
302         OS_ClearXML(&xml);
303         return (1);
304     }
305     /* If we don't find the IP, try the server hostname */
306     else {
307         if (str) {
308             free(str);
309             str = NULL;
310         }
311
312         str = OS_GetOneContentforElement(&xml, xml_serverhost);
313         if (str) {
314             char *s_ip;
315             s_ip = OS_GetHost(str, 0);
316             if (s_ip) {
317                 /* Clear the host memory */
318                 free(s_ip);
319
320                 /* Assign the hostname to the server info */
321                 config_inst.server_type = SERVER_HOST_USED;
322                 config_inst.server = str;
323                 OS_ClearXML(&xml);
324                 return (1);
325             }
326             free(str);
327         }
328     }
329
330     /* Set up final server name when not available */
331     config_inst.server = strdup(FL_NOSERVER);
332
333     OS_ClearXML(&xml);
334     return (0);
335 }
336
337 /* Run a cmd.exe command */
338 int run_cmd(char *cmd, HWND hwnd)
339 {
340     int result;
341     int cmdlen;
342     STARTUPINFO si;
343     PROCESS_INFORMATION pi;
344     DWORD exit_code;
345
346     /* Build command */
347     cmdlen = strlen(COMSPEC) + 5 + strlen(cmd);
348     char finalcmd[cmdlen];
349     snprintf(finalcmd, cmdlen, "%s /c %s", COMSPEC, cmd);
350
351     /* Log command being run */
352     log2file("%s: INFO: Running the following command (%s)", ARGV0, finalcmd);
353
354     ZeroMemory(&si, sizeof(si));
355     si.cb = sizeof(si);
356     ZeroMemory(&pi, sizeof(pi));
357
358     if (!CreateProcess(NULL, finalcmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL,
359                        &si, &pi)) {
360         MessageBox(hwnd, "Unable to run command.",
361                    "Error -- Failure Running Command", MB_OK);
362         return (0);
363     }
364
365     /* Wait until process exits */
366     WaitForSingleObject(pi.hProcess, INFINITE);
367
368     /* Get exit code from command */
369     result = GetExitCodeProcess(pi.hProcess, &exit_code);
370
371     /* Close process and thread */
372     CloseHandle(pi.hProcess);
373     CloseHandle(pi.hThread);
374
375     if (!result) {
376         MessageBox(hwnd, "Could not determine exit code from command.",
377                    "Error -- Failure Running Command", MB_OK);
378
379         return (0);
380     }
381
382     return (exit_code);
383 }
384
385 /* Set OSSEC Server IP */
386 int set_ossec_server(char *ip, HWND hwnd)
387 {
388     const char **xml_pt = NULL;
389     const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL};
390     const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL};
391
392     char config_tmp[] = CONFIG;
393     char *conf_file = basename_ex(config_tmp);
394
395     char tmp_path[strlen(TMP_DIR) + 1 + strlen(conf_file) + 6 + 1];
396
397     snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, conf_file);
398
399     /* Verify IP Address */
400     if (OS_IsValidIP(ip, NULL) != 1) {
401         char *s_ip;
402         s_ip = OS_GetHost(ip, 0);
403
404         if (!s_ip) {
405             MessageBox(hwnd, "Invalid Server.\r\n"
406                        "It must be the valid address of the "
407                        "OSSEC server or the resolvable hostname.",
408                        "Error -- Failure Setting IP", MB_OK);
409             return (0);
410         }
411         config_inst.server_type = SERVER_HOST_USED;
412         xml_pt = xml_serverhost;
413     } else {
414         config_inst.server_type = SERVER_IP_USED;
415         xml_pt = xml_serverip;
416     }
417
418     /* Create temporary file */
419     if (mkstemp_ex(tmp_path) == -1) {
420         MessageBox(hwnd, "Could not create temporary file.",
421                    "Error -- Failure Setting IP", MB_OK);
422         return (0);
423     }
424
425     /* Read the XML. Print error and line number. */
426     if (OS_WriteXML(CONFIG, tmp_path, xml_pt, NULL, ip) != 0) {
427         MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n"
428                    "(Internal error on the XML Write).",
429                    "Error -- Failure Setting IP", MB_OK);
430
431         if (unlink(tmp_path)) {
432             MessageBox(hwnd, "Could not delete temporary file.",
433                        "Error -- Failure Deleting Temporary File", MB_OK);
434         }
435
436         return (0);
437     }
438
439     /* Rename config files */
440     if (rename_ex(CONFIG, LASTCONFIG)) {
441         MessageBox(hwnd, "Unable to backup configuration.",
442                    "Error -- Failure Backing Up Configuration", MB_OK);
443
444         if (unlink(tmp_path)) {
445             MessageBox(hwnd, "Could not delete temporary file.",
446                        "Error -- Failure Deleting Temporary File", MB_OK);
447         }
448
449         return (0);
450     }
451
452     if (rename_ex(tmp_path, CONFIG)) {
453         MessageBox(hwnd, "Unable rename temporary file.",
454                    "Error -- Failure Renaming Temporary File", MB_OK);
455
456         if (unlink(tmp_path)) {
457             MessageBox(hwnd, "Could not delete temporary file.",
458                        "Error -- Failure Deleting Temporary File", MB_OK);
459         }
460
461         return (0);
462     }
463
464     return (1);
465 }
466
467 /* Set OSSEC Authentication Key */
468 int set_ossec_key(char *key, HWND hwnd)
469 {
470     FILE *fp;
471
472     char auth_file_tmp[] = AUTH_FILE;
473     char *keys_file = basename_ex(auth_file_tmp);
474
475     char tmp_path[strlen(TMP_DIR) + 1 + strlen(keys_file) + 6 + 1];
476
477     snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, keys_file);
478
479     /* Create temporary file */
480     if (mkstemp_ex(tmp_path) == -1) {
481         MessageBox(hwnd, "Could not create temporary file.",
482                    "Error -- Failure Setting IP", MB_OK);
483         return (0);
484     }
485
486     fp = fopen(tmp_path, "w");
487     if (fp) {
488         fprintf(fp, "%s", key);
489         fclose(fp);
490     } else {
491         MessageBox(hwnd, "Could not open temporary file for write.",
492                    "Error -- Failure Importing Key", MB_OK);
493
494         if (unlink(tmp_path)) {
495             MessageBox(hwnd, "Could not delete temporary file.",
496                        "Error -- Failure Deleting Temporary File", MB_OK);
497         }
498
499         return (0);
500     }
501
502     if (rename_ex(tmp_path, AUTH_FILE)) {
503         MessageBox(hwnd, "Unable to rename temporary file.",
504                    "Error -- Failure Renaming Temporary File", MB_OK);
505
506         if (unlink(tmp_path)) {
507             MessageBox(hwnd, "Could not delete temporary file.",
508                        "Error -- Failure Deleting Temporary File", MB_OK);
509         }
510
511         return (0);
512     }
513
514     return (1);
515 }