"Fossies" - the Fresh Open Source Software Archive

Member "spammilt-0.5.0-rc7/xfunctions.c" (22 Jun 2005, 11762 Bytes) of package /linux/privat/old/spammilt-0.5.0-rc7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "xfunctions.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 #-------------------------------------------------------------------------------
    3 #
    4 # $Id: xfunctions.c,v 1.17 2005/06/22 18:12:20 mardan Exp $ 
    5 #
    6 # $Log: xfunctions.c,v $
    7 # Revision 1.17  2005/06/22 18:12:20  mardan
    8 # code cleanups
    9 # update documentation
   10 # ----------------------------------------------------------------------
   11 #
   12 # Revision 1.16  2004/08/27 20:03:37  mardan
   13 # Added filtering of spam based on X-Spam-Score from the SpamAssassin package
   14 #
   15 # Revision 1.15  2003/12/30 22:57:55  mardan
   16 # Changed resolve function in xfunctions.c
   17 # Updated documentation
   18 # Bumbed to version 0.5.0-rc4
   19 #
   20 # Revision 1.14  2003/12/25 22:58:14  mardan
   21 # Fixed free bugs in temporary list in mlfi structure
   22 # Some code improvements..
   23 # Bumped to version 0.5.0-rc2
   24 #
   25 # Revision 1.13  2003/12/04 11:06:27  mardan
   26 # Typo fix
   27 #
   28 # Revision 1.12  2003/12/04 10:47:35  mardan
   29 # Added /etc... and /var... directories to Makefile
   30 # Hopefully fixed crash bug in dnsbl_check
   31 #
   32 # Revision 1.11  2003/11/29 18:06:09  mardan
   33 # Updated documentation
   34 # Added discard option
   35 # Re-introduced the reserved (LAN) ip range scan, to skip dnsbl queries
   36 #
   37 # Revision 1.10  2003/11/28 21:40:51  mardan
   38 # Added ACCEPT entry in statistics
   39 # Changed scan for IP in header
   40 # Changed err_log to syslog
   41 # Lots of cleanups
   42 #
   43 # Revision 1.9  2003/11/17 23:06:57  mardan
   44 # Added multiple dnsbl hosts, needs testing and lots of cleanups
   45 #
   46 # Revision 1.8  2003/11/16 00:26:22  mardan
   47 # Added new files (dynarray.c and .h) for allocating dynamic arrays for
   48 # mlfi_envrcpts and mlfi_bl_spam_match (blacklist match)
   49 # Changed standard-alloc routines to the better controlled alloc routines
   50 # Started improving better logging of errors in case of program errors
   51 #
   52 # Revision 1.7  2003/11/13 20:07:12  mardan
   53 # cleanups
   54 #
   55 # Revision 1.6  2003/11/12 22:13:11  mardan
   56 # Added fucntions to read files, allocate and free memory
   57 # Added array counters for list-arrays to properly read/free to the end.
   58 #
   59 # Revision 1.5  2003/10/28 14:18:38  mardan
   60 # Some cleanups, Fixed crashbug due to a not initialized subject when changing
   61 # subject when spam was received
   62 #
   63 # Revision 1.4  2003/04/27 14:21:39  mardan
   64 # Added the possibility to compile with Annoyance-filter, which is a nice
   65 # Bayesian based scan-filter. (see http://www.fourmilab.ch/annoyance-filter/)
   66 # (make BAYESIAN_ANNOYANCE=1)
   67 #
   68 # Revision 1.3  2002/09/15 00:07:34  mardan
   69 # Cleaned up some of the code.
   70 # Made some small changes in check_dnsbl to be thread safe.
   71 # Added the option to define DNSBL queryhost using a commandline parameter.
   72 #
   73 # Revision 1.2  2002/09/01 17:42:50  mardan
   74 # Fixed uninitilized string in dnsbl check.
   75 #
   76 # Revision 1.1  2002/09/01 16:08:25  mardan
   77 # Complete rewrite of spammilt due to stability problem.
   78 # Reduced number of .c files to spammilt.c and xfunctions.c
   79 # Diff between last spammilt and this version will be enormous when viewing
   80 # with cvsweb.
   81 # Added daemon mode.
   82 #
   83 #
   84 #
   85 # Copyright (c) 2002 by D.Wijsman (mardan@tweegy.demon.nl). 
   86 # All rights reserved.
   87 #
   88 # This program is free software; you can redistribute it and/or modify it
   89 # under the terms of the GNU General Public License as published by the Free
   90 # Software Foundation; either version 2 of the License, or (at your option)
   91 # any later version.
   92 # 
   93 # This program is distributed in the hope that it will be useful, but WITHOUT
   94 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   95 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   96 # more details.
   97 #
   98 # You should have received a copy of the GNU General Public License
   99 # along with this program; see the file COPYING.  If not, write to
  100 # the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  101 #
  102 #
  103 #-------------------------------------------------------------------------------
  104 */
  105 
  106 #include "xfunctions.h"
  107 
  108 
  109 
  110 char *search_replace (char *buffer, char *search, char *replace) 
  111     {
  112     char *S[1024], *p;
  113     size_t search_len = strlen(search);
  114     size_t replace_len = strlen(replace);
  115     size_t buffer_len = strlen(buffer);
  116     int k = 0 ,n , diff = replace_len - search_len;
  117 //    int j;
  118     
  119     for (p = strstr(buffer,search); p != NULL; p = strstr(p,search))
  120     S[++k] = p++;   
  121     n = k;
  122     S[n+1] = buffer + buffer_len;
  123     for (k=0; k<n; k++) {
  124     int q = (diff >= 0) ? n-k : k+1;
  125     int dist = q*diff;
  126     if (diff != 0)
  127         memmove(S[q] + search_len + dist, S[q] + search_len,
  128             (S[q+1]-buffer) - (S[q]-buffer) - search_len);
  129     memcpy (S[q]+dist-diff, replace, replace_len);
  130     }
  131     buffer[buffer_len + n*diff] = '\0';
  132     return buffer;
  133     }
  134     
  135 
  136 int lookup_ip(char *host, char *host_ip)
  137     {
  138     struct addrinfo hints, *res;
  139     int errcode;
  140     char addrstr[100];
  141     void *ptr = NULL;
  142   
  143 #ifdef DEBUG
  144     syslog(LOG_DEBUG, "DEBUG host:%s", host);
  145 #endif
  146       
  147     memset (&hints, 0, sizeof (hints));
  148     hints.ai_family = PF_UNSPEC;
  149     hints.ai_socktype = SOCK_STREAM;
  150     hints.ai_flags |= AI_CANONNAME;
  151           
  152     errcode = getaddrinfo (host, NULL, &hints, &res);
  153     if (errcode != 0) {
  154 #ifdef DEBUG
  155     syslog(LOG_DEBUG, "DEBUG: lookup err: %s", gai_strerror(errcode));
  156 #endif
  157     return 0;
  158     }
  159               
  160     while (res)
  161     {
  162     inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);
  163                             
  164     switch (res->ai_family)
  165         {
  166         case AF_INET:
  167         ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
  168         break;
  169         case AF_INET6:
  170         ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
  171         break;
  172         }
  173     inet_ntop (res->ai_family, ptr, addrstr, 100);
  174 //  printf ("IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname);
  175     res = res->ai_next;
  176     }                                                           
  177     freeaddrinfo(res);
  178     memcpy(host_ip, addrstr, 15);
  179 #ifdef DEBUG
  180     syslog(LOG_DEBUG, "DEBUG: host_ip: %s", host_ip);
  181 #endif
  182     return 1;
  183     }
  184 
  185 
  186 int check_dnsbl(char *ip, char *query_host, char *host_ip)
  187     {
  188     int B_SIZE = 128;
  189     char buf_ip[20];
  190     char query_ip[20];
  191     char host[B_SIZE];
  192     char *buff[5];
  193     char *token;
  194     char code_host_ip[16];
  195     char *buftok;
  196     char *vartok;
  197     int count;
  198     
  199     strncpy(buf_ip, ip, 19);
  200     buftok = buf_ip;
  201     token = strtok_r(buftok, ".", &vartok);
  202     count = 0;
  203     while(token != NULL) 
  204     {
  205         buff[count] = token;
  206     buftok = 0;
  207     token = strtok_r(buftok, ".", &vartok);
  208     count++;
  209         }
  210     snprintf(query_ip, sizeof(query_ip), "%s.%s.%s.%s.", buff[3], buff[2], buff[1], buff[0]);
  211 #ifdef DEBUG    
  212     syslog(LOG_DEBUG, "DEBUG: Host found: %s ", query_ip);
  213 #endif
  214     strcpy(host, "\0");    
  215     strncat(host, query_ip, B_SIZE - strlen(host));
  216     strncat(host, query_host, B_SIZE - strlen(host));
  217 #ifdef DEBUG    
  218     syslog(LOG_DEBUG, "DEBUG: Querying for: %s strlen(query_ip):%d strlen(query_host):%d", host, strlen(query_ip), strlen(query_host));
  219 #endif    
  220     if (!lookup_ip(host, code_host_ip)) {
  221 #ifdef DEBUG    
  222     syslog(LOG_DEBUG, "DEBUG: IP not blacklisted: %s",ip);
  223 #endif  
  224     return 0;                       // not blacklisted
  225     }
  226     memcpy(host_ip, code_host_ip, 15);
  227 #ifdef DEBUG    
  228     syslog(LOG_DEBUG, "DEBUG: IP blacklisted !: %s, code_ip: %s",ip, host_ip);
  229 #endif    
  230     return 1;
  231     }
  232 
  233 
  234 void err_log(char *err_msg,char *arg)
  235     {
  236     openlog ("spammiltd", LOG_CONS|LOG_PID|LOG_NDELAY, LOG_MAIL);
  237     syslog (LOG_INFO, err_msg, arg);
  238     closelog ();
  239     }
  240 
  241 
  242 int match(char *string, char *pattern) 
  243     {
  244     int i;
  245     regex_t re;
  246     char buf[250];
  247     
  248     i = regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE);
  249     if (i != 0) {
  250     (void) regerror(i, &re, buf, sizeof(buf));
  251     return(0);                       
  252     }
  253     i = regexec(&re, string, (size_t) 0, NULL, 0);
  254     regfree(&re);
  255     if (i != 0) {
  256     (void) regerror(i, &re, buf, sizeof(buf));
  257     return(0);
  258     }
  259     return(1);
  260     }
  261 
  262 
  263 void *xcalloc(size_t nmemb, size_t size)
  264     {
  265     void *alloc_mem;
  266 
  267     if ((alloc_mem = (char *)calloc(nmemb, size)) == NULL) {
  268         syslog (LOG_CRIT, "ERROR: calloc of %d bytes failed!", nmemb*size);
  269     exit(-1);
  270     }
  271     return alloc_mem;
  272     }
  273 
  274 
  275 void *xrealloc(void *oldbuffer, size_t newsize)
  276     {
  277     void *newbuffer;
  278 
  279     if ((newbuffer = (char **)realloc(oldbuffer, newsize)) == NULL) {                                                              
  280         syslog (LOG_CRIT, "ERROR: realloc of %d bytes failed!", newsize);
  281     exit(-1);
  282     } 
  283     return newbuffer;                                                                                                 
  284     }
  285 
  286 
  287 char *xstrdup (const char *dup)
  288     {
  289     char *ret;
  290     if ((ret = strdup(dup)) == NULL) {
  291     syslog (LOG_CRIT, "ERROR: strdup for %s failed", dup);
  292     exit(-1);
  293     }   
  294     return ret;
  295     }
  296 
  297 
  298 char **FreeList(char **List, int *Size)
  299     {
  300     int a_size, i;
  301     a_size = *Size;
  302 
  303     for (i=0; i< a_size;i++) {
  304     free(List[i]);
  305     }
  306     free(List);
  307     
  308     *Size = 0;
  309     return List;
  310     }
  311 
  312 
  313 char **ReadList(char *FileName, int *Size)
  314     {
  315     FILE *FH;
  316     char *buffer;
  317     char *line;
  318     char **list;
  319     int a_size = 0;
  320     int BUFFER_SIZE = 128;
  321     
  322     list = xcalloc(1, sizeof(char *));
  323     
  324     // open file to read
  325     if (!(FH = fopen(FileName, "r"))) {
  326     syslog(LOG_WARNING, "WARNING: Warning: Unable to open file: %s", FileName);
  327     *Size = 0;
  328     return list;
  329     }
  330 
  331     // init memory for buffers
  332     buffer = xcalloc(1, sizeof(char *));
  333     line = xcalloc(1, BUFFER_SIZE * sizeof(char *));
  334     
  335     // read char by char the file
  336     while (fgets(buffer, 2, FH))
  337     {
  338     if (buffer[0] == '\0' || buffer[0] == '\n') {
  339         if (strlen(line) < 1) {
  340             continue;
  341             }
  342         // we ve a newline, alloc memory more memory
  343         list = xrealloc(list, (a_size+1) * sizeof(char *));
  344         list[a_size] = xcalloc(1, strlen(line) * sizeof(char *));
  345                 
  346         // put line in array
  347         strncpy(list[a_size], line, strlen(line));
  348 
  349         // clear buffer and raise array-size
  350         strcpy(line, "\0");
  351         a_size++;
  352         continue;
  353     } else {
  354         // concat buffer to line if not oversized
  355         strncat(line, buffer, strlen(line) - BUFFER_SIZE);
  356         }
  357     }
  358 
  359     // also add last line from file, even if there is no newline
  360     if (buffer[0] != '\0' && buffer[0] != '\n') {
  361     list = xrealloc(list, (a_size+1) * sizeof(char *));
  362     list[a_size] = xcalloc(1, strlen(line) * sizeof(char *));
  363     strncpy(list[a_size], line, strlen(line));
  364     a_size++;
  365     }
  366 
  367     // close FileHandle and free buffers
  368     fclose(FH);
  369     free(buffer);
  370     free(line);
  371     
  372     *Size = a_size;
  373     return list;
  374     }
  375 
  376 // functions to check if IP is member of a reserved IP range
  377 int inrange(L_IP test, L_IP min, L_IP max)
  378     {
  379     return test >= min && test <= max;
  380     }
  381   
  382 L_IP convert(const char *dotted)
  383     {
  384     unsigned int a, b, c, d;
  385     sscanf(dotted, "%u.%u.%u.%u", &a, &b, &c, &d);
  386     return a << 24 | b << 16 | c << 8 | d;
  387     }
  388     
  389 int check_iprange(char *header_ip)
  390     {
  391     char *min[] = {
  392         "10.0.0.0",       
  393         "127.0.0.0",     
  394         "172.16.0.0",
  395         "192.168.0.0",
  396         "224.0.0.0"
  397         };
  398     char *max[] = {
  399         "10.255.255.255",
  400         "127.255.255.255", 
  401         "172.32.255.255",
  402         "192.168.255.255",
  403         "239.255.255.255" 
  404         };
  405     L_IP ip = convert(header_ip);
  406     int i, n;
  407     n = sizeof min / sizeof *min;
  408     for(i = 0; i < n; i++) {
  409     if(inrange(ip, convert(min[i]), convert(max[i]))) {
  410         return 1;
  411         }
  412     }
  413     return 0;
  414     }
  415 
  416 float get_assassin_score(char *string) 
  417 {
  418     unsigned short int i;
  419     unsigned short int hdr_length;
  420     float score = 0;
  421     char *tmp_string;
  422     
  423     tmp_string = xcalloc(1, sizeof(char *));
  424     
  425     hdr_length = strlen(string);
  426     for (i=0; i<hdr_length;i++) {
  427         if (strncmp(&string[i], " ", 1) == 0) {
  428             tmp_string = xrealloc(tmp_string, i+1);
  429             strncpy(tmp_string, string, i);
  430             score = atof(tmp_string);
  431             break;
  432         }
  433     }
  434     free(tmp_string);
  435     return (score);
  436 }
  437 
  438 
  439 /* The End */
  440 
  441