/* Update the keys if changed */ int OS_UpdateKeys(keystore *keys) { if (keys->file_change != File_DateofChange(KEYS_FILE)) { merror(ENCFILE_CHANGED, __local_name); debug1("%s: DEBUG: Freekeys", __local_name); OS_FreeKeys(keys); debug1("%s: DEBUG: OS_ReadKeys", __local_name); /* Read keys */ verbose(ENC_READ, __local_name); OS_ReadKeys(keys); debug1("%s: DEBUG: OS_StartCounter", __local_name); OS_StartCounter(keys); debug1("%s: DEBUG: OS_UpdateKeys completed", __local_name); return (1); } return (0); }
/* AgentdStart v0.2, 2005/11/09 * Starts the agent daemon. */ void AgentdStart(char *dir, int uid, int gid, char *user, char *group) { int rc = 0; int pid = 0; int maxfd = 0; fd_set fdset; struct timeval fdtimeout; pid = getpid(); available_server = 0; /* Going Daemon */ if (!run_foreground) { nowDaemon(); goDaemonLight(); } /* Setting group ID */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR, ARGV0, group); /* chrooting */ if(Privsep_Chroot(dir) < 0) ErrorExit(CHROOT_ERROR, ARGV0, dir); nowChroot(); if(Privsep_SetUser(uid) < 0) ErrorExit(SETUID_ERROR, ARGV0, user); /* Create the queue. In this case we are going to create * and read from it * Exit if fails. */ if((agt->m_queue = StartMQ(DEFAULTQUEUE, READ)) < 0) ErrorExit(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); maxfd = agt->m_queue; agt->sock = -1; /* Creating PID file */ if(CreatePID(ARGV0, getpid()) < 0) merror(PID_ERROR,ARGV0); /* Reading the private keys */ verbose(ENC_READ, ARGV0); OS_ReadKeys(&keys); OS_StartCounter(&keys); /* cmoraes : changed the following call to os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id); */ os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, agt->profile); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); /* Initial random numbers */ #ifdef __OpenBSD__ srandomdev(); #else srandom( time(0) + getpid()+ pid + getppid()); #endif random(); /* Connecting UDP */ rc = 0; while(rc < agt->rip_id) { verbose("%s: INFO: Server IP Address: %s", ARGV0, agt->rip[rc]); rc++; } /* Trying to connect to the server */ if(!connect_server(0)) { ErrorExit(UNABLE_CONN, ARGV0); } /* Setting max fd for select */ if(agt->sock > maxfd) { maxfd = agt->sock; } /* Connecting to the execd queue */ if(agt->execdq == 0) { if((agt->execdq = StartMQ(EXECQUEUE, WRITE)) < 0) { merror("%s: INFO: Unable to connect to the active response " "queue (disabled).", ARGV0); agt->execdq = -1; } } /* Trying to connect to server */ os_setwait(); start_agent(1); os_delwait(); /* Sending integrity message for agent configs */ intcheck_file(OSSECCONF, dir); intcheck_file(OSSEC_DEFINES, dir); /* Sending first notification */ run_notify(); /* Maxfd must be higher socket +1 */ maxfd++; /* monitor loop */ while(1) { /* Monitoring all available sockets from here */ FD_ZERO(&fdset); FD_SET(agt->sock, &fdset); FD_SET(agt->m_queue, &fdset); fdtimeout.tv_sec = 1; fdtimeout.tv_usec = 0; /* Continuously send notifications */ run_notify(); /* Wait with a timeout for any descriptor */ rc = select(maxfd, &fdset, NULL, NULL, &fdtimeout); if(rc == -1) { ErrorExit(SELECT_ERROR, ARGV0); } else if(rc == 0) { continue; } /* For the receiver */ if(FD_ISSET(agt->sock, &fdset)) { receive_msg(); } /* For the forwarder */ if(FD_ISSET(agt->m_queue, &fdset)) { EventForward(); } } }
/* Locally starts (after service/win init) */ int local_start() { int debug_level; int accept_manager_commands = 0; char *cfg = DEFAULTCPATH; WSADATA wsaData; DWORD threadID; DWORD threadID2; /* Starting logr */ logr = (agent *)calloc(1, sizeof(agent)); if(!logr) { ErrorExit(MEM_ERROR, ARGV0); } logr->port = DEFAULT_SECURE; /* Getting debug level */ debug_level = getDefine_Int("windows","debug", 0, 2); while(debug_level != 0) { nowDebug(); debug_level--; } accept_manager_commands = getDefine_Int("logcollector", "remote_commands", 0, 1); /* Configuration file not present */ if(File_DateofChange(cfg) < 0) ErrorExit("%s: Configuration file '%s' not found",ARGV0,cfg); /* Starting Winsock */ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { ErrorExit("%s: WSAStartup() failed", ARGV0); } /* Read agent config */ debug1("%s: DEBUG: Reading agent configuration.", ARGV0); if(ClientConf(cfg) < 0) { ErrorExit(CLIENT_ERROR,ARGV0); } if(logr->notify_time == 0) { logr->notify_time = NOTIFY_TIME; } if(logr->max_time_reconnect_try == 0 ) { logr->max_time_reconnect_try = NOTIFY_TIME * 3; } if(logr->max_time_reconnect_try <= logr->notify_time) { logr->max_time_reconnect_try = (logr->notify_time * 3); verbose("%s Max time to reconnect can't be less than notify_time(%d), using notify_time*3 (%d)",ARGV0,logr->notify_time,logr->max_time_reconnect_try); } verbose("%s Using notify time: %d and max time to reconnect: %d",ARGV0,logr->notify_time,logr->max_time_reconnect_try); /* Reading logcollector config file */ debug1("%s: DEBUG: Reading logcollector configuration.", ARGV0); if(LogCollectorConfig(cfg, accept_manager_commands) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } /* Checking auth keys */ if(!OS_CheckKeys()) { ErrorExit(AG_NOKEYS_EXIT, ARGV0); } /* If there is not file to monitor, create a clean entry * for the mark messages. */ if(logff == NULL) { os_calloc(2, sizeof(logreader), logff); logff[0].file = NULL; logff[0].ffile = NULL; logff[0].logformat = NULL; logff[0].fp = NULL; logff[1].file = NULL; logff[1].logformat = NULL; merror(NO_FILE, ARGV0); } /* Reading execd config. */ if(!WinExecd_Start()) { logr->execdq = -1; } /* Reading keys */ verbose(ENC_READ, ARGV0); OS_ReadKeys(&keys); OS_StartCounter(&keys); os_write_agent_info(keys.keyentries[0]->name, NULL, keys.keyentries[0]->id, NULL); /* Initial random numbers */ srandom(time(0)); random(); /* Socket connection */ logr->sock = -1; StartMQ(NULL, 0); /* Starting mutex */ debug1("%s: DEBUG: Creating thread mutex.", ARGV0); hMutex = CreateMutex(NULL, FALSE, NULL); if(hMutex == NULL) { ErrorExit("%s: Error creating mutex.", ARGV0); } /* Starting syscheck thread */ if(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)skthread, NULL, 0, (LPDWORD)&threadID) == NULL) { merror(THREAD_ERROR, ARGV0); } /* Checking if server is connected */ os_setwait(); start_agent(1); os_delwait(); /* Sending integrity message for agent configs */ intcheck_file(cfg, ""); intcheck_file(OSPATROL_DEFINES, ""); /* Starting receiver thread */ if(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)receiver_thread, NULL, 0, (LPDWORD)&threadID2) == NULL) { merror(THREAD_ERROR, ARGV0); } /* Sending agent information message */ send_win32_info(time(0)); /* Startting logcollector -- main process here */ LogCollectorStart(); WSACleanup(); return(0); }
/* Handle secure connections */ void HandleSecure() { int agentid; char buffer[OS_MAXSTR + 1]; char cleartext_msg[OS_MAXSTR + 1]; char srcip[IPSIZE + 1]; char *tmp_msg; char srcmsg[OS_FLSIZE + 1]; ssize_t recv_b; struct sockaddr_in peer_info; socklen_t peer_size; /* Send msg init */ send_msg_init(); /* Initialize key mutex */ keyupdate_init(); /* Initialize manager */ manager_init(0); /* Create Active Response forwarder thread */ if (CreateThread(AR_Forward, (void *)NULL) != 0) { ErrorExit(THREAD_ERROR, ARGV0); } /* Create wait_for_msgs thread */ if (CreateThread(wait_for_msgs, (void *)NULL) != 0) { ErrorExit(THREAD_ERROR, ARGV0); } /* Connect to the message queue * Exit if it fails. */ if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); } verbose(AG_AX_AGENTS, ARGV0, MAX_AGENTS); /* Read authentication keys */ verbose(ENC_READ, ARGV0); OS_ReadKeys(&keys); OS_StartCounter(&keys); /* Set up peer size */ peer_size = sizeof(peer_info); logr.peer_size = sizeof(peer_info); /* Initialize some variables */ memset(buffer, '\0', OS_MAXSTR + 1); memset(cleartext_msg, '\0', OS_MAXSTR + 1); memset(srcmsg, '\0', OS_FLSIZE + 1); tmp_msg = NULL; while (1) { /* Receive message */ recv_b = recvfrom(logr.sock, buffer, OS_MAXSTR, 0, (struct sockaddr *)&peer_info, &peer_size); /* Nothing received */ if (recv_b <= 0) { continue; } /* Set the source IP */ strncpy(srcip, inet_ntoa(peer_info.sin_addr), IPSIZE); srcip[IPSIZE] = '\0'; /* Get a valid agent id */ if (buffer[0] == '!') { tmp_msg = buffer; tmp_msg++; /* We need to make sure that we have a valid id * and that we reduce the recv buffer size */ while (isdigit((int)*tmp_msg)) { tmp_msg++; recv_b--; } if (*tmp_msg != '!') { merror(ENCFORMAT_ERROR, __local_name, srcip); continue; } *tmp_msg = '\0'; tmp_msg++; recv_b -= 2; agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip); if (agentid == -1) { if (check_keyupdate()) { agentid = OS_IsAllowedDynamicID(&keys, buffer + 1, srcip); if (agentid == -1) { merror(ENC_IP_ERROR, ARGV0, srcip); continue; } } else { merror(ENC_IP_ERROR, ARGV0, srcip); continue; } } } else { agentid = OS_IsAllowedIP(&keys, srcip); if (agentid < 0) { if (check_keyupdate()) { agentid = OS_IsAllowedIP(&keys, srcip); if (agentid == -1) { merror(DENYIP_WARN, ARGV0, srcip); continue; } } else { merror(DENYIP_WARN, ARGV0, srcip); continue; } } tmp_msg = buffer; } /* Decrypt the message */ tmp_msg = ReadSecMSG(&keys, tmp_msg, cleartext_msg, agentid, recv_b - 1); if (tmp_msg == NULL) { /* If duplicated, a warning was already generated */ continue; } /* Check if it is a control message */ if (IsValidHeader(tmp_msg)) { /* We need to save the peerinfo if it is a control msg */ memcpy(&keys.keyentries[agentid]->peer_info, &peer_info, peer_size); keys.keyentries[agentid]->rcvd = time(0); save_controlmsg((unsigned)agentid, tmp_msg); continue; } /* Generate srcmsg */ snprintf(srcmsg, OS_FLSIZE, "(%s) %s", keys.keyentries[agentid]->name, keys.keyentries[agentid]->ip->ip); /* If we can't send the message, try to connect to the * socket again. If it not exit. */ if (SendMSG(logr.m_queue, tmp_msg, srcmsg, SECURE_MQ) < 0) { merror(QUEUE_ERROR, ARGV0, DEFAULTQUEUE, strerror(errno)); if ((logr.m_queue = StartMQ(DEFAULTQUEUE, WRITE)) < 0) { ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQUEUE); } } } }