Imported Upstream version 2.7
[ossec-hids.git] / src / os_auth / main-client.c
1 /* @(#) $Id: ./src/os_auth/main-client.c, 2012/02/07 dcid Exp $
2  */
3
4 /* Copyright (C) 2010 Trend Micro Inc.
5  * All rights reserved.
6  *
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
10  * Foundation
11  *
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
16  * including the two.
17  *
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.
25  *
26  */
27
28 #include "shared.h"
29
30 #ifndef USE_OPENSSL
31
32 int main()
33 {
34     printf("ERROR: Not compiled. Missing OpenSSL support.\n");
35     exit(0);
36 }
37
38
39 #else
40
41 #include <openssl/ssl.h>
42 #include "auth.h"
43
44
45
46 void report_help()
47 {
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");
55     exit(1);
56 }
57
58
59
60 int main(int argc, char **argv)
61 {
62     int c, test_config = 0;
63     #ifndef WIN32
64     int gid = 0;
65     #endif
66
67     int sock = 0, port = 1515, ret = 0;
68     char *dir  = DEFAULTDIR;
69     char *user = USER;
70     char *group = GROUPGLOBAL;
71     char *cfg = DEFAULTCPATH;
72     char *manager = NULL;
73     char *agentname = NULL;
74     char lhostname[512 + 1];
75     char buf[2048 +1];
76     SSL_CTX *ctx;
77     SSL *ssl;
78     BIO *sbio;
79
80
81     bio_err = 0;
82     buf[2048] = '\0';
83
84
85     /* Setting the name */
86     OS_SetName(ARGV0);
87
88     while((c = getopt(argc, argv, "Vdhu:g:D:c:m:p:A:")) != -1)
89     {
90         switch(c){
91             case 'V':
92                 print_version();
93                 break;
94             case 'h':
95                 report_help();
96                 break;
97             case 'd':
98                 nowDebug();
99                 break;
100             case 'u':
101                 if(!optarg)
102                     ErrorExit("%s: -u needs an argument",ARGV0);
103                 user=optarg;
104                 break;
105             case 'g':
106                 if(!optarg)
107                     ErrorExit("%s: -g needs an argument",ARGV0);
108                 group=optarg;
109                 break;
110             case 'D':
111                 if(!optarg)
112                     ErrorExit("%s: -D needs an argument",ARGV0);
113                 dir=optarg;
114                 break;
115             case 'c':
116                 if(!optarg)
117                     ErrorExit("%s: -c needs an argument",ARGV0);
118                 cfg = optarg;
119                 break;
120             case 't':
121                 test_config = 1;
122                 break;
123             case 'm':
124                if(!optarg)
125                     ErrorExit("%s: -%c needs an argument",ARGV0, c);
126                 manager = optarg;
127                 break;
128             case 'A':
129                if(!optarg)
130                     ErrorExit("%s: -%c needs an argument",ARGV0, c);
131                 agentname = optarg;
132                 break;
133             case 'p':
134                if(!optarg)
135                     ErrorExit("%s: -%c needs an argument",ARGV0, c);
136                 port = atoi(optarg);
137                 if(port <= 0 || port >= 65536)
138                 {
139                     ErrorExit("%s: Invalid port: %s", ARGV0, optarg);
140                 }
141                 break;
142             default:
143                 report_help();
144                 break;
145         }
146     }
147
148     /* Starting daemon */
149     debug1(STARTED_MSG,ARGV0);
150
151
152     #ifndef WIN32
153     /* Check if the user/group given are valid */
154     gid = Privsep_GetGroup(group);
155     if(gid < 0)
156         ErrorExit(USER_ERROR,ARGV0,user,group);
157
158
159
160     /* Privilege separation */  
161     if(Privsep_SetGroup(gid) < 0)
162         ErrorExit(SETGID_ERROR,ARGV0,group);
163
164
165
166     /* Signal manipulation */
167     StartSIG(ARGV0);
168
169
170
171     /* Creating PID files */
172     if(CreatePID(ARGV0, getpid()) < 0)
173         ErrorExit(PID_ERROR,ARGV0);
174     #endif
175
176
177     /* Start up message */
178     verbose(STARTUP_MSG, ARGV0, (int)getpid());
179
180
181     if(agentname == NULL)
182     {
183         lhostname[512] = '\0';
184         if(gethostname(lhostname, 512 -1) != 0)
185         {
186             merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0);
187             exit(1);
188         }
189         agentname = lhostname;
190     }
191
192
193
194     /* Starting SSL */  
195     ctx = os_ssl_keys(1, NULL);
196     if(!ctx)
197     {
198         merror("%s: ERROR: SSL error. Exiting.", ARGV0);
199         exit(1);
200     }
201
202     if(!manager)
203     {
204         merror("%s: ERROR: Manager IP not set.", ARGV0);
205         exit(1);
206     }
207
208
209     /* Connecting via TCP */
210     sock = OS_ConnectTCP(port, manager, 0);
211     if(sock <= 0)
212     {
213         merror("%s: Unable to connect to %s:%d", ARGV0, manager, port);
214         exit(1);
215     }
216
217
218     /* Connecting the SSL socket */
219     ssl = SSL_new(ctx);
220     sbio = BIO_new_socket(sock, BIO_NOCLOSE);
221     SSL_set_bio(ssl, sbio, sbio);
222
223
224     ret = SSL_connect(ssl);
225     if(ret <= 0)
226     {
227         ERR_print_errors_fp(stderr);
228         merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret);
229         exit(1);
230     }
231
232
233     printf("INFO: Connected to %s:%d\n", manager, port);
234     printf("INFO: Using agent name as: %s\n", agentname);
235
236
237     snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname);
238     ret = SSL_write(ssl, buf, strlen(buf));
239     if(ret < 0)
240     {
241         printf("SSL write error (unable to send message.)\n");
242         ERR_print_errors_fp(stderr);
243         exit(1);
244     }
245
246     printf("INFO: Send request to manager. Waiting for reply.\n");
247
248     while(1)
249     {
250         ret = SSL_read(ssl,buf,sizeof(buf) -1);
251         switch(SSL_get_error(ssl,ret))
252         {
253             case SSL_ERROR_NONE:
254                 buf[ret] = '\0';
255                 if(strncmp(buf, "ERROR", 5) == 0)
256                 {
257                     char *tmpstr;
258                     tmpstr = strchr(buf, '\n');
259                     if(tmpstr) *tmpstr = '\0';
260                     printf("%s (from manager)\n", buf);
261                 }
262                 else if(strncmp(buf, "OSSEC K:'",9) == 0)
263                 {
264                     char *key;
265                     char *tmpstr;
266                     char **entry;
267                     printf("INFO: Received response with agent key\n");
268
269                     key = buf;
270                     key += 9;
271                     tmpstr = strchr(key, '\'');
272                     if(!tmpstr)
273                     {
274                         printf("ERROR: Invalid key received. Closing connection.\n");
275                         exit(1);
276                     }
277                     *tmpstr = '\0';
278                     entry = OS_StrBreak(' ', key, 4);
279                     if(!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) ||
280                        !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3]))
281                     {
282                         printf("ERROR: Invalid key received (2). Closing connection.\n");
283                         exit(1);
284                     }
285
286                     {
287                         FILE *fp;
288                         fp = fopen(KEYSFILE_PATH,"w");
289                         if(!fp)
290                         {
291                             printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH);
292                             exit(1);
293                         }
294                         fprintf(fp, "%s\n", key);
295                         fclose(fp);
296                     }
297                     printf("INFO: Valid key created. Finished.\n");
298                 }
299                 break;
300             case SSL_ERROR_ZERO_RETURN:
301             case SSL_ERROR_SYSCALL:
302                 printf("INFO: Connection closed.\n");
303                 exit(0);
304                 break;
305             default:
306                 printf("ERROR: SSL read (unable to receive message)\n");
307                 exit(1);
308                 break;
309         }
310
311     }
312
313
314
315     /* Shutdown the socket */
316     SSL_CTX_free(ctx);
317     close(sock);
318
319     exit(0);
320 }
321
322 #endif
323 /* EOF */