Imported Upstream version 2.7
[ossec-hids.git] / src / os_crypto / shared / keys.c
1 /* @(#) $Id: ./src/os_crypto/shared/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
18 #include "headers/shared.h"
19 #include "headers/sec.h"
20
21 #include "os_zlib/os_zlib.h"
22 #include "os_crypto/md5/md5_op.h"
23 #include "os_crypto/blowfish/bf_op.h"
24
25
26
27 /* __memclear: Clears keys entries.
28  */
29 void __memclear(char *id, char *name, char *ip, char *key, int size)
30 {
31         memset(id,'\0', size);
32         memset(name,'\0', size);
33         memset(key,'\0', size);
34         memset(ip,'\0', size);
35 }
36
37
38 /* __chash: Creates the final key.
39  */
40 void __chash(keystore *keys, char *id, char *name, char *ip, char *key)
41 {
42         os_md5 filesum1;
43         os_md5 filesum2;
44
45     char *tmp_str;
46         char _finalstr[KEYSIZE];
47
48
49     /* Allocating for the whole structure */
50     keys->keyentries =(keyentry **)realloc(keys->keyentries,
51                                          (keys->keysize+2)*sizeof(keyentry *));
52     if(!keys->keyentries)
53     {
54         ErrorExit(MEM_ERROR, __local_name);
55     }
56     os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]);
57
58
59     /* Setting configured values for id */
60     os_strdup(id, keys->keyentries[keys->keysize]->id);
61     OSHash_Add(keys->keyhash_id,
62                keys->keyentries[keys->keysize]->id,
63                keys->keyentries[keys->keysize]);
64
65
66     /* agent ip */
67     os_calloc(1, sizeof(os_ip), keys->keyentries[keys->keysize]->ip);
68     if(OS_IsValidIP(ip, keys->keyentries[keys->keysize]->ip) == 0)
69     {
70         ErrorExit(INVALID_IP, __local_name, ip);
71     }
72
73     /* We need to remove the "/" from the cidr */
74         if((tmp_str = strchr(keys->keyentries[keys->keysize]->ip->ip, '/')) != NULL)
75     {
76         *tmp_str = '\0';
77     }
78     OSHash_Add(keys->keyhash_ip,
79                keys->keyentries[keys->keysize]->ip->ip,
80                keys->keyentries[keys->keysize]);
81
82
83     /* agent name */
84     os_strdup(name, keys->keyentries[keys->keysize]->name);
85
86     /* Initializing the variables */
87     keys->keyentries[keys->keysize]->rcvd = 0;
88     keys->keyentries[keys->keysize]->local = 0;
89     keys->keyentries[keys->keysize]->keyid = keys->keysize;
90     keys->keyentries[keys->keysize]->global = 0;
91     keys->keyentries[keys->keysize]->fp = NULL;
92
93         
94
95         /** Generating final symmetric key **/
96
97         /* MD5 from name, id and key */
98         OS_MD5_Str(name, filesum1);     
99         OS_MD5_Str(id,  filesum2);
100
101
102         /* Generating new filesum1 */
103         snprintf(_finalstr, sizeof(_finalstr)-1, "%s%s", filesum1, filesum2);
104
105         
106     /* Using just half of the first md5 (name/id) */
107     OS_MD5_Str(_finalstr, filesum1);
108     filesum1[15] = '\0';        
109     filesum1[16] = '\0';
110
111
112     /* Second md is just the key */
113     OS_MD5_Str(key, filesum2);  
114         
115
116         /* Generating final key */
117         memset(_finalstr,'\0', sizeof(_finalstr));
118         snprintf(_finalstr, 49, "%s%s", filesum2, filesum1);
119
120
121     /* Final key is 48 * 4 = 192bits */
122     os_strdup(_finalstr, keys->keyentries[keys->keysize]->key);
123
124
125         /* Cleaning final string from memory */
126         memset(_finalstr,'\0', sizeof(_finalstr));
127
128
129         /* ready for next */
130         keys->keysize++;        
131
132
133         return;
134 }
135
136
137 /* int OS_CheckKeys():
138  * Checks if the authentication key file is present
139  */
140 int OS_CheckKeys()
141 {
142     FILE *fp;
143
144     if(File_DateofChange(KEYSFILE_PATH) < 0)
145     {
146         merror(NO_AUTHFILE, __local_name, KEYSFILE_PATH);
147         merror(NO_REM_CONN, __local_name);
148         return(0);
149     }
150
151     fp = fopen(KEYSFILE_PATH, "r");
152     if(!fp)
153     {
154         /* We can leave from here */
155         merror(FOPEN_ERROR, __local_name, KEYSFILE_PATH);
156         merror(NO_AUTHFILE, __local_name, KEYSFILE_PATH);
157         merror(NO_REM_CONN, __local_name);
158         return(0);
159     }
160
161     fclose(fp);
162
163
164     /* Authentication keys are present */
165     return(1);
166 }
167
168
169 /* void OS_ReadKeys(keystore *keys)
170  * Read the authentication keys.
171  */
172 void OS_ReadKeys(keystore *keys)
173 {
174     FILE *fp;
175
176     char buffer[OS_BUFFER_SIZE +1];
177
178     char name[KEYSIZE +1];
179     char ip[KEYSIZE +1];
180     char id[KEYSIZE +1];
181     char key[KEYSIZE +1];
182
183
184     /* Checking if the keys file is present and we can read it. */
185     if((keys->file_change = File_DateofChange(KEYS_FILE)) < 0)
186     {
187         merror(NO_AUTHFILE, __local_name, KEYS_FILE);
188         ErrorExit(NO_REM_CONN, __local_name);
189     }
190     fp = fopen(KEYS_FILE,"r");
191     if(!fp)
192     {
193         /* We can leave from here */
194         merror(FOPEN_ERROR, __local_name, KEYS_FILE);
195         ErrorExit(NO_REM_CONN, __local_name);
196     }
197
198
199     /* Initilizing hashes */
200     keys->keyhash_id = OSHash_Create();
201     keys->keyhash_ip = OSHash_Create();
202     if(!keys->keyhash_id || !keys->keyhash_ip)
203     {
204         ErrorExit(MEM_ERROR, __local_name);
205     }
206
207
208     /* Initializing structure */
209     keys->keyentries = NULL;
210     keys->keysize = 0;
211
212
213     /* Zeroing the buffers */
214     __memclear(id, name, ip, key, KEYSIZE +1);
215     memset(buffer, '\0', OS_BUFFER_SIZE +1);
216
217
218     /* Reading each line.
219      * lines are divided as "id name ip key"
220      */
221     while(fgets(buffer, OS_BUFFER_SIZE, fp) != NULL)
222     {
223         char *tmp_str;
224         char *valid_str;
225
226         if((buffer[0] == '#') || (buffer[0] == ' '))
227             continue;
228
229
230         /* Getting ID */
231         valid_str = buffer;
232         tmp_str = strchr(buffer, ' ');
233         if(!tmp_str)
234         {
235             merror(INVALID_KEY, __local_name, buffer);
236             continue;
237         }
238
239         *tmp_str = '\0';
240         tmp_str++;
241         strncpy(id, valid_str, KEYSIZE -1);
242
243         /* Removed entry. */
244         if(*tmp_str == '#')
245         {
246             continue;
247         }
248
249         /* Getting name */
250         valid_str = tmp_str;
251         tmp_str = strchr(tmp_str, ' ');
252         if(!tmp_str)
253         {
254             merror(INVALID_KEY, __local_name, buffer);
255         }
256
257         *tmp_str = '\0';
258         tmp_str++;
259         strncpy(name, valid_str, KEYSIZE -1);
260
261
262         /* Getting ip address */
263         valid_str = tmp_str;
264         tmp_str = strchr(tmp_str, ' ');
265         if(!tmp_str)
266         {
267             merror(INVALID_KEY, __local_name, buffer);
268         }
269
270         *tmp_str = '\0';
271         tmp_str++;
272         strncpy(ip, valid_str, KEYSIZE -1);
273
274
275         /* Getting key */
276         valid_str = tmp_str;
277         tmp_str = strchr(tmp_str, '\n');
278         if(tmp_str)
279         {
280             *tmp_str = '\0';
281         }
282
283         strncpy(key, valid_str, KEYSIZE -1);
284
285
286         /* Generating the key hash */
287         __chash(keys, id, name, ip, key);
288
289
290         /* Clearing the memory */
291         __memclear(id, name, ip, key, KEYSIZE +1);
292
293
294         /* Checking for maximum agent size */
295         if(keys->keysize >= (MAX_AGENTS -2))
296         {
297             merror(AG_MAX_ERROR, __local_name, MAX_AGENTS -2);
298             ErrorExit(CONFIG_ERROR, __local_name, KEYS_FILE);
299         }
300
301         continue;
302     }
303
304
305     /* Closing key file. */
306     fclose(fp);
307
308
309     /* clear one last time before leaving */
310     __memclear(id, name, ip, key, KEYSIZE +1);          
311
312
313     /* Checking if there is any agent available */
314     if(keys->keysize == 0)
315     {
316         ErrorExit(NO_REM_CONN, __local_name);
317     }
318
319
320     /* Adding additional entry for sender == keysize */
321     os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]);
322
323
324     return;
325 }
326
327
328 /* void __keysfree()
329  * Frees the auth keys.
330  */
331 void OS_FreeKeys(keystore *keys)
332 {
333     int i = 0;
334     int _keysize = 0;
335     void *hashid;
336     void *haship;
337
338     _keysize = keys->keysize;
339     hashid = keys->keyhash_id;
340     haship = keys->keyhash_ip;
341
342
343     /* Zeroing the entries. */
344     keys->keysize = 0;
345     keys->keyhash_id =NULL;
346     keys->keyhash_ip = NULL;
347
348
349     /* Sleeping to give time to other threads to stop using them. */
350     sleep(1);
351
352
353     /* Freeing the hashes */
354     OSHash_Free(hashid);
355     OSHash_Free(haship);
356
357
358     for(i = 0; i<= _keysize; i++)
359     {
360         if(keys->keyentries[i])
361         {
362             if(keys->keyentries[i]->ip)
363             {
364                 free(keys->keyentries[i]->ip->ip);
365                 free(keys->keyentries[i]->ip);
366             }
367
368             if(keys->keyentries[i]->id)
369                 free(keys->keyentries[i]->id);
370
371             if(keys->keyentries[i]->key)
372                 free(keys->keyentries[i]->key);
373
374             if(keys->keyentries[i]->name)
375                 free(keys->keyentries[i]->name);
376
377             /* Closing counter */
378             if(keys->keyentries[i]->fp)
379                 fclose(keys->keyentries[i]->fp);
380
381             free(keys->keyentries[i]);
382             keys->keyentries[i] = NULL;
383         }
384     }
385
386     /* Freeing structure */
387     free(keys->keyentries);
388     keys->keyentries = NULL;
389     keys->keysize = 0;
390 }
391
392
393 /* int OS_CheckUpdateKeys(keystore *keys)
394  * Checks if key changed.
395  */
396 int OS_CheckUpdateKeys(keystore *keys)
397 {
398     if(keys->file_change !=  File_DateofChange(KEYS_FILE))
399     {
400         return(1);
401     }
402     return(0);
403 }
404
405
406 /* OS_UpdateKeys(keystore *keys)
407  * Update the keys if changed.
408  */
409 int OS_UpdateKeys(keystore *keys)
410 {
411     if(keys->file_change !=  File_DateofChange(KEYS_FILE))
412     {
413         merror(ENCFILE_CHANGED, __local_name);
414         debug1("%s: DEBUG: Freekeys", __local_name);
415
416         OS_FreeKeys(keys);
417         debug1("%s: DEBUG: OS_ReadKeys", __local_name);
418
419         /* Reading keys */
420         verbose(ENC_READ, __local_name);
421
422
423         OS_ReadKeys(keys);
424         debug1("%s: DEBUG: OS_StartCounter", __local_name);
425
426         OS_StartCounter(keys);
427         debug1("%s: DEBUG: OS_UpdateKeys completed", __local_name);
428
429         return(1);
430     }
431     return(0);
432 }
433
434
435 /* OS_IsAllowedIP()
436  * Checks if an IP address is allowed to connect.
437  */
438 int OS_IsAllowedIP(keystore *keys, char *srcip)
439 {
440     keyentry *entry;
441
442     if(srcip == NULL)
443         return(-1);
444
445     entry = OSHash_Get(keys->keyhash_ip, srcip);
446     if(entry)
447     {
448         return(entry->keyid);
449     }
450
451     return(-1);
452 }
453
454
455 /* int OS_IsAllowedName
456  * Checks if the agent name is valid.
457  */
458 int OS_IsAllowedName(keystore *keys, char *name)
459 {
460     int i = 0;
461
462     for(i = 0; i < keys->keysize; i++)
463     {
464         if(strcmp(keys->keyentries[i]->name, name) == 0)
465             return(i);
466     }
467
468     return(-1);
469 }
470
471
472 /* OS_IsAllowedID
473  */
474 int OS_IsAllowedID(keystore *keys, char *id)
475 {
476     keyentry *entry;
477
478     if(id == NULL)
479         return(-1);
480
481     entry = OSHash_Get(keys->keyhash_id, id);
482     if(entry)
483     {
484         return(entry->keyid);
485     }
486     return(-1);
487 }
488
489
490 /* int OS_IsAllowedDynamicID -- Used for dynamic ip addresses.
491  */
492 int OS_IsAllowedDynamicID(keystore *keys, char *id, char *srcip)
493 {
494     keyentry *entry;
495
496     if(id == NULL)
497         return(-1);
498
499     entry = OSHash_Get(keys->keyhash_id, id);
500     if(entry)
501     {
502         if(OS_IPFound(srcip, entry->ip))
503         {
504             return(entry->keyid);
505         }
506     }
507
508     return(-1);
509 }
510
511
512 /* EOF */