Mercurial > dnsbl
comparison src/dnsbl.cpp @ 12:6ac6d6b822ce stable-2-0
fix memory leak with duplicate url host names,
document differences from sendmail.mc feature
author | carl |
---|---|
date | Fri, 23 Apr 2004 22:45:10 -0700 |
parents | 2c206836b4cc |
children | 2752e512fd32 |
comparison
equal
deleted
inserted
replaced
11:2c206836b4cc | 12:6ac6d6b822ce |
---|---|
144 static pthread_mutex_t config_mutex; | 144 static pthread_mutex_t config_mutex; |
145 static pthread_mutex_t syslog_mutex; | 145 static pthread_mutex_t syslog_mutex; |
146 static pthread_mutex_t resolve_mutex; | 146 static pthread_mutex_t resolve_mutex; |
147 | 147 |
148 | 148 |
149 | |
150 // include the content scanner | |
151 #include "scanner.cpp" | |
152 | |
153 | |
154 //////////////////////////////////////////////// | 149 //////////////////////////////////////////////// |
155 // helper to discard the strings held by a string_set | 150 // helper to discard the strings held by a string_set |
156 // | 151 // |
157 static void discard(string_set &s); | 152 static void discard(string_set &s); |
158 static void discard(string_set &s) { | 153 static void discard(string_set &s) { |
159 for (string_set::iterator i=s.begin(); i!=s.end(); i++) { | 154 for (string_set::iterator i=s.begin(); i!=s.end(); i++) { |
160 free(*i); | 155 free(*i); |
161 } | 156 } |
162 s.clear(); | 157 s.clear(); |
163 } | 158 } |
159 | |
160 //////////////////////////////////////////////// | |
161 // helper to register a string in a string set | |
162 // | |
163 static char* register_string(string_set &s, char *name); | |
164 static char* register_string(string_set &s, char *name) { | |
165 string_set::iterator i = s.find(name); | |
166 if (i != s.end()) return *i; | |
167 char *x = strdup(name); | |
168 s.insert(x); | |
169 return x; | |
170 } | |
171 | |
172 // include the content scanner | |
173 #include "scanner.cpp" | |
174 | |
164 | 175 |
165 | 176 |
166 //////////////////////////////////////////////// | 177 //////////////////////////////////////////////// |
167 // mail filter private data, held for us by sendmail | 178 // mail filter private data, held for us by sendmail |
168 // | 179 // |
177 bool authenticated; // client authenticated? if so, suppress all dnsbl checks | 188 bool authenticated; // client authenticated? if so, suppress all dnsbl checks |
178 bool have_whites; // have at least one whitelisted recipient? need to accept content and remove all non-whitelisted recipients if it fails | 189 bool have_whites; // have at least one whitelisted recipient? need to accept content and remove all non-whitelisted recipients if it fails |
179 bool only_whites; // every recipient is whitelisted? | 190 bool only_whites; // every recipient is whitelisted? |
180 url_scanner *scanner; // object to handle body scanning | 191 url_scanner *scanner; // object to handle body scanning |
181 string_set non_whites; // remember the non-whitelisted recipients so we can remove them if need be | 192 string_set non_whites; // remember the non-whitelisted recipients so we can remove them if need be |
182 string_set urls; // remember the urls that we have checked | 193 string_set hosts; // remember the hosts that we have checked |
183 mlfiPriv(); | 194 mlfiPriv(); |
184 ~mlfiPriv(); | 195 ~mlfiPriv(); |
185 void reset(bool final = false); // for a new message | 196 void reset(bool final = false); // for a new message |
186 }; | 197 }; |
187 mlfiPriv::mlfiPriv() { | 198 mlfiPriv::mlfiPriv() { |
192 ip = 0; | 203 ip = 0; |
193 mailaddr = NULL; | 204 mailaddr = NULL; |
194 authenticated = false; | 205 authenticated = false; |
195 have_whites = false; | 206 have_whites = false; |
196 only_whites = true; | 207 only_whites = true; |
197 scanner = new url_scanner(&urls); | 208 scanner = new url_scanner(&hosts); |
198 } | 209 } |
199 mlfiPriv::~mlfiPriv() { | 210 mlfiPriv::~mlfiPriv() { |
200 pthread_mutex_lock(&config_mutex); | 211 pthread_mutex_lock(&config_mutex); |
201 pc->reference_count--; | 212 pc->reference_count--; |
202 pthread_mutex_unlock(&config_mutex); | 213 pthread_mutex_unlock(&config_mutex); |
204 } | 215 } |
205 void mlfiPriv::reset(bool final) { | 216 void mlfiPriv::reset(bool final) { |
206 if (mailaddr) free(mailaddr); | 217 if (mailaddr) free(mailaddr); |
207 delete scanner; | 218 delete scanner; |
208 discard(non_whites); | 219 discard(non_whites); |
209 discard(urls); | 220 discard(hosts); |
210 if (!final) { | 221 if (!final) { |
211 mailaddr = NULL; | 222 mailaddr = NULL; |
212 authenticated = false; | 223 authenticated = false; |
213 have_whites = false; | 224 have_whites = false; |
214 only_whites = true; | 225 only_whites = true; |
215 scanner = new url_scanner(&urls); | 226 scanner = new url_scanner(&hosts); |
216 } | 227 } |
217 } | 228 } |
218 | 229 |
219 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) | 230 #define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx)) |
220 | 231 |
235 //////////////////////////////////////////////// | 246 //////////////////////////////////////////////// |
236 // register a global string | 247 // register a global string |
237 // | 248 // |
238 static char* register_string(char *name); | 249 static char* register_string(char *name); |
239 static char* register_string(char *name) { | 250 static char* register_string(char *name) { |
240 string_set::iterator i = all_strings.find(name); | 251 return register_string(all_strings, name); |
241 if (i != all_strings.end()) return *i; | |
242 char *x = strdup(name); | |
243 all_strings.insert(x); | |
244 return x; | |
245 } | 252 } |
246 | 253 |
247 | 254 |
248 static char* next_token(char *delim); | 255 static char* next_token(char *delim); |
249 static char* next_token(char *delim) { | 256 static char* next_token(char *delim) { |
423 | 430 |
424 | 431 |
425 //////////////////////////////////////////////// | 432 //////////////////////////////////////////////// |
426 // check the dnsbls specified for this recipient | 433 // check the dnsbls specified for this recipient |
427 // | 434 // |
428 static status check_urls(mlfiPriv &priv, char *&url, int &ip); | 435 static status check_hosts(mlfiPriv &priv, char *&url, int &ip); |
429 static status check_urls(mlfiPriv &priv, char *&url, int &ip) { | 436 static status check_hosts(mlfiPriv &priv, char *&url, int &ip) { |
430 CONFIG &dc = *priv.pc; | 437 CONFIG &dc = *priv.pc; |
431 if (!dc.content_suffix) return oksofar; | 438 if (!dc.content_suffix) return oksofar; |
432 int count = 0; | 439 int count = 0; |
433 for (string_set::iterator i=priv.urls.begin(); i!=priv.urls.end(); i++) { | 440 for (string_set::iterator i=priv.hosts.begin(); i!=priv.hosts.end(); i++) { |
434 count++; | 441 count++; |
435 if (count > 20) return oksofar; // silly to check too many urls | 442 if (count > 20) return oksofar; // silly to check too many hosts |
436 url = *i; | 443 url = *i; |
437 char buf[200]; | 444 char buf[200]; |
438 snprintf(buf, sizeof(buf), "looking for url %s", url); | 445 snprintf(buf, sizeof(buf), "looking for url %s", url); |
439 my_syslog(buf); | 446 my_syslog(buf); |
440 ip = protected_dns_interface(url); | 447 ip = protected_dns_interface(url); |
524 } | 531 } |
525 else { | 532 else { |
526 // accept the recipient | 533 // accept the recipient |
527 if (st == oksofar) { | 534 if (st == oksofar) { |
528 // but remember the non-whites | 535 // but remember the non-whites |
529 priv.non_whites.insert(strdup(rcptaddr)); | 536 register_string(priv.non_whites, rcptaddr); |
530 priv.only_whites = false; | 537 priv.only_whites = false; |
531 } | 538 } |
532 if (st == white) { | 539 if (st == white) { |
533 priv.have_whites = true; | 540 priv.have_whites = true; |
534 } | 541 } |
552 char *url = NULL; | 559 char *url = NULL; |
553 int ip; | 560 int ip; |
554 // process end of message | 561 // process end of message |
555 if (priv.authenticated || | 562 if (priv.authenticated || |
556 priv.only_whites || | 563 priv.only_whites || |
557 (check_urls(priv, url, ip) == oksofar)) rc = SMFIS_CONTINUE; | 564 (check_hosts(priv, url, ip) == oksofar)) rc = SMFIS_CONTINUE; |
558 else { | 565 else { |
559 if (!priv.have_whites) { | 566 if (!priv.have_whites) { |
560 // can reject the entire message | 567 // can reject the entire message |
561 char adr[sizeof "255.255.255.255"]; | 568 char adr[sizeof "255.255.255.255"]; |
562 adr[0] = '\0'; | 569 adr[0] = '\0'; |