Imported Upstream version 2.7
[ossec-hids.git] / src / os_maild / os_maild_client.c
1 /* @(#) $Id: ./src/os_maild/os_maild_client.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
13
14 #include "shared.h"
15 #include "maild.h"
16
17 /* GeoIP Stuff */
18 #ifdef GEOIP
19 #include "config/config.h"
20 #endif
21
22 /* OS_RecvMailQ,
23  * v0.1, 2005/03/15
24  * Receive a Message on the Mail queue
25  * v0,2: Using the new file-queue.
26  */
27 MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p,
28                       MailConfig *Mail, MailMsg **msg_sms)
29 {
30     int i = 0, body_size = OS_MAXSTR -3, log_size, sms_set = 0,donotgroup = 0;
31     char logs[OS_MAXSTR + 1];
32     char *subject_host;
33 #ifdef GEOIP
34     char geoip_msg_src[OS_SIZE_1024 +1];
35     char geoip_msg_dst[OS_SIZE_1024 +1];
36 #endif
37
38     MailMsg *mail;
39     alert_data *al_data;
40
41     Mail->priority = 0;
42
43
44     /* Get message if available */
45     al_data = Read_FileMon(fileq, p, mail_timeout);
46     if(!al_data)
47         return(NULL);
48
49
50     /* If e-mail came correctly, generate the e-mail body/subject */
51     os_calloc(1,sizeof(MailMsg), mail);
52     os_calloc(BODY_SIZE, sizeof(char), mail->body);
53     os_calloc(SUBJECT_SIZE, sizeof(char), mail->subject);
54
55
56     /* Generating the logs */
57     logs[0] = '\0';
58     logs[OS_MAXSTR] = '\0';
59
60     while(al_data->log[i])
61     {
62         log_size = strlen(al_data->log[i]) + 4;
63
64         /* If size left is small than the size of the log, stop it */
65         if(body_size <= log_size)
66         {
67             break;
68         }
69
70         strncat(logs, al_data->log[i], body_size);
71         strncat(logs, "\r\n", body_size);
72         body_size -= log_size;
73         i++;
74     }
75
76     if (al_data->old_md5) 
77     {
78         log_size = strlen(al_data->old_md5) + 16 + 4;
79         if(body_size > log_size)
80         {
81             strncat(logs, "Old md5sum was: ", 16);
82             strncat(logs, al_data->old_md5, body_size);
83             strncat(logs, "\r\n", 4);
84             body_size -= log_size;
85         }
86     }
87     if (al_data->new_md5) 
88     {
89         log_size = strlen(al_data->new_md5) + 16 + 4;
90         if(body_size > log_size)
91         {
92             strncat(logs, "New md5sum is : ", 16);
93             strncat(logs, al_data->new_md5, body_size);
94             strncat(logs, "\r\n", 4);
95             body_size -= log_size;
96         }
97     }
98     if (al_data->old_sha1) 
99     {
100         log_size = strlen(al_data->old_sha1) + 17 + 4;
101         if(body_size > log_size)
102         {
103             strncat(logs, "Old sha1sum was: ", 17);
104             strncat(logs, al_data->old_sha1, body_size);
105             strncat(logs, "\r\n", 4);
106             body_size -= log_size;
107         }
108     }
109     if (al_data->new_sha1) 
110     {
111         log_size = strlen(al_data->new_sha1) + 17 + 4;
112         if(body_size > log_size)
113         {
114             strncat(logs, "New sha1sum is : ", 17);
115             strncat(logs, al_data->new_sha1, body_size);
116             strncat(logs, "\r\n", 4);
117             body_size -= log_size;
118         }
119     }
120
121
122     /* Subject */
123     subject_host = strchr(al_data->location, '>');
124     if(subject_host)
125     {
126         subject_host--;
127         *subject_host = '\0';
128     }
129
130     /* We have two subject options - full and normal */
131     if(Mail->subject_full)
132     {
133         /* Option for a clean full subject (without ossec in the name) */
134         #ifdef CLEANFULL
135         snprintf(mail->subject, SUBJECT_SIZE -1, MAIL_SUBJECT_FULL2,
136                                 al_data->level,
137                                 al_data->comment,
138                                 al_data->location);
139         #else
140         snprintf(mail->subject, SUBJECT_SIZE -1, MAIL_SUBJECT_FULL,
141                                 al_data->location,
142                                 al_data->level,
143                                 al_data->comment);
144         #endif
145     }
146     else
147     {
148         snprintf(mail->subject, SUBJECT_SIZE -1, MAIL_SUBJECT,
149                                              al_data->location,
150                                              al_data->level);
151     }
152
153
154     /* fixing subject back */
155     if(subject_host)
156     {
157         *subject_host = '-';
158     }
159
160 #ifdef GEOIP
161     /* Get GeoIP information */
162     if (Mail->geoip) {
163        if (al_data->geoipdatasrc) {
164            snprintf(geoip_msg_src, OS_SIZE_1024, "Src Location: %s\r\n", al_data->geoipdatasrc);
165        } else {
166            geoip_msg_src[0] = '\0';
167        }
168        if (al_data->geoipdatadst) {
169            snprintf(geoip_msg_dst, OS_SIZE_1024, "Dst Location: %s\r\n", al_data->geoipdatadst);
170        } else {
171            geoip_msg_dst[0] = '\0';
172        }
173     }
174     else {
175        geoip_msg_src[0] = '\0';
176        geoip_msg_dst[0] = '\0';
177     }
178 #endif
179
180     /* Body */
181 #ifdef GEOIP
182     snprintf(mail->body, BODY_SIZE -1, MAIL_BODY,
183             al_data->date,
184             al_data->location,
185             al_data->rule,
186             al_data->level,
187             al_data->comment,
188             geoip_msg_src,
189             geoip_msg_dst,
190             logs);
191 #else
192     snprintf(mail->body, BODY_SIZE -1, MAIL_BODY,
193             al_data->date,
194             al_data->location,
195             al_data->rule,
196             al_data->level,
197             al_data->comment,
198             logs);
199 #endif
200     debug2("OS_RecvMailQ: mail->body[%s]", mail->body);
201
202     /* Checking for granular email configs */
203     if(Mail->gran_to)
204     {
205         i = 0;
206         while(Mail->gran_to[i] != NULL)
207         {
208             int gr_set = 0;
209
210             /* Looking if location is set */
211             if(Mail->gran_location[i])
212             {
213                 if(OSMatch_Execute(al_data->location,
214                                    strlen(al_data->location),
215                                    Mail->gran_location[i]))
216                 {
217                     gr_set = 1;
218                 }
219                 else
220                 {
221                     i++;
222                     continue;
223                 }
224             }
225
226             /* Looking for the level */
227             if(Mail->gran_level[i])
228             {
229                 if(al_data->level >= Mail->gran_level[i])
230                 {
231                     gr_set = 1;
232                 }
233                 else
234                 {
235                     i++;
236                     continue;
237                 }
238             }
239
240
241             /* Looking for rule id */
242             if(Mail->gran_id[i])
243             {
244                 int id_i = 0;
245                 while(Mail->gran_id[i][id_i] != 0)
246                 {
247                     if(Mail->gran_id[i][id_i] == al_data->rule)
248                     {
249                         break;
250                     }
251                     id_i++;
252                 }
253
254                 /* If we found, id is going to be a valid rule */
255                 if(Mail->gran_id[i][id_i])
256                 {
257                     gr_set = 1;
258                 }
259                 else
260                 {
261                     i++;
262                     continue;
263                 }
264             }
265
266
267             /* Looking for the group */
268             if(Mail->gran_group[i])
269             {
270                 if(OSMatch_Execute(al_data->group,
271                                    strlen(al_data->group),
272                                    Mail->gran_group[i]))
273                 {
274                     gr_set = 1;
275                 }
276                 else
277                 {
278                     i++;
279                     continue;
280                 }
281             }
282
283
284             /* If we got in here, it is because everything
285              * matched. Set this e-mail to be used.
286              */
287             if(gr_set)
288             {
289                 if(Mail->gran_format[i] == SMS_FORMAT)
290                 {
291                     Mail->gran_set[i] = SMS_FORMAT;
292
293                     /* Setting the SMS flag */
294                     sms_set = 1;
295                 }
296                 else
297                 {
298                     /* Options */
299                     if(Mail->gran_format[i] == FORWARD_NOW)
300                     {
301                         Mail->priority = 1;
302                         Mail->gran_set[i] = FULL_FORMAT;
303                     }
304                     else if(Mail->gran_format[i] == DONOTGROUP)
305                     {
306                         Mail->priority = DONOTGROUP;
307                         Mail->gran_set[i] = DONOTGROUP;
308                         donotgroup = 1;
309                     }
310                     else
311                     {
312                         Mail->gran_set[i] = FULL_FORMAT;
313                     }
314                 }
315             }
316             i++;
317         }
318     }
319
320
321     /* If DONOTGROUP is set, we can't assign the new subject */
322     if(!donotgroup)
323     {
324         /* Getting highest level for alert */
325         if(_g_subject[0] != '\0')
326         {
327             if(_g_subject_level < al_data->level)
328             {
329                 strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
330                 _g_subject_level = al_data->level;
331             }
332         }
333         else
334         {
335             strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
336             _g_subject_level = al_data->level;
337         }
338     }
339
340
341     /* If sms is set, create the sms output */
342     if(sms_set)
343     {
344         MailMsg *msg_sms_tmp;
345
346         /* Allocate memory for sms */
347         os_calloc(1,sizeof(MailMsg), msg_sms_tmp);
348         os_calloc(BODY_SIZE, sizeof(char), msg_sms_tmp->body);
349         os_calloc(SUBJECT_SIZE, sizeof(char), msg_sms_tmp->subject);
350
351         snprintf(msg_sms_tmp->subject, SUBJECT_SIZE -1, SMS_SUBJECT,
352                                       al_data->level,
353                                       al_data->rule,
354                                       al_data->comment);
355
356
357         strncpy(msg_sms_tmp->body, logs, 128);
358         msg_sms_tmp->body[127] = '\0';
359
360         /* Assigning msg_sms */
361         *msg_sms = msg_sms_tmp;
362     }
363
364
365
366     /* Clearing the memory */
367     FreeAlertData(al_data);
368
369
370     return(mail);
371
372 }
373 /* EOF */