3 /* Copyright (C) 2010 Trend Micro Inc.
6 * This program is a free software; you can redistribute it
7 * and/or modify it under the terms of the GNU General Public
8 * License (version 2) as published by the FSF - Free Software
11 * In addition, as a special exception, the copyright holders give
12 * permission to link the code of portions of this program with the
13 * OpenSSL library under certain conditions as described in each
14 * individual source file, and distribute linked combinations
17 * You must obey the GNU General Public License in all respects
18 * for all of the code used other than OpenSSL. If you modify
19 * file(s) with this exception, you may extend this exception to your
20 * version of the file(s), but you are not obligated to do so. If you
21 * do not wish to do so, delete this exception statement from your
22 * version. If you delete this exception statement from all source
23 * files in the program, then also delete it here.
31 /* TODO: Pulled this value out of the sky, may or may not be sane */
34 /* ossec-reportd - Runs manual reports. */
42 printf("ERROR: Not compiled. Missing OpenSSL support.\n");
47 /* Function to use with SSL on non blocking socket,
48 to know if SSL operation failed for good */
49 int ssl_error(const SSL* ssl, int ret)
53 switch (SSL_get_error(ssl, ret))
55 case SSL_ERROR_WANT_READ:
56 case SSL_ERROR_WANT_WRITE:
60 merror("%s: ERROR: SSL Error (%d)", ARGV0, ret);
61 ERR_print_errors_fp(stderr);
69 void clean_exit(SSL_CTX* ctx, int sock)
76 int main(int argc, char **argv)
79 // Bucket to keep pids in.
80 int process_pool[POOL_SIZE];
81 // Count of pids we are wait()ing on.
82 int c = 0, test_config = 0, use_ip_address = 0, pid = 0, status, i = 0, active_processes = 0;
83 int gid = 0, client_sock = 0, sock = 0, port = 1515, ret = 0;
84 char *dir = DEFAULTDIR;
86 char *group = GROUPGLOBAL;
87 // TODO: implement or delete
88 char *cfg __attribute__((unused)) = DEFAULTCPATH;
92 char srcip[IPSIZE +1];
93 struct sockaddr_in _nc;
97 /* Initializing some variables */
98 memset(srcip, '\0', IPSIZE + 1);
99 memset(process_pool, 0x0, POOL_SIZE);
104 /* Setting the name */
106 /* add an option to use the ip on the socket to tie the name to a
108 while((c = getopt(argc, argv, "Vdhiu:g:D:c:m:p:")) != -1)
125 ErrorExit("%s: -u needs an argument",ARGV0);
130 ErrorExit("%s: -g needs an argument",ARGV0);
135 ErrorExit("%s: -D needs an argument",ARGV0);
140 ErrorExit("%s: -c needs an argument",ARGV0);
148 ErrorExit("%s: -%c needs an argument",ARGV0, c);
150 if(port <= 0 || port >= 65536)
152 ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
162 /* Starting daemon -- NB: need to double fork and setsid */
163 debug1(STARTED_MSG,ARGV0);
165 /* Check if the user/group given are valid */
166 gid = Privsep_GetGroup(group);
168 ErrorExit(USER_ERROR,ARGV0,user,group);
172 /* Exit here if test config is set */
177 /* Privilege separation */
178 if(Privsep_SetGroup(gid) < 0)
179 ErrorExit(SETGID_ERROR,ARGV0,group);
182 /* chrooting -- TODO: this isn't a chroot. Should also close
183 unneeded open file descriptors (like stdin/stdout)*/
188 /* Signal manipulation */
192 /* Creating PID files */
193 if(CreatePID(ARGV0, getpid()) < 0)
194 ErrorExit(PID_ERROR,ARGV0);
196 /* Start up message */
197 verbose(STARTUP_MSG, ARGV0, (int)getpid());
200 fp = fopen(KEYSFILE_PATH,"a");
203 merror("%s: ERROR: Unable to open %s (key file)", ARGV0, KEYSFILE_PATH);
209 ctx = os_ssl_keys(0, dir);
212 merror("%s: ERROR: SSL error. Exiting.", ARGV0);
217 /* Connecting via TCP */
218 sock = OS_Bindporttcp(port, NULL, 0);
221 merror("%s: Unable to bind to port %d", ARGV0, port);
224 fcntl(sock, F_SETFL, O_NONBLOCK);
226 debug1("%s: DEBUG: Going into listening mode.", ARGV0);
230 // no need to completely pin the cpu, 100ms should be fast enough
233 // Only check process-pool if we have active processes
234 if(active_processes > 0){
235 for (i = 0; i < POOL_SIZE; i++)
241 rv = waitpid(process_pool[i], &status, WNOHANG);
243 debug1("%s: DEBUG: Process %d exited", ARGV0, process_pool[i]);
245 active_processes = active_processes - 1;
250 memset(&_nc, 0, sizeof(_nc));
253 if((client_sock = accept(sock, (struct sockaddr *) &_nc, &_ncl)) > 0){
254 if (active_processes >= POOL_SIZE)
256 merror("%s: Error: Max concurrency reached. Unable to fork", ARGV0);
262 active_processes = active_processes + 1;
264 for (i = 0; i < POOL_SIZE; i++)
266 if (! process_pool[i])
268 process_pool[i] = pid;
275 strncpy(srcip, inet_ntoa(_nc.sin_addr),IPSIZE -1);
276 char *agentname = NULL;
278 SSL_set_fd(ssl, client_sock);
282 ret = SSL_accept(ssl);
284 if (ssl_error(ssl, ret))
285 clean_exit(ctx, client_sock);
289 verbose("%s: INFO: New connection from %s", ARGV0, srcip);
293 ret = SSL_read(ssl, buf, sizeof(buf));
295 if (ssl_error(ssl, ret))
296 clean_exit(ctx, client_sock);
301 if(strncmp(buf, "OSSEC A:'", 9) == 0)
304 agentname = tmpstr + 9;
306 while(*tmpstr != '\0')
311 verbose("%s: INFO: Received request for a new agent (%s) from: %s", ARGV0, agentname, srcip);
320 merror("%s: ERROR: Invalid request for new agent from: %s", ARGV0, srcip);
326 char response[2048 +1];
327 char *finalkey = NULL;
328 response[2048] = '\0';
330 if(!OS_IsValidName(agentname))
332 merror("%s: ERROR: Invalid agent name: %s from %s", ARGV0, agentname, srcip);
333 snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
334 ret = SSL_write(ssl, response, strlen(response));
335 snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
336 ret = SSL_write(ssl, response, strlen(response));
342 /* Checking for a duplicated names. */
343 strncpy(fname, agentname, 2048);
344 while(NameExist(fname))
346 snprintf(fname, 2048, "%s%d", agentname, acount);
350 merror("%s: ERROR: Invalid agent name %s (duplicated)", ARGV0, agentname);
351 snprintf(response, 2048, "ERROR: Invalid agent name: %s\n\n", agentname);
352 ret = SSL_write(ssl, response, strlen(response));
353 snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
354 ret = SSL_write(ssl, response, strlen(response));
362 /* Adding the new agent. */
365 finalkey = OS_AddNewAgent(agentname, srcip, NULL, NULL);
369 finalkey = OS_AddNewAgent(agentname, NULL, NULL, NULL);
373 merror("%s: ERROR: Unable to add agent: %s (internal error)", ARGV0, agentname);
374 snprintf(response, 2048, "ERROR: Internal manager error adding agent: %s\n\n", agentname);
375 ret = SSL_write(ssl, response, strlen(response));
376 snprintf(response, 2048, "ERROR: Unable to add agent.\n\n");
377 ret = SSL_write(ssl, response, strlen(response));
383 snprintf(response, 2048,"OSSEC K:'%s'\n\n", finalkey);
384 verbose("%s: INFO: Agent key generated for %s (requested by %s)", ARGV0, agentname, srcip);
385 ret = SSL_write(ssl, response, strlen(response));
388 merror("%s: ERROR: SSL write error (%d)", ARGV0, ret);
389 merror("%s: ERROR: Agen key not saved for %s", ARGV0, agentname);
390 ERR_print_errors_fp(stderr);
394 verbose("%s: INFO: Agent key created for %s (requested by %s)", ARGV0, agentname, srcip);
398 clean_exit(ctx, client_sock);
404 /* Shutdown the socket */
405 clean_exit(ctx, sock);