1 /* @(#) $Id: ./src/os_auth/main-client.c, 2012/02/07 dcid Exp $
4 /* Copyright (C) 2010 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 * In addition, as a special exception, the copyright holders give
13 * permission to link the code of portions of this program with the
14 * OpenSSL library under certain conditions as described in each
15 * individual source file, and distribute linked combinations
18 * You must obey the GNU General Public License in all respects
19 * for all of the code used other than OpenSSL. If you modify
20 * file(s) with this exception, you may extend this exception to your
21 * version of the file(s), but you are not obligated to do so. If you
22 * do not wish to do so, delete this exception statement from your
23 * version. If you delete this exception statement from all source
24 * files in the program, then also delete it here.
34 printf("ERROR: Not compiled. Missing OpenSSL support.\n");
41 #include <openssl/ssl.h>
48 printf("\nOSSEC HIDS %s: Connects to the manager to extract the agent key.\n", ARGV0);
49 printf("Available options:\n");
50 printf("\t-h This help message.\n");
51 printf("\t-m <manager ip> Manager IP Address.\n");
52 printf("\t-p <port> Manager port (default 1515).\n");
53 printf("\t-A <agent name> Agent name (default is the hostname).\n");
54 printf("\t-D <OSSEC Dir> Location where OSSEC is installed.\n");
60 int main(int argc, char **argv)
63 // TODO: implement or delete
64 int test_config __attribute__((unused)) = 0;
69 int sock = 0, port = 1515, ret = 0;
70 // TODO: implement or delete
71 char *dir __attribute__((unused)) = DEFAULTDIR;
73 char *group = GROUPGLOBAL;
74 // TODO: implement or delete
75 char *cfg __attribute__((unused)) = DEFAULTCPATH;
77 char *agentname = NULL;
78 char lhostname[512 + 1];
89 /* Setting the name */
92 while((c = getopt(argc, argv, "Vdhu:g:D:c:m:p:A:")) != -1)
106 ErrorExit("%s: -u needs an argument",ARGV0);
111 ErrorExit("%s: -g needs an argument",ARGV0);
116 ErrorExit("%s: -D needs an argument",ARGV0);
121 ErrorExit("%s: -c needs an argument",ARGV0);
129 ErrorExit("%s: -%c needs an argument",ARGV0, c);
134 ErrorExit("%s: -%c needs an argument",ARGV0, c);
139 ErrorExit("%s: -%c needs an argument",ARGV0, c);
141 if(port <= 0 || port >= 65536)
143 ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
152 /* Starting daemon */
153 debug1(STARTED_MSG,ARGV0);
157 /* Check if the user/group given are valid */
158 gid = Privsep_GetGroup(group);
160 ErrorExit(USER_ERROR,ARGV0,user,group);
164 /* Privilege separation */
165 if(Privsep_SetGroup(gid) < 0)
166 ErrorExit(SETGID_ERROR,ARGV0,group);
170 /* Signal manipulation */
175 /* Creating PID files */
176 if(CreatePID(ARGV0, getpid()) < 0)
177 ErrorExit(PID_ERROR,ARGV0);
181 /* Start up message */
182 verbose(STARTUP_MSG, ARGV0, (int)getpid());
185 if(agentname == NULL)
187 lhostname[512] = '\0';
188 if(gethostname(lhostname, 512 -1) != 0)
190 merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0);
193 agentname = lhostname;
199 ctx = os_ssl_keys(1, NULL);
202 merror("%s: ERROR: SSL error. Exiting.", ARGV0);
208 merror("%s: ERROR: Manager IP not set.", ARGV0);
213 /* Check to see if manager is an IP */
215 struct sockaddr_in iptest;
216 memset(&iptest, 0, sizeof(iptest));
218 if(inet_pton(AF_INET, manager, &iptest.sin_addr) != 1)
219 is_ip = 0; /* This is not an IPv4 address */
221 /* Not IPv4, IPv6 maybe? */
224 struct sockaddr_in6 iptest6;
225 memset(&iptest6, 0, sizeof(iptest6));
226 if(inet_pton(AF_INET6, manager, &iptest6.sin6_addr) != 1)
229 is_ip = 1; /* This is an IPv6 address */
233 /* If it isn't an ip, try to resolve the IP */
237 ipaddress = OS_GetHost(manager, 3);
238 if(ipaddress != NULL)
239 strncpy(manager, ipaddress, 16);
242 printf("Could not resolve hostname: %s\n", manager);
248 /* Connecting via TCP */
249 sock = OS_ConnectTCP(port, manager, 0);
252 merror("%s: Unable to connect to %s:%d", ARGV0, manager, port);
257 /* Connecting the SSL socket */
259 sbio = BIO_new_socket(sock, BIO_NOCLOSE);
260 SSL_set_bio(ssl, sbio, sbio);
263 ret = SSL_connect(ssl);
266 ERR_print_errors_fp(stderr);
267 merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret);
272 printf("INFO: Connected to %s:%d\n", manager, port);
273 printf("INFO: Using agent name as: %s\n", agentname);
276 snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname);
277 ret = SSL_write(ssl, buf, strlen(buf));
280 printf("SSL write error (unable to send message.)\n");
281 ERR_print_errors_fp(stderr);
285 printf("INFO: Send request to manager. Waiting for reply.\n");
289 ret = SSL_read(ssl,buf,sizeof(buf) -1);
290 switch(SSL_get_error(ssl,ret))
294 if(strncmp(buf, "ERROR", 5) == 0)
297 tmpstr = strchr(buf, '\n');
298 if(tmpstr) *tmpstr = '\0';
299 printf("%s (from manager)\n", buf);
301 else if(strncmp(buf, "OSSEC K:'",9) == 0)
306 printf("INFO: Received response with agent key\n");
310 tmpstr = strchr(key, '\'');
313 printf("ERROR: Invalid key received. Closing connection.\n");
317 entry = OS_StrBreak(' ', key, 4);
318 if(!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) ||
319 !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3]))
321 printf("ERROR: Invalid key received (2). Closing connection.\n");
327 fp = fopen(KEYSFILE_PATH,"w");
330 printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH);
333 fprintf(fp, "%s\n", key);
336 printf("INFO: Valid key created. Finished.\n");
339 case SSL_ERROR_ZERO_RETURN:
340 case SSL_ERROR_SYSCALL:
341 printf("INFO: Connection closed.\n");
345 printf("ERROR: SSL read (unable to receive message)\n");
354 /* Shutdown the socket */