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