1 /* Copyright (C) 2009 Trend Micro Inc.
2 * All rights reserved.
3 *
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
7 * Foundation
8 */
9
10 #include "shared.h"
11 #include "maild.h"
12 #ifdef LIBGEOIP_ENABLED
13 #include "config/config.h"
14 #endif
15
16
17 /* Receive a Message on the Mail queue */
OS_RecvMailQ(file_queue * fileq,struct tm * p,MailConfig * Mail,MailMsg ** msg_sms)18 MailMsg *OS_RecvMailQ(file_queue *fileq, struct tm *p,
19 MailConfig *Mail, MailMsg **msg_sms)
20 {
21 int i = 0, sms_set = 0, donotgroup = 0;
22 size_t body_size = OS_MAXSTR - 3, log_size;
23 char logs[OS_MAXSTR + 1];
24 char extra_data[OS_MAXSTR + 1];
25 char log_string[OS_MAXSTR / 4 + 1];
26 char *subject_host;
27 #ifdef LIBGEOIP_ENABLED
28 char geoip_msg_src[OS_SIZE_1024 + 1];
29 char geoip_msg_dst[OS_SIZE_1024 + 1];
30 #endif
31
32 MailMsg *mail;
33 alert_data *al_data;
34
35 Mail->priority = 0;
36
37 /* Get message if available */
38 al_data = Read_FileMon(fileq, p, mail_timeout);
39 if (!al_data) {
40 return (NULL);
41 }
42
43 /* If e-mail came correctly, generate the e-mail body/subject */
44 os_calloc(1, sizeof(MailMsg), mail);
45 os_calloc(BODY_SIZE, sizeof(char), mail->body);
46 os_calloc(SUBJECT_SIZE, sizeof(char), mail->subject);
47
48 /* Generate the logs */
49 logs[0] = '\0';
50 extra_data[0] = '\0';
51 logs[OS_MAXSTR] = '\0';
52
53 while (al_data->log[i]) {
54 log_size = strlen(al_data->log[i]) + 4;
55
56 /* If size left is small than the size of the log, stop it */
57 if (body_size <= log_size) {
58 break;
59 }
60
61 strncat(logs, al_data->log[i], body_size);
62 strncat(logs, "\r\n", body_size);
63 body_size -= log_size;
64 i++;
65 }
66
67 if (al_data->old_md5) {
68 log_size = strlen(al_data->old_md5) + 16 + 4;
69 if (body_size > log_size) {
70 strncat(logs, "Old md5sum was: ", 16);
71 strncat(logs, al_data->old_md5, body_size);
72 strncat(logs, "\r\n", 4);
73 body_size -= log_size;
74 }
75 }
76 if (al_data->new_md5) {
77 log_size = strlen(al_data->new_md5) + 16 + 4;
78 if (body_size > log_size) {
79 strncat(logs, "New md5sum is : ", 16);
80 strncat(logs, al_data->new_md5, body_size);
81 strncat(logs, "\r\n", 4);
82 body_size -= log_size;
83 }
84 }
85 if (al_data->old_sha1) {
86 log_size = strlen(al_data->old_sha1) + 17 + 4;
87 if (body_size > log_size) {
88 strncat(logs, "Old sha1sum was: ", 17);
89 strncat(logs, al_data->old_sha1, body_size);
90 strncat(logs, "\r\n", 4);
91 body_size -= log_size;
92 }
93 }
94 if (al_data->new_sha1) {
95 log_size = strlen(al_data->new_sha1) + 17 + 4;
96 if (body_size > log_size) {
97 strncat(logs, "New sha1sum is : ", 17);
98 strncat(logs, al_data->new_sha1, body_size);
99 strncat(logs, "\r\n", 4);
100 body_size -= log_size;
101 }
102 }
103 if (al_data->perm_chg) {
104 log_size = strlen(al_data->perm_chg) + 17 + 4;
105 if (body_size > log_size) {
106 strncat(logs, "Permission change: ", 20);
107 strncat(logs, al_data->perm_chg, body_size);
108 strncat(logs, "\r\n", 4);
109 body_size -= log_size;
110 }
111 }
112
113
114 /* EXTRA DATA */
115 if (al_data->srcip) {
116 log_size = snprintf(log_string, sizeof(log_string) - 1, "Src IP: %s\r\n", al_data->srcip );
117 if (body_size > log_size) {
118 if ( strncat(extra_data, log_string, log_size) != NULL ) {
119 body_size -= log_size;
120 }
121 }
122 }
123 if (al_data->dstip) {
124 log_size = snprintf(log_string, sizeof(log_string) - 1, "Dst IP: %s\r\n", al_data->dstip );
125 if (body_size > log_size) {
126 if ( strncat(extra_data, log_string, log_size) != NULL ) {
127 body_size -= log_size;
128 }
129 }
130 }
131 if (al_data->user) {
132 log_size = snprintf(log_string, sizeof(log_string) - 1, "User: %s\r\n", al_data->user );
133 if (body_size > log_size) {
134 if ( strncat(extra_data, log_string, log_size) != NULL ) {
135 body_size -= log_size;
136 }
137 }
138 }
139
140 /* Subject */
141 subject_host = strchr(al_data->location, '>');
142 if (subject_host) {
143 subject_host--;
144 *subject_host = '\0';
145 }
146
147 /* We have two subject options - full and normal */
148 if (Mail->subject_full == 0) {
149 /* Option for a clean full subject (without ossec in the name) */
150 #ifdef CLEANFULL
151 snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL2,
152 al_data->level,
153 al_data->comment,
154 al_data->location);
155 #else
156 snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT_FULL,
157 al_data->location,
158 al_data->level,
159 al_data->comment);
160 #endif
161 } else {
162 snprintf(mail->subject, SUBJECT_SIZE - 1, MAIL_SUBJECT,
163 al_data->location,
164 al_data->level);
165 }
166
167
168 /* Fix subject back */
169 if (subject_host) {
170 *subject_host = '-';
171 }
172
173 #ifdef LIBGEOIP_ENABLED
174 /* Get GeoIP information */
175 if (Mail->geoip) {
176 if (al_data->srcgeoip) {
177 snprintf(geoip_msg_src, OS_SIZE_1024, "Src Location: %s\r\n", al_data->srcgeoip);
178 } else {
179 geoip_msg_src[0] = '\0';
180 }
181 if (al_data->dstgeoip) {
182 snprintf(geoip_msg_dst, OS_SIZE_1024, "Dst Location: %s\r\n", al_data->dstgeoip);
183 } else {
184 geoip_msg_dst[0] = '\0';
185 }
186 } else {
187 geoip_msg_src[0] = '\0';
188 geoip_msg_dst[0] = '\0';
189 }
190 #endif
191
192 /* Body */
193 #ifdef LIBGEOIP_ENABLED
194 snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
195 al_data->date,
196 al_data->location,
197 al_data->rule,
198 al_data->level,
199 al_data->comment,
200 geoip_msg_src,
201 geoip_msg_dst,
202 extra_data,
203 logs);
204 #else
205 snprintf(mail->body, BODY_SIZE - 1, MAIL_BODY,
206 al_data->date,
207 al_data->location,
208 al_data->rule,
209 al_data->level,
210 al_data->comment,
211 extra_data,
212 logs);
213 #endif
214 debug2("OS_RecvMailQ: mail->body[%s]", mail->body);
215
216 /* Check for granular email configs */
217 if (Mail->gran_to) {
218 i = 0;
219 while (Mail->gran_to[i] != NULL) {
220 int gr_set = 0;
221
222 /* Look if location is set */
223 if (Mail->gran_location[i]) {
224 if (OSMatch_Execute(al_data->location,
225 strlen(al_data->location),
226 Mail->gran_location[i])) {
227 gr_set = 1;
228 } else {
229 i++;
230 continue;
231 }
232 }
233
234 /* Look for the level */
235 if (Mail->gran_level[i]) {
236 if (al_data->level >= Mail->gran_level[i]) {
237 gr_set = 1;
238 } else {
239 i++;
240 continue;
241 }
242 }
243
244 /* Look for rule id */
245 if (Mail->gran_id[i]) {
246 int id_i = 0;
247 while (Mail->gran_id[i][id_i] != 0) {
248 if (Mail->gran_id[i][id_i] == al_data->rule) {
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 gr_set = 1;
257 } else {
258 i++;
259 continue;
260 }
261 }
262
263 /* Look for the group */
264 if (Mail->gran_group[i]) {
265 if (OSMatch_Execute(al_data->group,
266 strlen(al_data->group),
267 Mail->gran_group[i])) {
268 gr_set = 1;
269 } else {
270 i++;
271 continue;
272 }
273 }
274
275 /* If we got here, everything matched. Set this e-mail to be used. */
276 if (gr_set) {
277 if (Mail->gran_format[i] == SMS_FORMAT) {
278 Mail->gran_set[i] = SMS_FORMAT;
279
280 /* Set the SMS flag */
281 sms_set = 1;
282 } else {
283 /* Options */
284 if (Mail->gran_format[i] == FORWARD_NOW) {
285 Mail->priority = 1;
286 Mail->gran_set[i] = FULL_FORMAT;
287 } else if (Mail->gran_format[i] == DONOTGROUP) {
288 Mail->priority = DONOTGROUP;
289 Mail->gran_set[i] = DONOTGROUP;
290 donotgroup = 1;
291 } else {
292 Mail->gran_set[i] = FULL_FORMAT;
293 }
294 }
295 }
296 i++;
297 }
298 }
299
300
301 /* If DONOTGROUP is set, we can't assign the new subject */
302 if (!donotgroup) {
303 /* Get highest level for alert */
304 if (_g_subject[0] != '\0') {
305 if (_g_subject_level < al_data->level) {
306 strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
307 _g_subject_level = al_data->level;
308 }
309 } else {
310 strncpy(_g_subject, mail->subject, SUBJECT_SIZE);
311 _g_subject_level = al_data->level;
312 }
313 }
314
315 /* If SMS is set, create the SMS output */
316 if (sms_set) {
317 MailMsg *msg_sms_tmp;
318
319 /* Allocate memory for SMS */
320 os_calloc(1, sizeof(MailMsg), msg_sms_tmp);
321 os_calloc(BODY_SIZE, sizeof(char), msg_sms_tmp->body);
322 os_calloc(SUBJECT_SIZE, sizeof(char), msg_sms_tmp->subject);
323
324 snprintf(msg_sms_tmp->subject, SUBJECT_SIZE - 1, SMS_SUBJECT,
325 al_data->level,
326 al_data->rule,
327 al_data->comment);
328
329
330 strncpy(msg_sms_tmp->body, logs, 128);
331 msg_sms_tmp->body[127] = '\0';
332 *msg_sms = msg_sms_tmp;
333 }
334
335 /* Clear the memory */
336 FreeAlertData(al_data);
337
338 return (mail);
339 }
340
341