b9ab116d652545bf3a12d8c0026793ddb5be5479
[ossec-hids.git] / src / client-agent / receiver.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All right 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
12
13 #include "shared.h"
14
15
16 #ifdef WIN32
17 #include "os_execd/execd.h"
18 #endif
19
20
21 #include "os_crypto/md5/md5_op.h"
22 #include "os_net/os_net.h"
23
24
25 #include "agentd.h"
26
27 FILE *fp = NULL;
28 char file_sum[34] = "";
29 char file[OS_SIZE_1024 +1] = "";
30
31
32 /* receive_msg: 
33  * Receive events from the server.
34  */
35 void *receive_msg()
36 {
37     int recv_b;
38
39     char buffer[OS_MAXSTR +1];
40
41     char cleartext[OS_MAXSTR + 1];
42     char *tmp_msg;
43
44
45     memset(cleartext, '\0', OS_MAXSTR +1);
46     memset(buffer, '\0', OS_MAXSTR +1);
47
48
49
50     /* Read until no more messages are available */ 
51     while((recv_b = recv(logr->sock, buffer, OS_SIZE_1024, MSG_DONTWAIT)) > 0)
52     {
53         buffer[recv_b] = '\0';
54
55         tmp_msg = ReadSecMSG(&keys, buffer, cleartext, 0, recv_b -1);
56         if(tmp_msg == NULL)
57         {
58             merror(MSG_ERROR,ARGV0,logr->rip[logr->rip_id]);
59             continue;
60         }
61
62
63         /* Check for commands */
64         if(IsValidHeader(tmp_msg))
65         {
66             available_server = (int)time(NULL);
67
68
69             #ifdef WIN32
70             /* Run timeout commands. */
71             if(logr->execdq >= 0)
72                 WinTimeoutRun(available_server);
73             #endif
74
75
76             /* If it is an active response message */
77             if(strncmp(tmp_msg, EXECD_HEADER, strlen(EXECD_HEADER)) == 0)
78             {
79                 tmp_msg+=strlen(EXECD_HEADER);
80
81                 #ifndef WIN32
82                 if(logr->execdq >= 0)
83                 {
84                     if(OS_SendUnix(logr->execdq, tmp_msg, 0) < 0)
85                     {
86                         merror("%s: Error communicating with execd", 
87                                 ARGV0);
88                     }
89                 }
90
91                 #else
92
93
94                 /* Run on windows. */
95                 if(logr->execdq >= 0)
96                 {
97                     WinExecdRun(tmp_msg);
98                 }
99
100                 #endif
101
102
103                 continue;
104             } 
105
106
107             /* Restart syscheck. */
108             else if(strcmp(tmp_msg, HC_SK_RESTART) == 0)
109             {
110                 os_set_restart_syscheck();
111                 continue;
112             }
113
114
115             /* Ack from server */
116             else if(strcmp(tmp_msg, HC_ACK) == 0)
117             {
118                 continue;
119             }
120
121
122             /* Close any open file pointer if it was being written to */
123             if(fp)
124             {
125                 fclose(fp);
126                 fp = NULL;
127             }
128
129
130             /* File update message */
131             if(strncmp(tmp_msg, FILE_UPDATE_HEADER, 
132                        strlen(FILE_UPDATE_HEADER)) == 0)
133             {
134                 char *validate_file;
135
136                 tmp_msg += strlen(FILE_UPDATE_HEADER);
137
138                 /* Going to after the file sum */
139                 validate_file = strchr(tmp_msg, ' ');
140                 if(!validate_file)
141                 {
142                     continue;
143                 }
144
145                 *validate_file = '\0';
146
147                 /* copying the file sum */
148                 strncpy(file_sum, tmp_msg, 33);
149
150
151                 /* Setting tmp_msg to the beginning of the file name */
152                 validate_file++;
153                 tmp_msg = validate_file;
154
155
156                 if((validate_file = strchr(tmp_msg, '\n')) != NULL)
157                 {
158                     *validate_file = '\0';
159                 }
160
161                 while((validate_file = strchr(tmp_msg, '/')) != NULL)
162                 {
163                     *validate_file = '-';
164                 }
165
166                 if(tmp_msg[0] == '.')
167                     tmp_msg[0] = '-';            
168
169
170                 snprintf(file, OS_SIZE_1024, "%s/%s", 
171                         SHAREDCFG_DIR,
172                         tmp_msg);
173
174
175                 fp = fopen(file, "w");
176                 if(!fp)
177                 {
178                     merror(FOPEN_ERROR, ARGV0, file);
179                 }
180             }
181
182             else if(strncmp(tmp_msg, FILE_CLOSE_HEADER, 
183                         strlen(FILE_CLOSE_HEADER)) == 0)
184             {
185                 /* no error */
186                 os_md5 currently_md5;
187
188                 /* Making sure to close for the rename to work */
189                 if(fp)
190                 {
191                     fclose(fp);
192                     fp = NULL;
193                 }
194
195                 if(file[0] == '\0')
196                 {
197                     /* nada */
198                 }
199
200                 else if(OS_MD5_File(file, currently_md5) < 0)
201                 {
202                     /* Removing file */
203                     unlink(file);
204                     file[0] = '\0';
205                 }
206                 else
207                 {
208                     if(strcmp(currently_md5, file_sum) != 0)
209                     {
210                         debug1("%s: ERROR: Failed md5 for: %s -- deleting.",
211                                 ARGV0, file); 
212                         unlink(file);
213                     }
214                     else
215                     {
216                         char *final_file;
217
218                         /* Renaming the file to its orignal name */
219                         final_file = strrchr(file, '/');
220                         if(final_file)
221                         {
222                             if(strcmp(final_file + 1, SHAREDCFG_FILENAME) == 0)
223                             {
224                                 UnmergeFiles(file, SHAREDCFG_DIR);
225                             }
226                         }
227                         else
228                         {
229                             /* Removing file. */
230                             unlink(file);
231                         }
232                     }
233
234                     file[0] = '\0';
235                 }
236             }
237
238             else
239             {
240                 merror("%s: WARN: Unknown message received from server.", ARGV0);
241             }
242         }
243
244         else if(fp)
245         {
246             available_server = (int)time(NULL);
247             fprintf(fp, "%s", tmp_msg);
248         }
249
250         else
251         {
252             merror("%s: WARN: Unknown message received. No action defined.",
253                     ARGV0);
254         }
255     }    
256
257
258     return(NULL);
259
260 }
261
262
263 /* EOF */