Imported Upstream version 2.7
[ossec-hids.git] / src / addagent / manage_keys.c
1 /* @(#) $Id: ./src/addagent/manage_keys.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 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  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 #include "manage_agents.h"
18 #include "os_crypto/md5/md5_op.h"
19 #include <stdlib.h>
20
21 /* b64 function prototypes */
22 char *decode_base64(const char *src);
23 char *encode_base64(int size, char *src);
24
25 char *trimwhitespace(char *str)
26 {
27   char *end;
28
29   // Trim leading space
30   while(isspace(*str)) str++;
31
32   if(*str == 0)  // All spaces?
33     return str;
34
35   // Trim trailing space
36   end = str + strlen(str) - 1;
37   while(end > str && isspace(*end)) end--;
38
39   // Write new null terminator
40   *(end+1) = 0;
41
42   return str;
43 }
44
45 /* Import a key */
46 int k_import(char *cmdimport)
47 {
48     FILE *fp;
49     char *user_input;
50     char *b64_dec;
51
52     char *name; char *ip; char *tmp_key;
53
54     char line_read[FILE_SIZE +1];
55
56
57     /* Parsing user argument. */
58     if(cmdimport)
59     {
60         user_input = cmdimport;
61     }
62     else
63     {
64         printf(IMPORT_KEY);
65
66         user_input = getenv("OSSEC_AGENT_KEY");
67         if (user_input == NULL) {
68           user_input = read_from_user();
69         }
70     }
71
72
73     /* quit */
74     if(strcmp(user_input, QUIT) == 0)
75         return(0);
76
77     b64_dec = decode_base64(user_input);
78     if(b64_dec == NULL)
79     {
80         printf(NO_KEY);
81         printf(PRESS_ENTER);
82         read_from_user();
83         return(0);
84     }
85
86
87     memset(line_read, '\0', FILE_SIZE +1);
88     strncpy(line_read, b64_dec, FILE_SIZE);
89
90
91     name = strchr(b64_dec, ' ');
92     if(name && strlen(line_read) < FILE_SIZE)
93     {
94         *name = '\0';
95         name++;
96         ip = strchr(name, ' ');
97         if(ip)
98         {
99             *ip = '\0';
100             ip++;
101
102             tmp_key = strchr(ip, ' ');
103             if(!tmp_key)
104             {
105                 printf(NO_KEY);
106                 return(0);
107             }
108             *tmp_key = '\0';
109
110             printf("\n");
111             printf(AGENT_INFO, b64_dec, name, ip);
112
113             while(1)
114             {
115                 printf(ADD_CONFIRM);
116                 fflush(stdout);
117
118                 user_input = getenv("OSSEC_ACTION_CONFIRMED");
119                 if (user_input == NULL) {
120                   user_input = read_from_user();
121                 }
122
123                 if(user_input[0] == 'y' || user_input[0] == 'Y')
124                 {
125                     fp = fopen(KEYS_FILE,"w");
126                     if(!fp)
127                     {
128                         ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE);
129                     }
130                     fprintf(fp,"%s\n",line_read);
131                     fclose(fp);
132                     #ifndef WIN32
133                     chmod(KEYS_FILE, 0440);
134                     #endif
135
136                     /* Removing sender counter. */
137                     OS_RemoveCounter("sender");
138
139                     printf(ADDED);
140                     printf(PRESS_ENTER);
141                     read_from_user();
142                     restart_necessary = 1;
143                     return(1);
144                 }
145                 else /* if(user_input[0] == 'n' || user_input[0] == 'N') */
146                 {
147                     printf("%s", ADD_NOT);
148                     return(0);
149                 }
150             }
151         }
152     }
153
154     printf(NO_KEY);
155     printf(PRESS_ENTER);
156     read_from_user();
157     return(0);
158
159 }
160
161
162 /* extract base64 for a specific agent */
163 int k_extract(char *cmdextract)
164 {
165     FILE *fp;
166     char *user_input;
167     char *b64_enc;
168     char line_read[FILE_SIZE +1];
169     char n_id[USER_SIZE +1];
170
171
172     if(cmdextract)
173     {
174         user_input = cmdextract;
175
176         if(!IDExist(user_input))
177         {
178             printf(NO_ID, user_input);
179             exit(1);
180         }
181     }
182
183     else
184     {
185         if(!print_agents(0, 0, 0))
186         {
187             printf(NO_AGENT);
188             printf(PRESS_ENTER);
189             read_from_user();
190             return(0);
191         }
192
193         do
194         {
195             printf(EXTRACT_KEY);
196             fflush(stdout);
197             user_input = read_from_user();
198
199             /* quit */
200             if(strcmp(user_input, QUIT) == 0)
201                 return(0);
202
203             if(!IDExist(user_input))
204                 printf(NO_ID, user_input);
205
206         } while(!IDExist(user_input));
207     }
208
209
210     /* Trying to open the auth file */
211     fp = fopen(AUTH_FILE, "r");
212     if(!fp)
213     {
214         ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE);
215     }
216
217     fsetpos(fp, &fp_pos);
218
219     memset(n_id, '\0', USER_SIZE +1);
220     strncpy(n_id, user_input, USER_SIZE -1);
221
222
223     if(fgets(line_read, FILE_SIZE, fp) == NULL)
224     {
225         printf(ERROR_KEYS);
226         fclose(fp);
227         exit(1);
228     }
229     chomp(line_read);
230
231
232     b64_enc = encode_base64(strlen(line_read),line_read);
233     if(b64_enc == NULL)
234     {
235         printf(EXTRACT_ERROR);
236         fclose(fp);
237         exit(1);
238     }
239
240     printf(EXTRACT_MSG, n_id, b64_enc);
241     if(!cmdextract)
242     {
243         printf("\n" PRESS_ENTER);
244         read_from_user();
245     }
246
247     free(b64_enc);
248     fclose(fp);
249
250     return(0);
251 }
252
253 /* Bulk generate client keys from file */
254 int k_bulkload(char *cmdbulk)
255 {
256     int i = 1;
257     FILE *fp, *infp;
258     char str1[STR_SIZE +1];
259     char str2[STR_SIZE +1];
260
261     os_md5 md1;
262     os_md5 md2;
263     char line[FILE_SIZE+1];
264     char name[FILE_SIZE +1];
265     char id[FILE_SIZE +1];
266     char ip[FILE_SIZE+1];
267     os_ip *c_ip;
268     char delims[] = ",";
269     char * token = NULL;
270
271     /* Checking if we can open the input file */
272     printf("Opening: [%s]\n", cmdbulk);
273     infp = fopen(cmdbulk,"r");
274     if(!infp)
275     {
276         perror("Failed.");
277         ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk);
278     }
279
280
281     /* Checking if we can open the auth_file */
282     fp = fopen(AUTH_FILE,"a");
283     if(!fp)
284     {
285         ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE);
286     }
287     fclose(fp);
288
289     /* Allocating for c_ip */
290     os_calloc(1, sizeof(os_ip), c_ip);
291
292         while(fgets(line, FILE_SIZE - 1, infp) != NULL)
293         {
294                 if (1 >= strlen(trimwhitespace(line)))
295                         continue;
296
297                 memset(ip, '\0', FILE_SIZE +1);
298                 token = strtok(line, delims);
299                 strncpy(ip, trimwhitespace(token),FILE_SIZE -1);
300
301                 memset(name, '\0', FILE_SIZE +1);
302                 token = strtok(NULL, delims);
303                 strncpy(name, trimwhitespace(token),FILE_SIZE -1);
304                         
305                 #ifndef WIN32
306                 chmod(AUTH_FILE, 0440);
307                 #endif
308
309                 /* Setting time 2 */
310                 time2 = time(0);
311
312
313                 /* Source is time1+ time2 +pid + ppid */
314                 #ifndef WIN32
315                         #ifdef __OpenBSD__
316                         srandomdev();
317                         #else
318                         srandom(time2 + time1 + getpid() + getppid());
319                         #endif
320                 #else
321                 srandom(time2 + time1 + getpid());
322                 #endif
323
324                 rand1 = random();
325
326
327                 /* Zeroing strings */
328                 memset(str1,'\0', STR_SIZE +1);
329                 memset(str2,'\0', STR_SIZE +1);
330
331
332                 /* check the name */
333                 if(!OS_IsValidName(name))
334                 {
335                 printf(INVALID_NAME,name);
336                 continue;
337                 }
338
339                 /* Search for name  -- no duplicates */
340                 if(NameExist(name))
341                 {
342                 printf(ADD_ERROR_NAME, name);
343                 continue;
344                 }
345
346
347                 if(!OS_IsValidIP(ip, c_ip))
348                 {
349                         printf(IP_ERROR, ip);
350                         continue;
351                 }
352
353                 do
354                 {
355                         /* Default ID */
356                         i = 1024;
357                         snprintf(id, 8, "%03d", i);
358                         while(!IDExist(id))
359                         {
360                         i--;
361                         snprintf(id, 8, "%03d", i);
362
363                         /* No key present, use id 0 */
364                         if(i <= 0)
365                         {
366                                 i = 0;
367                                 break;
368                         }
369                         }
370                         snprintf(id, 8, "%03d", i+1);
371
372                         if(!OS_IsValidID(id))
373                         printf(INVALID_ID, id);
374
375                         /* Search for ID KEY  -- no duplicates */
376                         if(IDExist(id))
377                         printf(ADD_ERROR_ID, id);
378
379                 } while(IDExist(id) || !OS_IsValidID(id));
380
381                 printf(AGENT_INFO, id, name, ip);
382                 fflush(stdout);
383
384
385                 time3 = time(0);
386                 rand2 = random();
387
388                 fp = fopen(AUTH_FILE,"a");
389                 if(!fp)
390                 {
391                 ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE);
392                 }
393                 #ifndef WIN32
394                 chmod(AUTH_FILE, 0440);
395                 #endif
396
397
398                 /* Random 1: Time took to write the agent information.
399                 * Random 2: Time took to choose the action.
400                 * Random 3: All of this + time + pid
401                 * Random 4: Md5 all of this + the name, key and ip
402                 * Random 5: Final key
403                 */
404
405                 snprintf(str1, STR_SIZE, "%d%s%d",time3-time2, name, rand1);
406                 snprintf(str2, STR_SIZE, "%d%s%s%d", time2-time1, ip, id, rand2);
407
408                 OS_MD5_Str(str1, md1);
409                 OS_MD5_Str(str2, md2);
410
411                 snprintf(str1, STR_SIZE, "%s%d%d%d",md1,(int)getpid(), (int)random(),
412                                             time3);
413                 OS_MD5_Str(str1, md1);
414
415                 //fprintf(fp,"%s %s %s %s%s\n",id, name, ip, md1,md2);
416                 fprintf(fp,"%s %s %s %s%s\n",id, name, c_ip->ip, md1,md2);
417
418                 fclose(fp);
419
420                 printf(AGENT_ADD);
421                 restart_necessary = 1;
422         };
423
424         fclose(infp);
425         return(0);
426 }
427
428
429 /* EOF */