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