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