1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right 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 #include "shared.h"
10 #include "mail-config.h"
11 #include "config.h"
12 
13 
Read_EmailAlerts(XML_NODE node,void * configp,void * mailp)14 int Read_EmailAlerts(XML_NODE node, __attribute__((unused)) void *configp, void *mailp)
15 {
16     int i = 0;
17     unsigned int granto_size = 0;
18 
19     /* XML definitions */
20     const char *xml_email_to = "email_to";
21     const char *xml_email_format = "format";
22     const char *xml_email_level = "level";
23     const char *xml_email_id = "rule_id";
24     const char *xml_email_group = "group";
25     const char *xml_email_location = "event_location";
26     const char *xml_email_donotdelay = "do_not_delay";
27     const char *xml_email_donotgroup = "do_not_group";
28 
29     MailConfig *Mail;
30 
31     Mail = (MailConfig *)mailp;
32     if (!Mail) {
33         return (0);
34     }
35 
36     /* Get Granular mail_to size */
37     if (Mail && Mail->gran_to) {
38         char **ww;
39         ww = Mail->gran_to;
40         while (*ww != NULL) {
41             ww++;
42             granto_size++;
43         }
44     }
45 
46     if (Mail) {
47         os_realloc(Mail->gran_to,
48                    sizeof(char *) * (granto_size + 2), Mail->gran_to);
49         os_realloc(Mail->gran_id,
50                    sizeof(unsigned int *) * (granto_size + 2), Mail->gran_id);
51         os_realloc(Mail->gran_level,
52                    sizeof(unsigned int) * (granto_size + 2), Mail->gran_level);
53         os_realloc(Mail->gran_set,
54                    sizeof(int) * (granto_size + 2), Mail->gran_set);
55         os_realloc(Mail->gran_format,
56                    sizeof(int) * (granto_size + 2), Mail->gran_format);
57         os_realloc(Mail->gran_location,
58                    sizeof(OSMatch *) * (granto_size + 2), Mail->gran_location);
59         os_realloc(Mail->gran_group,
60                    sizeof(OSMatch *) * (granto_size + 2), Mail->gran_group);
61 
62         Mail->gran_to[granto_size] = NULL;
63         Mail->gran_to[granto_size + 1] = NULL;
64 
65         Mail->gran_id[granto_size] = NULL;
66         Mail->gran_id[granto_size + 1] = NULL;
67 
68         Mail->gran_location[granto_size] = NULL;
69         Mail->gran_location[granto_size + 1] = NULL;
70 
71         Mail->gran_group[granto_size] = NULL;
72         Mail->gran_group[granto_size + 1] = NULL;
73 
74         Mail->gran_level[granto_size] = 0;
75         Mail->gran_level[granto_size + 1] = 0;
76 
77         Mail->gran_format[granto_size] = FULL_FORMAT;
78         Mail->gran_format[granto_size + 1] = FULL_FORMAT;
79 
80         Mail->gran_set[granto_size] = 0;
81         Mail->gran_set[granto_size + 1] = 0;
82     }
83 
84     while (node[i]) {
85         if (!node[i]->element) {
86             merror(XML_ELEMNULL, __local_name);
87             return (OS_INVALID);
88         } else if (!node[i]->content) {
89             merror(XML_VALUENULL, __local_name, node[i]->element);
90             return (OS_INVALID);
91         }
92         /* Mail notification */
93         else if (strcmp(node[i]->element, xml_email_level) == 0) {
94             if (!OS_StrIsNum(node[i]->content)) {
95                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
96                 return (OS_INVALID);
97             }
98 
99             Mail->gran_level[granto_size] = atoi(node[i]->content);
100         } else if (strcmp(node[i]->element, xml_email_to) == 0) {
101             os_strdup(node[i]->content, Mail->gran_to[granto_size]);
102         } else if (strcmp(node[i]->element, xml_email_id) == 0) {
103             int r_id = 0;
104             char *str_pt = node[i]->content;
105 
106             while (*str_pt != '\0') {
107                 /* We allow spaces in between */
108                 if (*str_pt == ' ') {
109                     str_pt++;
110                     continue;
111                 }
112 
113                 /* If is digit, we get the value and
114                  * search for the next digit available
115                  */
116                 else if (isdigit((int)*str_pt)) {
117                     unsigned int id_i = 0;
118 
119                     r_id = atoi(str_pt);
120                     debug1("%s: DEBUG: Adding '%d' to granular e-mail",
121                            __local_name, r_id);
122 
123                     if (!Mail->gran_id[granto_size]) {
124                         os_calloc(2, sizeof(unsigned int), Mail->gran_id[granto_size]);
125                         Mail->gran_id[granto_size][0] = 0;
126                         Mail->gran_id[granto_size][1] = 0;
127                     } else {
128                         while (Mail->gran_id[granto_size][id_i] != 0) {
129                             id_i++;
130                         }
131 
132                         os_realloc(Mail->gran_id[granto_size],
133                                    (id_i + 2) * sizeof(unsigned int),
134                                    Mail->gran_id[granto_size]);
135                         Mail->gran_id[granto_size][id_i + 1] = 0;
136                     }
137                     Mail->gran_id[granto_size][id_i] = r_id;
138 
139                     str_pt = strchr(str_pt, ',');
140                     if (str_pt) {
141                         str_pt++;
142                     } else {
143                         break;
144                     }
145                 }
146 
147                 /* Check for duplicate commas */
148                 else if (*str_pt == ',') {
149                     str_pt++;
150                     continue;
151                 }
152 
153                 else {
154                     break;
155                 }
156             }
157 
158         } else if (strcmp(node[i]->element, xml_email_format) == 0) {
159             if (strcmp(node[i]->content, "default") == 0) {
160                 /* Default is full format */
161             } else {
162                 merror(XML_VALUEERR, __local_name, node[i]->element, node[i]->content);
163                 return (OS_INVALID);
164             }
165         } else if (strcmp(node[i]->element, xml_email_donotdelay) == 0) {
166             if ((Mail->gran_format[granto_size] != SMS_FORMAT) &&
167                     (Mail->gran_format[granto_size] != DONOTGROUP)) {
168                 Mail->gran_format[granto_size] = FORWARD_NOW;
169             }
170         } else if (strcmp(node[i]->element, xml_email_donotgroup) == 0) {
171             if (Mail->gran_format[granto_size] != SMS_FORMAT) {
172                 Mail->gran_format[granto_size] = DONOTGROUP;
173             }
174         } else if (strcmp(node[i]->element, xml_email_location) == 0) {
175             os_calloc(1, sizeof(OSMatch), Mail->gran_location[granto_size]);
176             if (!OSMatch_Compile(node[i]->content,
177                                  Mail->gran_location[granto_size], 0)) {
178                 merror(REGEX_COMPILE, __local_name, node[i]->content,
179                        Mail->gran_location[granto_size]->error);
180                 return (-1);
181             }
182         } else if (strcmp(node[i]->element, xml_email_group) == 0) {
183             os_calloc(1, sizeof(OSMatch), Mail->gran_group[granto_size]);
184             if (!OSMatch_Compile(node[i]->content,
185                                  Mail->gran_group[granto_size], 0)) {
186                 merror(REGEX_COMPILE, __local_name, node[i]->content,
187                        Mail->gran_group[granto_size]->error);
188                 return (-1);
189             }
190         } else {
191             merror(XML_INVELEM, __local_name, node[i]->element);
192             return (OS_INVALID);
193         }
194         i++;
195     }
196 
197     /* We must have at least one entry set */
198     if ((Mail->gran_location[granto_size] == NULL &&
199             Mail->gran_level[granto_size] == 0 &&
200             Mail->gran_group[granto_size] == NULL &&
201             Mail->gran_id[granto_size] == NULL &&
202             Mail->gran_format[granto_size] == FULL_FORMAT) ||
203             Mail->gran_to[granto_size] == NULL) {
204         merror(XML_INV_GRAN_MAIL, __local_name);
205         return (OS_INVALID);
206     }
207 
208     return (0);
209 }
210 
211