Mercurial > syslog2iptables
annotate src/syslogconfig.cpp @ 57:c95acc20f7ed
Added tag stable-1-0-13-2 for changeset 73dd2daeaf8e
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Wed, 17 Aug 2011 10:16:17 -0700 |
parents | 206448c00b55 |
children | b45dddebe8fc |
rev | line source |
---|---|
36 | 1 /* |
2 | |
3 Copyright (c) 2007 Carl Byington - 510 Software Group, released under | |
4 the GPL version 3 or any later version at your choice available at | |
5 http://www.gnu.org/licenses/gpl-3.0.txt | |
6 | |
7 */ | |
1 | 8 |
9 #include "includes.h" | |
2 | 10 #include <fcntl.h> |
3 | 11 #include <sys/socket.h> |
12 #include <netinet/in.h> | |
13 #include <arpa/inet.h> | |
14 #include <netdb.h> | |
4 | 15 #include <limits.h> |
1 | 16 |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
17 const char *token_add; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
18 const char *token_bucket; |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
19 const char *token_context; |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
20 const char *token_file; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
21 const char *token_ignore; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
22 const char *token_include; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
23 const char *token_index; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
24 const char *token_lbrace; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
25 const char *token_message; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
26 const char *token_pattern; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
27 const char *token_rbrace; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
28 const char *token_remove; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
29 const char *token_semi; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
30 const char *token_slash; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
31 const char *token_threshold; |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
32 string_set all_strings;// owns all the strings, only modified by the config loader thread |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
33 recorder_map recorders; // all the recorders are named |
36 | 34 const int maxlen = 1000; // used for snprintf buffers |
3 | 35 |
36 | |
37 //////////////////////////////////////////////// | |
38 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
39 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
40 IPR::IPR() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
41 reference_count = 0; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
42 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
43 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
44 IPR* IPR::find(const char* name) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
45 recorder_map::iterator m = recorders.find(name); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
46 if (m == recorders.end()) recorders[name] = new IPR; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
47 recorders[name]->reference(1); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
48 return recorders[name]; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
49 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
50 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
51 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
52 void IPR::release(const char* name) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
53 recorder_map::iterator m = recorders.find(name); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
54 IPR* i = (*m).second; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
55 int r = i->reference(-1); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
56 if (r == 0) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
57 delete i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
58 recorders.erase(m); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
59 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
60 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
61 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
62 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
63 void IPR::add(int ip, int amount, CONTEXT &con, const char *file_name, int pattern_index, const char *message) { |
36 | 64 if (con.looking(ip)) { |
65 ip_buckets::iterator i = violations.find(ip); | |
66 if (i == violations.end()) { | |
67 bucket b; | |
68 b.count = amount; | |
69 b.latch = (con.get_threshold() <= b.count); | |
70 violations[ip] = b; | |
71 if (b.latch) { | |
72 update(ip, true, file_name, pattern_index, message); | |
73 changed(con, ip, true); | |
74 } | |
75 } | |
76 else { | |
77 bucket &b = (*i).second; | |
78 if (b.count < (INT_MAX-amount)) { | |
79 int t = con.get_threshold(); | |
80 int c = b.count; | |
81 b.count += amount; | |
82 if ((!b.latch) && (c < t) && (t <= b.count)) { | |
83 b.latch = true; | |
84 update(ip, true, file_name, pattern_index, message); | |
85 changed(con, ip, true); | |
86 } | |
87 } | |
88 } | |
89 } | |
3 | 90 } |
91 | |
92 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
93 void IPR::leak(int amount, CONTEXT &con) { |
36 | 94 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); ) { |
95 int ip = (*i).first; | |
96 bucket &b = (*i).second; | |
97 if (b.count <= amount) { | |
98 if (b.latch) { | |
99 update(ip, false, NULL, 0, NULL); | |
100 changed(con, ip, false); | |
101 } | |
102 violations.erase(i++); | |
103 } | |
104 else { | |
105 b.count -= amount; | |
106 i++; | |
107 } | |
108 } | |
109 } | |
110 | |
111 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
112 void IPR::free_all(CONTEXT &con) { |
37 | 113 if (debug_syslog > 2) { |
114 my_syslog("syslog2iptables shutting down"); | |
115 } | |
36 | 116 for (ip_buckets::iterator i=violations.begin(); i!=violations.end(); i++) { |
117 int ip = (*i).first; | |
118 bucket &b = (*i).second; | |
119 if (b.latch) { | |
120 update(ip, false, NULL, 0, NULL); | |
121 changed(con, ip, false); | |
122 } | |
123 } | |
124 violations.clear(); | |
20 | 125 } |
126 | |
127 | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
128 void IPR::update(int ip, bool added, const char *file_name, int pattern_index, const char *message) { |
36 | 129 if (debug_syslog > 2) { |
130 char buf[maxlen]; | |
131 in_addr ad; | |
132 ad.s_addr = htonl(ip); | |
133 if (added) { | |
134 if (message) snprintf(buf, maxlen, "dropping traffic from/to %s based on %s in %s", inet_ntoa(ad), message, file_name); | |
135 else snprintf(buf, maxlen, "dropping traffic from/to %s based on pattern match %d in %s", inet_ntoa(ad), pattern_index, file_name); | |
136 } | |
137 else snprintf(buf, maxlen, "allowing traffic from/to %s", inet_ntoa(ad)); | |
138 my_syslog(buf); | |
139 } | |
3 | 140 } |
141 | |
142 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
143 void IPR::changed(CONTEXT &con, int ip, bool added) { |
36 | 144 int t = con.get_threshold(); |
145 char buf[maxlen]; | |
146 if (added) { | |
147 bucket &b = violations[ip]; | |
148 if (con.looking(ip) && (b.count > t)) { | |
149 in_addr ad; | |
150 ad.s_addr = htonl(ip); | |
151 snprintf(buf, maxlen, con.add_command, inet_ntoa(ad)); | |
152 system(buf); | |
153 } | |
154 } | |
155 else { | |
156 in_addr ad; | |
157 ad.s_addr = htonl(ip); | |
158 snprintf(buf, maxlen, con.remove_command, inet_ntoa(ad)); | |
159 system(buf); | |
160 } | |
3 | 161 } |
1 | 162 |
163 | |
3 | 164 //////////////////////////////////////////////// |
165 // | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
166 int ip_address(const char *have); |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
167 int ip_address(const char *have) { |
36 | 168 int ipaddr = 0; |
169 in_addr ip; | |
170 if (inet_aton(have, &ip)) ipaddr = ip.s_addr; | |
171 else { | |
172 struct hostent *host = gethostbyname(have); | |
173 if (host && host->h_addrtype == AF_INET) memcpy(&ipaddr, host->h_addr, sizeof(ipaddr)); | |
174 } | |
175 return ntohl(ipaddr); | |
3 | 176 } |
177 | |
178 | |
179 //////////////////////////////////////////////// | |
180 // | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
181 PATTERN::PATTERN(TOKEN &tok, const char *pattern_, int index_, int amount_, const char *msg_) { |
36 | 182 pattern = pattern_; |
183 index = index_; | |
184 amount = amount_; | |
185 message = msg_; | |
186 if (pattern) { | |
187 int rc = regcomp(&re, pattern, REG_ICASE | REG_EXTENDED); | |
188 if (rc) { | |
189 char bu[maxlen]; | |
190 regerror(rc, &re, bu, maxlen); | |
191 char buf[maxlen]; | |
192 snprintf(buf, sizeof(buf), "pattern %s not valid - %s", pattern, bu); | |
193 tok.token_error(buf); | |
194 pattern = NULL; | |
195 } | |
196 } | |
3 | 197 } |
198 | |
199 | |
200 PATTERN::~PATTERN() { | |
36 | 201 regfree(&re); |
3 | 202 } |
203 | |
204 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
205 bool PATTERN::process(char *buf, CONTEXT &con, const char *file_name, int pattern_index) { |
36 | 206 if (pattern) { |
207 const int nmatch = index+1; | |
208 regmatch_t match[nmatch]; | |
209 if (0 == regexec(&re, buf, nmatch, match, 0)) { | |
210 int s = match[index].rm_so; | |
211 int e = match[index].rm_eo; | |
212 if (s != -1) { | |
213 if (debug_syslog > 3) { | |
214 my_syslog(buf); // show lines with matches | |
215 } | |
216 buf[e] = '\0'; | |
217 int ip = ip_address(buf+s); | |
218 if (ip) { | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
219 con.recorder->add(ip, amount, con, file_name, pattern_index, message); |
36 | 220 } |
221 return true; | |
222 } | |
223 } | |
224 } | |
225 return false; | |
3 | 226 } |
227 | |
228 | |
229 void PATTERN::dump(int level) { | |
36 | 230 char indent[maxlen]; |
231 int i = min(maxlen-1, level*4); | |
232 memset(indent, ' ', i); | |
233 indent[i] = '\0'; | |
234 printf("%s pattern \"%s\" {; \n", indent, pattern); | |
235 printf("%s index %d; \n", indent, index); | |
236 printf("%s bucket %d; \n", indent, amount); | |
237 if (message) printf("%s message \"%s\"; \n", indent, message); | |
238 printf("%s }; \n", indent); | |
3 | 239 } |
240 | |
241 | |
242 //////////////////////////////////////////////// | |
243 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
244 CONTEXT::CONTEXT(const char *nam) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
245 name = nam; |
36 | 246 threshold = 500; |
247 add_command = "/sbin/iptables -I INPUT --src %s --jump DROP"; | |
248 remove_command = "/sbin/iptables -D INPUT --src %s --jump DROP"; | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
249 recorder = IPR::find(name); |
1 | 250 } |
251 | |
252 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
253 //////////////////////////////////////////////// |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
254 // |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
255 CONTEXT::~CONTEXT() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
256 ignore.clear(); |
36 | 257 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { |
258 SYSLOGCONFIG *c = *i; | |
259 delete c; | |
260 } | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
261 IPR::release(name); |
1 | 262 } |
263 | |
264 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
265 void CONTEXT::add_syslogconfig(SYSLOGCONFIGP con) { |
36 | 266 syslogconfigs.push_back(con); |
1 | 267 } |
268 | |
269 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
270 void CONTEXT::add_pair(IPPAIR pair) { |
36 | 271 ignore.push_back(pair); |
3 | 272 } |
273 | |
274 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
275 void CONTEXT::dump() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
276 string indents(" "); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
277 const char *indent = indents.c_str(); |
3 | 278 |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
279 printf("context %s {\n", name); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
280 printf("%s threshold %d; \n\n", indent, threshold); |
27 | 281 |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
282 printf("%s add_command \"%s\"; \n", indent, add_command); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
283 printf("%s remove_command \"%s\"; \n\n", indent, remove_command); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
284 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
285 printf("%s ignore { \n", indent); |
36 | 286 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { |
287 IPPAIR &p = *i; | |
288 in_addr ip; | |
289 ip.s_addr = htonl(p.first); | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
290 printf("%s %s/%d; \n", indent, inet_ntoa(ip), p.cidr); |
36 | 291 } |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
292 printf("%s }; \n\n", indent); |
3 | 293 |
36 | 294 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { |
295 SYSLOGCONFIGP c = *i; | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
296 c->dump(1); |
36 | 297 } |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
298 printf("}; \n\n"); |
1 | 299 } |
300 | |
301 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
302 void CONTEXT::read(CONFIG &con) { |
36 | 303 while (true) { |
304 bool have = false; | |
305 for (syslogconfig_list::iterator i=syslogconfigs.begin(); i!=syslogconfigs.end(); i++) { | |
306 SYSLOGCONFIGP c = *i; | |
307 have |= c->read(*this); | |
308 } | |
309 if (!have) break; | |
310 } | |
2 | 311 } |
312 | |
313 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
314 void CONTEXT::free_all() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
315 recorder->free_all(*this); |
3 | 316 } |
317 | |
318 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
319 void CONTEXT::leak(int delta) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
320 recorder->leak(delta, *this); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
321 |
36 | 322 } |
323 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
324 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
325 bool CONTEXT::looking(int ip) { |
36 | 326 for (ippair_list::iterator i=ignore.begin(); i!=ignore.end(); i++) { |
327 IPPAIR &p = *i; | |
328 if ((p.first <= ip) && (ip <= p.last)) return false; | |
329 } | |
330 return true; | |
3 | 331 } |
332 | |
333 //////////////////////////////////////////////// | |
334 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
335 CONFIG::CONFIG() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
336 reference_count = 0; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
337 generation = 0; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
338 load_time = 0; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
339 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
340 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
341 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
342 CONFIG::~CONFIG() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
343 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
344 CONTEXT *c = *i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
345 delete c; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
346 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
347 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
348 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
349 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
350 void CONFIG::dump() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
351 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
352 CONTEXTP c = *i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
353 c->dump(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
354 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
355 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
356 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
357 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
358 void CONFIG::read() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
359 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
360 CONTEXT *c = *i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
361 c->read(*this); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
362 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
363 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
364 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
365 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
366 void CONFIG::sleep(int duration, time_t &previous) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
367 ::sleep(duration); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
368 time_t now = time(NULL); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
369 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
370 CONTEXT *c = *i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
371 c->leak(now-previous); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
372 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
373 previous = now; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
374 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
375 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
376 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
377 void CONFIG::free_all() { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
378 for (context_list::iterator i=contexts.begin(); i!=contexts.end(); i++) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
379 CONTEXT *c = *i; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
380 c->free_all(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
381 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
382 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
383 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
384 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
385 //////////////////////////////////////////////// |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
386 // |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
387 SYSLOGCONFIG::SYSLOGCONFIG(TOKEN &tok, const char *file_name_) { |
36 | 388 tokp = &tok; |
389 file_name = file_name_; | |
390 open(true); | |
1 | 391 } |
392 | |
393 | |
394 SYSLOGCONFIG::~SYSLOGCONFIG() { | |
36 | 395 close(); |
396 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { | |
397 PATTERN *p = *i; | |
398 delete p; | |
399 } | |
2 | 400 } |
401 | |
402 | |
4 | 403 void SYSLOGCONFIG::open(bool msg) { |
36 | 404 fd = ::open(file_name, O_RDONLY); |
405 len = 0; | |
406 if (fd == -1) { | |
407 if (msg) { | |
408 char buf[maxlen]; | |
409 snprintf(buf, sizeof(buf), "syslog file %s not readable", file_name); | |
410 tokp->token_error(buf); | |
411 } | |
412 } | |
413 else { | |
414 if (debug_syslog > 1) { | |
415 snprintf(buf, sizeof(buf), "syslog file %s opened", file_name); | |
416 my_syslog(buf); | |
417 } | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
418 if (msg) lseek(fd, 0, SEEK_END); |
36 | 419 if (fstat(fd, &openfdstat)) { |
420 close(); | |
421 snprintf(buf, sizeof(buf), "syslog file %s cannot stat after open", file_name); | |
422 tokp->token_error(buf); | |
423 } | |
424 // specify that this fd gets closed on exec, so that selinux | |
425 // won't complain about iptables trying to read log files. | |
426 int oldflags = fcntl(fd, F_GETFD, 0); | |
427 if (oldflags >= 0) { | |
428 fcntl(fd, F_SETFD, oldflags | FD_CLOEXEC); | |
429 } | |
430 } | |
3 | 431 } |
432 | |
433 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
434 bool SYSLOGCONFIG::read(CONTEXT &con) { |
36 | 435 if (failed()) { |
436 open(false); | |
437 if (failed()) return false; | |
438 } | |
439 int n = ::read(fd, buf+len, buflen-len); | |
440 bool have = (n > 0); | |
441 if (have) { | |
442 len += n; | |
443 while (true) { | |
444 char *p = (char*)memchr(buf, '\n', len); | |
445 if (!p) break; | |
446 n = p-buf; | |
447 *p = '\0'; | |
448 process(con); // process null terminated string | |
449 len -= n+1; | |
450 memmove(buf, p+1, len); | |
451 } | |
452 // no <lf> in a full buffer | |
453 if (len == buflen) len = 0; | |
454 } | |
455 else { | |
456 // check for file close | |
457 struct stat filenamest; | |
458 if (0 == stat(file_name, &filenamest)) { | |
459 if ((filenamest.st_dev != openfdstat.st_dev) || | |
460 (filenamest.st_ino != openfdstat.st_ino)) { | |
461 close(); | |
462 } | |
463 } | |
464 else { | |
465 // filename no longer exists | |
466 close(); | |
467 } | |
468 } | |
469 return have; | |
2 | 470 } |
471 | |
472 | |
4 | 473 void SYSLOGCONFIG::close() { |
36 | 474 if (debug_syslog > 1) { |
475 snprintf(buf, sizeof(buf), "syslog file %s closed", file_name); | |
476 my_syslog(buf); | |
477 } | |
478 if (fd != -1) ::close(fd); | |
479 fd = -1; | |
4 | 480 } |
481 | |
482 | |
483 void SYSLOGCONFIG::add_pattern(PATTERNP pat) { | |
36 | 484 patterns.push_back(pat); |
4 | 485 } |
486 | |
487 | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
488 void SYSLOGCONFIG::process(CONTEXT &con) { |
36 | 489 int pi=0; |
490 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { | |
491 PATTERN *p = *i; | |
492 if (p->process(buf, con, file_name, pi)) break; | |
493 pi++; | |
494 } | |
1 | 495 } |
496 | |
497 | |
498 void SYSLOGCONFIG::dump(int level) { | |
36 | 499 char indent[maxlen]; |
500 int i = min(maxlen-1, level*4); | |
501 memset(indent, ' ', i); | |
502 indent[i] = '\0'; | |
503 printf("%s file \"%s\" {\n", indent, file_name); | |
504 for (pattern_list::iterator i=patterns.begin(); i!=patterns.end(); i++) { | |
505 PATTERN *p = *i; | |
506 p->dump(level+1); | |
507 } | |
508 printf("%s }; \n", indent); | |
1 | 509 } |
510 | |
511 | |
512 //////////////////////////////////////////////// | |
513 // helper to discard the strings held by a string_set | |
514 // | |
515 void discard(string_set &s) { | |
36 | 516 for (string_set::iterator i=s.begin(); i!=s.end(); i++) { |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
517 free((void*)*i); |
36 | 518 } |
519 s.clear(); | |
1 | 520 } |
521 | |
522 | |
523 //////////////////////////////////////////////// | |
524 // helper to register a string in a string set | |
525 // | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
526 const char* register_string(string_set &s, const char *name) { |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
527 string_set::const_iterator i = s.find(name); |
36 | 528 if (i != s.end()) return *i; |
529 char *x = strdup(name); | |
530 s.insert(x); | |
531 return x; | |
1 | 532 } |
533 | |
534 | |
535 //////////////////////////////////////////////// | |
536 // register a global string | |
537 // | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
538 const char* register_string(const char *name) { |
36 | 539 return register_string(all_strings, name); |
1 | 540 } |
541 | |
542 | |
543 //////////////////////////////////////////////// | |
38 | 544 // clear all global strings, helper for valgrind checking |
545 // | |
546 void clear_strings() { | |
547 discard(all_strings); | |
548 } | |
549 | |
550 | |
551 //////////////////////////////////////////////// | |
1 | 552 // |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
553 bool tsa(TOKEN &tok, const char *token); |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
554 bool tsa(TOKEN &tok, const char *token) { |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
555 const char *have = tok.next(); |
36 | 556 if (have == token) return true; |
557 tok.token_error(token, have); | |
558 return false; | |
1 | 559 } |
560 | |
561 | |
562 //////////////////////////////////////////////// | |
563 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
564 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con, CONTEXT &me); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
565 bool parse_pattern(TOKEN &tok, SYSLOGCONFIG &con, CONTEXT &me) { |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
566 const char *pat = tok.next(); |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
567 int ind = 0; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
568 int buc = 0; |
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
569 const char *msg = NULL; |
36 | 570 if (!tsa(tok, token_lbrace)) return false; |
571 while (true) { | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
572 const char *have = tok.next(); |
36 | 573 if (!have) break; |
574 if (have == token_rbrace) break; | |
575 if (have == token_index) { | |
576 have = tok.next(); | |
577 ind = atoi(have); | |
578 if (!tsa(tok, token_semi)) return false; | |
579 } | |
580 else if (have == token_bucket) { | |
581 have = tok.next(); | |
582 buc = atoi(have); | |
583 if (!tsa(tok, token_semi)) return false; | |
584 } | |
585 else if (have == token_message) { | |
586 msg = tok.next(); | |
587 if (!tsa(tok, token_semi)) return false; | |
588 } | |
589 else { | |
590 tok.token_error("index/bucket", have); | |
591 return false; | |
592 } | |
593 } | |
594 if (!tsa(tok, token_semi)) return false; | |
595 PATTERNP patt = new PATTERN(tok, pat, ind, buc, msg); | |
596 con.add_pattern(patt); | |
597 return true; | |
3 | 598 } |
599 | |
600 | |
601 //////////////////////////////////////////////// | |
602 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
603 bool parse_ignore(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
604 bool parse_ignore(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
36 | 605 if (!tsa(tok, token_lbrace)) return false; |
606 while (true) { | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
607 const char *have = tok.next(); |
36 | 608 if (!have) break; |
609 if (have == token_rbrace) break; | |
610 int ipaddr = ip_address(have); | |
611 if (ipaddr == 0) { | |
612 tok.token_error("ip address", have); | |
613 return false; | |
614 } | |
615 if (!tsa(tok, token_slash)) return false; | |
616 have = tok.next(); | |
617 int mask = atoi(have); | |
618 if ((mask < 8) || (mask > 32)) { | |
619 tok.token_error("cidr 8..32 value", have); | |
620 return false; | |
621 } | |
622 if (!tsa(tok, token_semi)) return false; | |
623 IPPAIR pair; | |
624 const int masks[33] = {0xffffffff, // 0 | |
625 0x7fffffff, // 1 | |
626 0x3fffffff, // 2 | |
627 0x1fffffff, // 3 | |
628 0x0fffffff, // 4 | |
629 0x07ffffff, // 5 | |
630 0x03ffffff, // 6 | |
631 0x01ffffff, // 7 | |
632 0x00ffffff, // 8 | |
633 0x007fffff, // 9 | |
634 0x003fffff, // 10 | |
635 0x001fffff, // 11 | |
636 0x000fffff, // 12 | |
637 0x0007ffff, // 13 | |
638 0x0003ffff, // 14 | |
639 0x0001ffff, // 15 | |
640 0x0000ffff, // 16 | |
641 0x00007fff, // 17 | |
642 0x00003fff, // 18 | |
643 0x00001fff, // 19 | |
644 0x00000fff, // 20 | |
645 0x000007ff, // 21 | |
646 0x000003ff, // 22 | |
647 0x000001ff, // 23 | |
648 0x000000ff, // 24 | |
649 0x0000007f, // 25 | |
650 0x0000003f, // 26 | |
651 0x0000001f, // 27 | |
652 0x0000000f, // 28 | |
653 0x00000007, // 29 | |
654 0x00000003, // 30 | |
655 0x00000001, // 31 | |
656 0x00000000}; // 32 | |
657 pair.first = ipaddr; | |
658 pair.last = ipaddr | masks[mask]; | |
659 pair.cidr = mask; | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
660 me.add_pair(pair); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
661 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
662 if (!tsa(tok, token_semi)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
663 return true; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
664 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
665 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
666 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
667 //////////////////////////////////////////////// |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
668 // |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
669 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc, CONTEXT &me); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
670 bool parse_syslogconfig(TOKEN &tok, CONFIG &dc, CONTEXT &me) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
671 const char *name = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
672 if (!tsa(tok, token_lbrace)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
673 SYSLOGCONFIGP con = new SYSLOGCONFIG(tok, name); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
674 if (con->failed()) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
675 delete con; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
676 return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
677 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
678 me.add_syslogconfig(con); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
679 while (true) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
680 const char *have = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
681 if (!have) break; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
682 if (have == token_rbrace) break; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
683 if (have == token_pattern) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
684 if (!parse_pattern(tok, *con, me)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
685 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
686 else { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
687 tok.token_error("pattern", have); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
688 return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
689 } |
36 | 690 } |
691 if (!tsa(tok, token_semi)) return false; | |
692 return true; | |
3 | 693 } |
694 | |
695 | |
696 //////////////////////////////////////////////// | |
697 // | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
698 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
699 bool parse_context(TOKEN &tok, CONFIG &dc, CONTEXTP parent) { |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
700 const char *name = tok.next(); |
36 | 701 if (!tsa(tok, token_lbrace)) return false; |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
702 CONTEXTP con = new CONTEXT(name); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
703 |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
704 while (true) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
705 const char *have = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
706 if (!have) break; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
707 if (have == token_rbrace) break; // done |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
708 if (have == token_threshold) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
709 have = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
710 con->set_threshold(atoi(have)); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
711 if (!tsa(tok, token_semi)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
712 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
713 else if (have == token_ignore) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
714 if (!parse_ignore(tok, dc, *con)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
715 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
716 else if (have == token_add) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
717 have = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
718 con->set_add(have); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
719 if (!tsa(tok, token_semi)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
720 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
721 else if (have == token_remove) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
722 have = tok.next(); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
723 con->set_remove(have); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
724 if (!tsa(tok, token_semi)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
725 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
726 else if (have == token_file) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
727 if (!parse_syslogconfig(tok, dc, *con)) return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
728 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
729 else { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
730 tok.token_error("threshold/ignore/add_command/remove_command/file", have); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
731 return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
732 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
733 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
734 if (!tsa(tok, token_semi)) { |
36 | 735 delete con; |
736 return false; | |
737 } | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
738 dc.add_context(con); |
36 | 739 return true; |
1 | 740 } |
741 | |
742 | |
743 //////////////////////////////////////////////// | |
744 // parse a config file | |
745 // | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
746 bool load_conf(CONFIG &dc, const char *fn) { |
36 | 747 int count = 0; |
748 TOKEN tok(fn, &dc.config_files); | |
749 while (true) { | |
48
ba0259c9e411
Fixes to compile on Fedora 9 and for const correctness
Carl Byington <carl@five-ten-sg.com>
parents:
42
diff
changeset
|
750 const char *have = tok.next(); |
36 | 751 if (!have) break; |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
752 if (have == token_context) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
753 if (!parse_context(tok, dc, NULL)) { |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
754 tok.token_error("load_conf() failed to parse context"); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
755 return false; |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
756 } |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
757 else count++; |
36 | 758 } |
759 else { | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
760 tok.token_error(token_context, have); |
36 | 761 return false; |
762 } | |
763 } | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
764 tok.token_error("load_conf() found %d contexts in %s", count, fn); |
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
765 return (!dc.contexts.empty()); |
1 | 766 } |
767 | |
768 | |
769 //////////////////////////////////////////////// | |
770 // init the tokens | |
771 // | |
772 void token_init() { | |
36 | 773 token_add = register_string("add_command"); |
774 token_bucket = register_string("bucket"); | |
51
206448c00b55
Allow multiple contexts with independent add/remove commands.
Carl Byington <carl@five-ten-sg.com>
parents:
48
diff
changeset
|
775 token_context = register_string("context"); |
36 | 776 token_file = register_string("file"); |
777 token_ignore = register_string("ignore"); | |
778 token_include = register_string("include"); | |
779 token_index = register_string("index"); | |
780 token_lbrace = register_string("{"); | |
781 token_message = register_string("message"); | |
782 token_pattern = register_string("pattern"); | |
783 token_rbrace = register_string("}"); | |
784 token_remove = register_string("remove_command"); | |
785 token_semi = register_string(";"); | |
786 token_slash = register_string("/"); | |
787 token_threshold = register_string("threshold"); | |
1 | 788 } |