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/? This help message.\n");
49 printf("\t-h This help message.\n");
50 printf("\thelp This help message.\n");
51 printf("\tinstall-service Installs as a service\n");
52 printf("\tuninstall-service Uninstalls as a service\n");
53 printf("\tstart Manually starts (not from services)\n");
57 /* syscheck main thread */
60 verbose("%s: Starting syscheckd thread.", ARGV0);
62 Start_win32_Syscheck();
68 /** main(int argc, char **argv)
71 int main(int argc, char **argv)
74 char mypath[OS_MAXSTR +1];
75 char myfinalpath[OS_MAXSTR +1];
76 char myfile[OS_MAXSTR +1];
78 /* Setting the name */
83 mypath[OS_MAXSTR] = '\0';
84 myfinalpath[OS_MAXSTR] = '\0';
85 myfile[OS_MAXSTR] = '\0';
88 /* mypath is going to be the whole path of the file */
89 strncpy(mypath, argv[0], OS_MAXSTR);
90 tmpstr = strrchr(mypath, '\\');
93 /* tmpstr is now the file name */
96 strncpy(myfile, tmpstr, OS_MAXSTR);
100 strncpy(myfile, argv[0], OS_MAXSTR);
105 getcwd(mypath, OS_MAXSTR -1);
106 snprintf(myfinalpath, OS_MAXSTR, "\"%s\\%s\"", mypath, myfile);
111 if(strcmp(argv[1], "install-service") == 0)
113 return(InstallService(myfinalpath));
115 else if(strcmp(argv[1], "uninstall-service") == 0)
117 return(UninstallService());
119 else if(strcmp(argv[1], "start") == 0)
121 return(local_start());
123 else if(strcmp(argv[1], "/?") == 0)
127 else if(strcmp(argv[1], "-h") == 0)
131 else if(strcmp(argv[1], "help") == 0)
137 merror("%s: Unknown option: %s", ARGV0, argv[1]);
144 if(!os_WinMain(argc, argv))
146 ErrorExit("%s: Unable to start WinMain.", ARGV0);
153 /* Locally starts (after service/win init) */
157 int accept_manager_commands = 0;
158 char *cfg = DEFAULTCPATH;
165 agt = (agent *)calloc(1, sizeof(agent));
168 ErrorExit(MEM_ERROR, ARGV0);
170 agt->port = DEFAULT_SECURE;
172 /* Getting debug level */
173 debug_level = getDefine_Int("windows","debug", 0, 2);
174 while(debug_level != 0)
179 accept_manager_commands = getDefine_Int("logcollector",
180 "remote_commands", 0, 1);
185 /* Configuration file not present */
186 if(File_DateofChange(cfg) < 0)
187 ErrorExit("%s: Configuration file '%s' not found",ARGV0,cfg);
190 /* Starting Winsock */
191 if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
193 ErrorExit("%s: WSAStartup() failed", ARGV0);
197 /* Read agent config */
198 debug1("%s: DEBUG: Reading agent configuration.", ARGV0);
199 if(ClientConf(cfg) < 0)
201 ErrorExit(CLIENT_ERROR,ARGV0);
203 if(agt->notify_time == 0)
205 agt->notify_time = NOTIFY_TIME;
207 if(agt->max_time_reconnect_try == 0 )
209 agt->max_time_reconnect_try = NOTIFY_TIME * 3;
211 if(agt->max_time_reconnect_try <= agt->notify_time)
213 agt->max_time_reconnect_try = (agt->notify_time * 3);
214 verbose("%s: Max time to reconnect can't be less than notify_time(%d), using notify_time*3 (%d)",ARGV0,agt->notify_time,agt->max_time_reconnect_try);
216 verbose("%s: Using notify time: %d and max time to reconnect: %d",ARGV0,agt->notify_time,agt->max_time_reconnect_try);
218 /* Reading logcollector config file */
219 debug1("%s: DEBUG: Reading logcollector configuration.", ARGV0);
220 if(LogCollectorConfig(cfg, accept_manager_commands) < 0)
222 ErrorExit(CONFIG_ERROR, ARGV0, cfg);
226 /* Checking auth keys */
229 ErrorExit(AG_NOKEYS_EXIT, ARGV0);
234 /* If there is not file to monitor, create a clean entry
235 * for the mark messages.
239 os_calloc(2, sizeof(logreader), logff);
240 logff[0].file = NULL;
241 logff[0].ffile = NULL;
242 logff[0].logformat = NULL;
244 logff[1].file = NULL;
245 logff[1].logformat = NULL;
247 merror(NO_FILE, ARGV0);
251 /* Reading execd config. */
252 if(!WinExecd_Start())
259 verbose(ENC_READ, ARGV0);
262 OS_StartCounter(&keys);
263 os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, agt->profile);
266 /* Initial random numbers */
271 /* Socket connection */
277 debug1("%s: DEBUG: Creating thread mutex.", ARGV0);
278 hMutex = CreateMutex(NULL, FALSE, NULL);
281 ErrorExit("%s: Error creating mutex.", ARGV0);
286 /* Starting syscheck thread */
287 if(CreateThread(NULL,
289 (LPTHREAD_START_ROUTINE)skthread,
292 (LPDWORD)&threadID) == NULL)
294 merror(THREAD_ERROR, ARGV0);
299 /* Checking if server is connected */
307 /* Sending integrity message for agent configs */
308 intcheck_file(cfg, "");
309 intcheck_file(OSSEC_DEFINES, "");
312 /* Starting receiver thread */
313 if(CreateThread(NULL,
315 (LPTHREAD_START_ROUTINE)receiver_thread,
318 (LPDWORD)&threadID2) == NULL)
320 merror(THREAD_ERROR, ARGV0);
324 /* Sending agent information message */
325 send_win32_info(time(0));
328 /* Startting logcollector -- main process here */
336 /* SendMSG for windows */
337 int SendMSG(int queue, char *message, char *locmsg, char loc)
344 char tmpstr[OS_MAXSTR+2];
345 char crypt_msg[OS_MAXSTR +2];
349 tmpstr[OS_MAXSTR +1] = '\0';
350 crypt_msg[OS_MAXSTR +1] = '\0';
352 debug2("%s: DEBUG: Attempting to send message to server.", ARGV0);
354 /* Using a mutex to synchronize the writes */
357 dwWaitResult = WaitForSingleObject(hMutex, 1000000L);
359 if(dwWaitResult != WAIT_OBJECT_0)
364 merror("%s: Error waiting mutex (timeout).", ARGV0);
368 merror("%s: Error waiting mutex (abandoned).", ARGV0);
371 merror("%s: Error waiting mutex.", ARGV0);
380 } /*end - while for mutex...*/
386 /* Check if the server has responded */
387 if((cu_time - available_server) > agt->notify_time)
389 debug1("%s: DEBUG: Sending info to server (c1)...", ARGV0);
390 verbose("%s: More than %d seconds without server response...sending win32info", ARGV0,agt->notify_time);
391 send_win32_info(cu_time);
394 /* Attempting to send message again. */
395 if((cu_time - available_server) > agt->notify_time)
399 send_win32_info(cu_time);
402 if((cu_time - available_server) > agt->notify_time)
404 send_win32_info(cu_time);
409 /* If we reached here, the server is unavailable for a while. */
410 if((cu_time - available_server) > agt->max_time_reconnect_try)
413 verbose("%s: More than %d seconds without server response...is server alive? and Is there connection?", ARGV0,agt->max_time_reconnect_try);
415 /* Last attempt before going into reconnect mode. */
416 debug1("%s: DEBUG: Sending info to server (c3)...", ARGV0);
418 send_win32_info(cu_time);
419 if((cu_time - available_server) > agt->max_time_reconnect_try)
422 send_win32_info(cu_time);
427 /* Checking and generating log if unavailable. */
429 if((cu_time - available_server) > agt->max_time_reconnect_try)
431 int global_sleep = 1;
434 /* If response is not available, set lock and
437 verbose(SERVER_UNAV, ARGV0);
440 /* Going into reconnect mode. */
441 while((cu_time - available_server) > agt->max_time_reconnect_try)
443 /* Sending information to see if server replies */
446 send_win32_info(cu_time);
462 /* If we have more than one server, try all. */
463 if(wi > 12 && agt->rip[1])
465 int curr_rip = agt->rip_id;
466 merror("%s: INFO: Trying next server ip in "
469 agt->rip[agt->rip_id + 1] != NULL?
470 agt->rip[agt->rip_id + 1]:
473 connect_server(agt->rip_id +1);
475 if(agt->rip_id != curr_rip)
480 else if(global_sleep == 2 || ((global_sleep % mod_sleep) == 0) ||
483 connect_server(agt->rip_id +1);
486 sleep(wi + global_sleep);
493 if(global_sleep > 30)
500 verbose(AG_CONNECTED, ARGV0, agt->rip[agt->rip_id],
502 verbose(SERVER_UP, ARGV0);
513 /* Send notification */
514 else if((cu_time - __win32_curr_time) > (NOTIFY_TIME - 200))
516 debug1("%s: DEBUG: Sending info to server (ctime2)...", ARGV0);
517 send_win32_info(cu_time);
522 /* locmsg cannot have the C:, as we use it as delimiter */
523 pl = strchr(locmsg, ':');
526 /* Setting pl after the ":" if it exists. */
535 debug2("%s: DEBUG: Sending message to server: '%s'", ARGV0, message);
537 snprintf(tmpstr,OS_MAXSTR,"%c:%s:%s", loc, pl, message);
539 _ssize = CreateSecMSG(&keys, tmpstr, crypt_msg, 0);
542 /* Returns NULL if can't create encrypted message */
545 merror(SEC_ERROR,ARGV0);
546 if(!ReleaseMutex(hMutex))
548 merror("%s: Error releasing mutex.", ARGV0);
554 /* Send _ssize of crypt_msg */
555 if(OS_SendUDPbySize(agt->sock, _ssize, crypt_msg) < 0)
557 merror(SEND_ERROR,ARGV0, "server");
561 if(!ReleaseMutex(hMutex))
563 merror("%s: Error releasing mutex.", ARGV0);
569 /* StartMQ for windows */
570 int StartMQ(char * path, short int type)
572 /* Connecting to the server. */
575 if((path == NULL) && (type == 0))
584 /* Send win32 info to server */
585 void send_win32_info(time_t curr_time)
588 char tmp_msg[OS_MAXSTR +2];
589 char crypt_msg[OS_MAXSTR +2];
591 tmp_msg[OS_MAXSTR +1] = '\0';
592 crypt_msg[OS_MAXSTR +1] = '\0';
595 debug1("%s: DEBUG: Sending keep alive message.", ARGV0);
598 __win32_curr_time = curr_time;
604 __win32_uname = getuname();
607 merror("%s: Error generating system information.", ARGV0);
608 os_strdup("Microsoft Windows - Unknown (unable to get system info)", __win32_uname);
613 /* Getting shared files list -- every 30 seconds only. */
614 if((__win32_curr_time - __win32_shared_time) > 30)
618 free(__win32_shared);
619 __win32_shared = NULL;
622 __win32_shared_time = __win32_curr_time;
626 /* get shared files */
629 __win32_shared = getsharedfiles();
632 __win32_shared = strdup("\0");
635 merror(MEM_ERROR, ARGV0);
643 /* creating message */
644 if(File_DateofChange(AGENTCONFIGINT) > 0)
647 if(OS_MD5_File(AGENTCONFIGINT, md5sum) != 0)
649 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared);
653 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s / %s\n%s", __win32_uname, md5sum, __win32_shared);
658 snprintf(tmp_msg, OS_SIZE_1024, "#!-%s\n%s", __win32_uname, __win32_shared);
662 /* creating message */
663 debug1("%s: DEBUG: Sending keep alive: %s", ARGV0, tmp_msg);
665 msg_size = CreateSecMSG(&keys, tmp_msg, crypt_msg, 0);
669 merror(SEC_ERROR, ARGV0);
673 /* Sending UDP message */
674 if(OS_SendUDPbySize(agt->sock, msg_size, crypt_msg) < 0)
676 merror(SEND_ERROR, ARGV0, "server");