1 /* @(#) $Id: ./src/win32/win_agent.c, 2011/11/01 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
7 * This program is a free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General Public
9 * License (version 2) as published by the FSF - Free Software
12 * License details at the LICENSE file included with OSSEC or
13 * online at: http://www.ossec.net/en/licensing.html
21 #include "logcollector.h"
23 #include "os_net/os_net.h"
24 #include "os_execd/execd.h"
25 #include "os_crypto/md5/md5_op.h"
28 #define ARGV0 "ossec-agent"
31 time_t __win32_curr_time = 0;
32 time_t __win32_shared_time = 0;
33 char *__win32_uname = NULL;
34 char *__win32_shared = NULL;
39 int Start_win32_Syscheck();
40 void send_win32_info(time_t curr_time);
46 printf("\nOSSEC HIDS %s %s .\n", ARGV0, __version);
47 printf("Available options:\n");
48 printf("\t-h This help message.\n");
49 printf("\thelp This help message.\n");
50 printf("\tinstall-service Installs as a service\n");
51 printf("\tuninstall-service Uninstalls as a service\n");
52 printf("\tstart Manually starts (not from services)\n");
56 /* syscheck main thread */
59 verbose("%s: Starting syscheckd thread.", ARGV0);
61 Start_win32_Syscheck();
67 /** main(int argc, char **argv)
70 int main(int argc, char **argv)
73 char mypath[OS_MAXSTR +1];
74 char myfile[OS_MAXSTR +1];
76 /* Setting the name */
81 mypath[OS_MAXSTR] = '\0';
82 myfile[OS_MAXSTR] = '\0';
85 /* mypath is going to be the whole path of the file */
86 strncpy(mypath, argv[0], OS_MAXSTR);
87 tmpstr = strrchr(mypath, '\\');
90 /* tmpstr is now the file name */
93 strncpy(myfile, tmpstr, OS_MAXSTR);
97 strncpy(myfile, argv[0], OS_MAXSTR);
102 getcwd(mypath, OS_MAXSTR -1);
103 strncat(mypath, "\\", OS_MAXSTR - (strlen(mypath) + 2));
104 strncat(mypath, myfile, OS_MAXSTR - (strlen(mypath) + 2));
109 if(strcmp(argv[1], "install-service") == 0)
111 return(InstallService(mypath));
113 else if(strcmp(argv[1], "uninstall-service") == 0)
115 return(UninstallService());
117 else if(strcmp(argv[1], "start") == 0)
119 return(local_start());
121 else if(strcmp(argv[1], "-h") == 0)
125 else if(strcmp(argv[1], "help") == 0)
131 merror("%s: Unknown option: %s", ARGV0, argv[1]);
138 if(!os_WinMain(argc, argv))
140 ErrorExit("%s: Unable to start WinMain.", ARGV0);
147 /* Locally starts (after service/win init) */
151 int accept_manager_commands = 0;
152 char *cfg = DEFAULTCPATH;
159 logr = (agent *)calloc(1, sizeof(agent));
162 ErrorExit(MEM_ERROR, ARGV0);
164 logr->port = DEFAULT_SECURE;
167 /* Getting debug level */
168 debug_level = getDefine_Int("windows","debug", 0, 2);
169 while(debug_level != 0)
174 accept_manager_commands = getDefine_Int("logcollector",
175 "remote_commands", 0, 1);
180 /* Configuration file not present */
181 if(File_DateofChange(cfg) < 0)
182 ErrorExit("%s: Configuration file '%s' not found",ARGV0,cfg);
185 /* Starting Winsock */
186 if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
188 ErrorExit("%s: WSAStartup() failed", ARGV0);
192 /* Read agent config */
193 debug1("%s: DEBUG: Reading agent configuration.", ARGV0);
194 if(ClientConf(cfg) < 0)
196 ErrorExit(CLIENT_ERROR,ARGV0);
200 /* Reading logcollector config file */
201 debug1("%s: DEBUG: Reading logcollector configuration.", ARGV0);
202 if(LogCollectorConfig(cfg, accept_manager_commands) < 0)
204 ErrorExit(CONFIG_ERROR, ARGV0, cfg);
208 /* Checking auth keys */
211 ErrorExit(AG_NOKEYS_EXIT, ARGV0);
216 /* If there is not file to monitor, create a clean entry
217 * for the mark messages.
221 os_calloc(2, sizeof(logreader), logff);
222 logff[0].file = NULL;
223 logff[0].ffile = NULL;
224 logff[0].logformat = NULL;
226 logff[1].file = NULL;
227 logff[1].logformat = NULL;
229 merror(NO_FILE, ARGV0);
233 /* Reading execd config. */
234 if(!WinExecd_Start())
241 verbose(ENC_READ, ARGV0);
244 OS_StartCounter(&keys);
245 os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, NULL);
248 /* Initial random numbers */
253 /* Socket connection */
259 debug1("%s: DEBUG: Creating thread mutex.", ARGV0);
260 hMutex = CreateMutex(NULL, FALSE, NULL);
263 ErrorExit("%s: Error creating mutex.", ARGV0);
268 /* Starting syscheck thread */
269 if(CreateThread(NULL,
271 (LPTHREAD_START_ROUTINE)skthread,
274 (LPDWORD)&threadID) == NULL)
276 merror(THREAD_ERROR, ARGV0);
281 /* Checking if server is connected */
289 /* Sending integrity message for agent configs */
290 intcheck_file(cfg, "");
291 intcheck_file(OSSEC_DEFINES, "");
294 /* Starting receiver thread */
295 if(CreateThread(NULL,
297 (LPTHREAD_START_ROUTINE)receiver_thread,
300 (LPDWORD)&threadID2) == NULL)
302 merror(THREAD_ERROR, ARGV0);
306 /* Sending agent information message */
307 send_win32_info(time(0));
310 /* Startting logcollector -- main process here */
318 /* SendMSG for windows */
319 int SendMSG(int queue, char *message, char *locmsg, char loc)
326 char tmpstr[OS_MAXSTR+2];
327 char crypt_msg[OS_MAXSTR +2];
331 tmpstr[OS_MAXSTR +1] = '\0';
332 crypt_msg[OS_MAXSTR +1] = '\0';
335 debug2("%s: DEBUG: Attempting to send message to server.", ARGV0);
337 /* Using a mutex to synchronize the writes */
340 dwWaitResult = WaitForSingleObject(hMutex, 1000000L);
342 if(dwWaitResult != WAIT_OBJECT_0)
347 merror("%s: Error waiting mutex (timeout).", ARGV0);
351 merror("%s: Error waiting mutex (abandoned).", ARGV0);
354 merror("%s: Error waiting mutex.", ARGV0);
370 /* Check if the server has responded */
371 if((cu_time - available_server) > (NOTIFY_TIME - 180))
373 debug1("%s: DEBUG: Sending info to server (c1)...", ARGV0);
374 send_win32_info(cu_time);
377 /* Attempting to send message again. */
378 if((cu_time - available_server) > NOTIFY_TIME)
381 send_win32_info(cu_time);
384 if((cu_time - available_server) > NOTIFY_TIME)
386 send_win32_info(cu_time);
391 /* If we reached here, the server is unavailable for a while. */
392 if((cu_time - available_server) > ((3 * NOTIFY_TIME) - 180))
397 /* Last attempt before going into reconnect mode. */
398 debug1("%s: DEBUG: Sending info to server (c3)...", ARGV0);
400 send_win32_info(cu_time);
401 if((cu_time - available_server) > ((3 * NOTIFY_TIME) - 180))
404 send_win32_info(cu_time);
409 /* Checking and generating log if unavailable. */
411 if((cu_time - available_server) > ((3 * NOTIFY_TIME) - 180))
413 int global_sleep = 1;
416 /* If response is not available, set lock and
419 verbose(SERVER_UNAV, ARGV0);
422 /* Going into reconnect mode. */
423 while((cu_time - available_server) > ((3*NOTIFY_TIME) - 180))
425 /* Sending information to see if server replies */
428 send_win32_info(cu_time);
444 /* If we have more than one server, try all. */
445 if(wi > 12 && logr->rip[1])
447 int curr_rip = logr->rip_id;
448 merror("%s: INFO: Trying next server ip in "
451 logr->rip[logr->rip_id + 1] != NULL?
452 logr->rip[logr->rip_id + 1]:
455 connect_server(logr->rip_id +1);
457 if(logr->rip_id != curr_rip)
462 else if(global_sleep == 2 || ((global_sleep % mod_sleep) == 0) ||
465 connect_server(logr->rip_id +1);
468 sleep(wi + global_sleep);
475 if(global_sleep > 30)
482 verbose(AG_CONNECTED, ARGV0, logr->rip[logr->rip_id],
484 verbose(SERVER_UP, ARGV0);
495 /* Send notification */
496 else if((cu_time - __win32_curr_time) > (NOTIFY_TIME - 200))
498 debug1("%s: DEBUG: Sending info to server (ctime2)...", ARGV0);
499 send_win32_info(cu_time);
504 /* locmsg cannot have the C:, as we use it as delimiter */
505 pl = strchr(locmsg, ':');
508 /* Setting pl after the ":" if it exists. */
517 debug2("%s: DEBUG: Sending message to server: '%s'", ARGV0, message);
519 snprintf(tmpstr,OS_MAXSTR,"%c:%s:%s", loc, pl, message);
521 _ssize = CreateSecMSG(&keys, tmpstr, crypt_msg, 0);
524 /* Returns NULL if can't create encrypted message */
527 merror(SEC_ERROR,ARGV0);
528 if(!ReleaseMutex(hMutex))
530 merror("%s: Error releasing mutex.", ARGV0);
536 /* Send _ssize of crypt_msg */
537 if(OS_SendUDPbySize(logr->sock, _ssize, crypt_msg) < 0)
539 merror(SEND_ERROR,ARGV0, "server");
543 if(!ReleaseMutex(hMutex))
545 merror("%s: Error releasing mutex.", ARGV0);
551 /* StartMQ for windows */
552 int StartMQ(char * path, short int type)
554 /* Connecting to the server. */
557 if((path == NULL) && (type == 0))
566 /* Send win32 info to server */
567 void send_win32_info(time_t curr_time)
570 char tmp_msg[OS_MAXSTR +2];
571 char crypt_msg[OS_MAXSTR +2];
573 tmp_msg[OS_MAXSTR +1] = '\0';
574 crypt_msg[OS_MAXSTR +1] = '\0';
577 debug1("%s: DEBUG: Sending keep alive message.", ARGV0);
581 __win32_curr_time = curr_time;
587 __win32_uname = getuname();
590 merror("%s: Error generating system information.", ARGV0);
591 os_strdup("Microsoft Windows - Unknown (unable to get system info)", __win32_uname);
596 /* Getting shared files list -- every 30 seconds only. */
597 if((__win32_curr_time - __win32_shared_time) > 30)
601 free(__win32_shared);
602 __win32_shared = NULL;
605 __win32_shared_time = __win32_curr_time;
609 /* get shared files */
612 __win32_shared = getsharedfiles();
615 __win32_shared = strdup("\0");
618 merror(MEM_ERROR, ARGV0);
626 /* creating message */
627 if(File_DateofChange(AGENTCONFIGINT) > 0)
630 if(OS_MD5_File(AGENTCONFIGINT, md5sum) != 0)
632 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared);
636 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s", __win32_uname, md5sum, __win32_shared);
641 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared);
645 /* creating message */
646 debug1("%s: DEBUG: Sending keep alive: %s", ARGV0, tmp_msg);
648 msg_size = CreateSecMSG(&keys, tmp_msg, crypt_msg, 0);
652 merror(SEC_ERROR, ARGV0);
656 /* Sending UDP message */
657 if(OS_SendUDPbySize(logr->sock, msg_size, crypt_msg) < 0)
659 merror(SEND_ERROR, ARGV0, "server");