View Single Post
Old 09-20-07, 10:09 PM   #5
evilghost
Registered User
 
Join Date: Jul 2005
Posts: 3,606
Default Re: C++ Gurus, School Me :D

Note, I no longer own the domain stickit.nu, the site is now NSFW. This code may help you, I wrote it a while back for use with qmail in .qmail files for |condredirect I believe.

Code:
// Spamfilter by evilghost
//
// Version 4.1 Beta
// Release date March 19, 2003
//
// Spam Filter Beta 4.1 - with wildcard domain support.
// Modified by evilghost@stickit.nu Nov 28, 2001
//      + Added default exit code of 1.
// Modified by evilghost@stickit.nu Feb 09, 2002
//      + Added Single-line denied log file syntax
//      + Modified invalid argument output to fit on screen
//      + Stripped newline character from datet() function
//      + Added tab delimitted log output
//      + Added comment support with '#' character in spamlist.txt
//      + Added valid spam address filter testing
// Modified by evilghost@stickit.nu July 03, 2002
//      + Added subdomain support, syntax is '@*.domain.com'
// Modified by evilghost@stickit.nu March 19, 2003
//      + Enabled Debug Mode for $SENDER and $RECIPIENT arguments
//      + Removed strlwr() function and included in main functions due to pointer issues.

#include <fstream.h>
#include <string>
#include <time.h>
#include <ctype.h>

   void print_log(int, char*, char*, char*, char*);
   void check(char*, char*, char*, char*);
   char* datet();
   string ddate;        //Added in 4.01

   void main(int argc, char* argv[]){
      if((argv[1] == NULL) || (argv[2] == NULL) || (argv[3] == NULL) || (argv[4] == NULL)){
         cout << "Spamfilter Beta 4.1\n";
         cout << "Usage: " << argv[0] << " [sender] [recipient] [/path/to/spamlist] [/path/to/logfile] <debugfile>\n";
         cout << "Report bugs to evilghost@stickit.nu\n";
         exit(1);
      }else {
         //Debugging output.
         if(argv[5] != NULL){
           ofstream debugfile;
           debugfile.open(argv[5], ios::app);
           if(debugfile.fail()){
             debugfile.open(argv[5], ios::out);
               if(debugfile.fail())
                  cerr << "Cannot find nor create " << argv[5] << "\n\a";
           }
           ddate = datet();
           debugfile << ddate + " " + "Sender: " + argv[1] + " Recipient: " + argv[2];
           debugfile << endl;
           debugfile.close();
         }

         char* sender = argv[1];
         char* recipient = argv[2];
         char* global = argv[3];
         char* logfile = argv[4];
         check(sender, recipient, global, logfile);
      }
   }

   void print_log(int a, char* sender, char* recipient, char* logfile){
      ofstream log;
      log.open(logfile, ios::app);
      if(log.fail()){
         log.open(logfile, ios::out);
         if(log.fail())
            cerr << "Cannot find nor create " << logfile << "\n\a";
      }
      if(a == 1){
        ddate = datet();
        log << ddate + "\tDenied " << sender << " to " << recipient;
      }
      if(a == 2)
         log << "Cannot access global list!";

      log << endl;
      log.close();
   }


   void check(char* sender, char* recipient, char* global, char* logfile){
      string spamaddr;
      int maxlen = 0;
      int x=0;

      //Lowercase sender
      x=0;
      while(x < strlen(sender)){
         sender[x] = tolower(sender[x]);
         x++;
      }

      ifstream glist(global);
      if(glist.fail()){
         print_log(2, sender, recipient, logfile);
         exit(1);
      }

      while(glist >> spamaddr){
        //Lowercase SpamAddr
        x=0;
        while(x < strlen(spamaddr.c_str())){
          spamaddr[x] = tolower(spamaddr[x]);
           x++;
        }

        if(spamaddr[0] != '#' && strlen(spamaddr.c_str()) > 2){
          if(spamaddr[0] == '@'){
            if(spamaddr[0] == '@' && spamaddr[1] == '*' && spamaddr[2] == '.') //Adjust the wildcard for subdomain matching, added in 4.02
               spamaddr.erase(0,2);
            if(strstr(sender,spamaddr.c_str())){
               print_log(1, sender, recipient, logfile); // log spam attempt
               exit(0);
            }
          }else{
             maxlen = strlen(sender);
             if((strlen(spamaddr.c_str())) > (strlen(sender)))
               maxlen = strlen(spamaddr.c_str());

             if(!strncasecmp(sender,spamaddr.c_str(),maxlen)){
               print_log(1, sender, recipient, logfile); // log spam attempt
               exit(0);
             }
            }
          }
      }
      glist.close();
      exit(1);
   }

   char* datet(){
      char* dt;
      time_t timer;
      struct tm *tblock;
      timer = time(NULL);
      tblock = localtime(&timer);
      dt = asctime(tblock);
      return strtok(dt,"\n");   //Added in 4.01, return the string minus the newline character.
   }
Code:
#Sample Deny Spamlist.txt
#Comments are prefixed with the '#' character.

#This is an example of a domain filter
#Deny all messages from this domain
@foo.fr
@foo.br

#This is an example of a account filter
john@foo.com
sexyjen1287@foo.com

#This is an example of a subdomain filter
#Deny domains like mail.foo.com, groups.foo.com, etc.
@*.foo.com
@*.foo2.com
evilghost is offline   Reply With Quote