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';