Author: hawk                         Date: Thu Jul 14 19:16:30 2011 GMT
Module: packages                      Tag: HEAD
---- Log message:
- IPv6 support, taken from Fedora

---- Files affected:
packages/spamass-milter:
   spamass-milter-ipv6.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/spamass-milter/spamass-milter-ipv6.patch
diff -u /dev/null packages/spamass-milter/spamass-milter-ipv6.patch:1.1
--- /dev/null   Thu Jul 14 21:16:30 2011
+++ packages/spamass-milter/spamass-milter-ipv6.patch   Thu Jul 14 21:16:25 2011
@@ -0,0 +1,297 @@
+diff -up spamass-milter-0.3.1/spamass-milter.cpp.ipv6 
spamass-milter-0.3.1/spamass-milter.cpp
+--- spamass-milter-0.3.1/spamass-milter.cpp.ipv6       2010-09-23 
16:26:36.227224902 +0100
++++ spamass-milter-0.3.1/spamass-milter.cpp    2010-09-23 17:25:22.307099331 
+0100
+@@ -88,6 +88,7 @@
+ #include "subst_poll.h"
+ #endif
+ #include <errno.h>
++#include <netdb.h>
+ 
+ #include <grp.h>
+ 
+@@ -718,12 +719,18 @@ mlfi_connect(SMFICTX * ctx, char *hostna
+       sctx = (struct context *)malloc(sizeof(*sctx));
+       if (!hostaddr)
+       {
++              static struct sockaddr_in localhost;
++              
+               /* not a socket; probably a local user calling sendmail 
directly */
+               /* set to 127.0.0.1 */
+-              sctx->connect_ip.s_addr = htonl(INADDR_LOOPBACK);
++              strcpy(sctx->connect_ip, "127.0.0.1");
++              localhost.sin_family = AF_INET;
++              localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
++              hostaddr = (struct sockaddr*) &localhost;
+       } else
+       {
+-              sctx->connect_ip = ((struct sockaddr_in *) hostaddr)->sin_addr;
++              getnameinfo(hostaddr, sizeof(struct sockaddr_in6),
++                          sctx->connect_ip, 63, NULL, 0, NI_NUMERICHOST);
+       }
+       sctx->assassin = NULL;
+       sctx->helo = NULL;
+@@ -758,12 +765,12 @@ mlfi_connect(SMFICTX * ctx, char *hostna
+               debug(D_ALWAYS, "smfi_setpriv failed!");
+               return SMFIS_TEMPFAIL;
+       }
+-      /* debug(D_ALWAYS, "ZZZ set private context to %p", sctx); */
+ 
+-      if (ip_in_networklist(sctx->connect_ip, &ignorenets))
++      debug(D_NET, "Checking %s against:", sctx->connect_ip);
++      if (ip_in_networklist(hostaddr, &ignorenets))
+       {
+               debug(D_NET, "%s is in our ignore list - accepting message",
+-                  inet_ntoa(sctx->connect_ip));
++                    sctx->connect_ip);
+               debug(D_FUNC, "mlfi_connect: exit ignore");
+               return SMFIS_ACCEPT;
+       }
+@@ -807,7 +814,6 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+     debug(D_ALWAYS, "smfi_getpriv failed!");
+     return SMFIS_TEMPFAIL;
+   }
+-  /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
+ 
+   if (ignore_authenticated_senders)
+   {
+@@ -835,7 +841,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+       return SMFIS_TEMPFAIL;
+     };
+   
+-  assassin->set_connectip(string(inet_ntoa(sctx->connect_ip)));
++  assassin->set_connectip(string(sctx->connect_ip));
+ 
+   // Store a pointer to the assassin object in our context struct
+   sctx->assassin = assassin;
+@@ -2128,69 +2134,135 @@ void parse_networklist(char *string, str
+       {
+               char *tnet = strsep(&token, "/");
+               char *tmask = token;
+-              struct in_addr net, mask;
++              struct in_addr net;
++              struct in6_addr net6;
+ 
+               if (list->num_nets % 10 == 0)
+-                      list->nets = (struct net*)realloc(list->nets, 
sizeof(*list->nets) * (list->num_nets + 10));
++                      list->nets = (union net*)realloc(list->nets, 
sizeof(*list->nets) * (list->num_nets + 10));
+ 
+-              if (!inet_aton(tnet, &net))
++              if (inet_pton(AF_INET, tnet, &net))
+               {
+-                      fprintf(stderr, "Could not parse \"%s\" as a 
network\n", tnet);
+-                      exit(1);
+-              }
++                      struct in_addr mask;
++                      
++                      if (tmask)
++                      {
++                              if (strchr(tmask, '.') == NULL)
++                              {
++                                      /* CIDR */
++                                      unsigned int bits;
++                                      int ret;
++                                      ret = sscanf(tmask, "%u", &bits);
++                                      if (ret != 1 || bits > 32)
++                                      {
++                                              fprintf(stderr,"%s: bad CIDR 
value", tmask);
++                                              exit(1);
++                                      }
++                                      mask.s_addr = htonl(~((1L << (32 - 
bits)) - 1) & 0xffffffff);
++                              } else if (!inet_pton(AF_INET6, tmask, &mask))
++                              {
++                                      fprintf(stderr, "Could not parse \"%s\" 
as a netmask\n", tmask);
++                                      exit(1);
++                              }
++                      } else
++                              mask.s_addr = 0xffffffff;
+ 
+-              if (tmask)
+-              {
+-                      if (strchr(tmask, '.') == NULL)
++                      net.s_addr = net.s_addr & mask.s_addr;
++                      list->nets[list->num_nets].net4.af = AF_INET;
++                      list->nets[list->num_nets].net4.network = net;
++                      list->nets[list->num_nets].net4.netmask = mask;
++              } else if (inet_pton(AF_INET6, tnet, &net6))
++              {
++                      int mask;
++                      
++                      if (tmask)
+                       {
+-                              /* CIDR */
+-                              unsigned int bits;
+-                              int ret;
+-                              ret = sscanf(tmask, "%u", &bits);
+-                              if (ret != 1 || bits > 32)
++                              if (sscanf(tmask, "%d", &mask) != 1 || mask > 
128)
+                               {
+                                       fprintf(stderr,"%s: bad CIDR value", 
tmask);
+                                       exit(1);
+                               }
+-                              mask.s_addr = htonl(~((1L << (32 - bits)) - 1) 
& 0xffffffff);
+-                      } else if (!inet_aton(tmask, &mask))
+-                      {
+-                              fprintf(stderr, "Could not parse \"%s\" as a 
netmask\n", tmask);
+-                              exit(1);
+-                      }
++                      } else
++                              mask = 128;
++                      
++                      list->nets[list->num_nets].net6.af = AF_INET6;
++                      list->nets[list->num_nets].net6.network = net6;
++                      list->nets[list->num_nets].net6.netmask = mask;
+               } else
+-                      mask.s_addr = 0xffffffff;
++              {
++                      fprintf(stderr, "Could not parse \"%s\" as a 
network\n", tnet);
++                      exit(1);
++              }
+ 
+               {
+-                      char *snet = strdup(inet_ntoa(net));
+-                      debug(D_MISC, "Adding %s/%s to network list", snet, 
inet_ntoa(mask));
+-                      free(snet);
++                      int af = list->nets[list->num_nets].net.af;
++                      char addrbuf[INET6_ADDRSTRLEN];
++                      char maskbuf[4];
++                      char *maskstr;
++
++                      if (af == AF_INET6) {
++                              inet_ntop(af, 
&list->nets[list->num_nets].net6.network,
++                                      addrbuf, INET6_ADDRSTRLEN);
++                              sprintf(maskbuf, "%d", 
list->nets[list->num_nets].net6.netmask);
++                              maskstr = maskbuf;
++                              list->nets[list->num_nets].net6.addrstr = 
strdup(addrbuf);
++                              list->nets[list->num_nets].net6.maskstr = 
strdup(maskbuf);
++                      } else
++                      {
++                              inet_ntop(af, 
&list->nets[list->num_nets].net4.network,
++                                      addrbuf, INET6_ADDRSTRLEN);
++                              maskstr = 
inet_ntoa(list->nets[list->num_nets].net4.netmask);
++                              list->nets[list->num_nets].net4.addrstr = 
strdup(addrbuf);
++                              list->nets[list->num_nets].net4.maskstr = 
strdup(maskstr);
++                      }
++                      debug(D_MISC, "Added %s/%s to network list", addrbuf, 
maskstr);
+               }
+ 
+-              net.s_addr = net.s_addr & mask.s_addr;
+-              list->nets[list->num_nets].network = net;
+-              list->nets[list->num_nets].netmask = mask;
+               list->num_nets++;
+       }
+       free(string);
+ }
+ 
+-int ip_in_networklist(struct in_addr ip, struct networklist *list)
++int ip_in_networklist(struct sockaddr *addr, struct networklist *list)
+ {
+       int i;
+ 
+       if (list->num_nets == 0)
+               return 0;
+-              
+-      debug(D_NET, "Checking %s against:", inet_ntoa(ip));
++      
+       for (i = 0; i < list->num_nets; i++)
+       {
+-              debug(D_NET, "%s", inet_ntoa(list->nets[i].network));
+-              debug(D_NET, "/%s", inet_ntoa(list->nets[i].netmask));
+-              if ((ip.s_addr & list->nets[i].netmask.s_addr) == 
list->nets[i].network.s_addr)
+-        {
+-              debug(D_NET, "Hit!");
+-                      return 1;
++              if (list->nets[i].net.af == AF_INET && addr->sa_family == 
AF_INET)
++              {
++                      struct in_addr ip = ((struct sockaddr_in 
*)addr)->sin_addr;
++                      
++                      debug(D_NET, "%s/%s", list->nets[i].net4.addrstr, 
list->nets[i].net4.maskstr);
++                      if ((ip.s_addr & list->nets[i].net4.netmask.s_addr) == 
list->nets[i].net4.network.s_addr)
++                      {
++                              debug(D_NET, "Hit!");
++                              return 1;
++                      }
++              } else if (list->nets[i].net.af == AF_INET6 && addr->sa_family 
== AF_INET6)
++              {
++                      u_int8_t *ip = ((struct sockaddr_in6 
*)addr)->sin6_addr.s6_addr;
++                      int mask, j;
++
++                      debug(D_NET, "%s/%s", list->nets[i].net6.addrstr, 
list->nets[i].net6.maskstr);
++                      mask = list->nets[i].net6.netmask;
++                      for (j = 0; j < 16 && mask > 0; j++, mask -= 8)
++                      {
++                              unsigned char bytemask;
++                              
++                              bytemask = (mask < 8) ? ~((1L << (8 - mask)) - 
1) : 0xff;
++                              
++                              if ((ip[j] & bytemask) != 
(list->nets[i].net6.network.s6_addr[j] & bytemask))
++                                      break;
++                      }
++                      
++                      if (mask <= 0)
++                      {
++                              debug(D_NET, "Hit!");
++                              return 1;
++                      }
+               }
+       }
+ 
+diff -up spamass-milter-0.3.1/spamass-milter.h.ipv6 
spamass-milter-0.3.1/spamass-milter.h
+--- spamass-milter-0.3.1/spamass-milter.h.ipv6 2010-09-23 16:26:36.224160445 
+0100
++++ spamass-milter-0.3.1/spamass-milter.h      2010-09-23 17:00:16.487410690 
+0100
+@@ -56,16 +56,34 @@ sfsistat mlfi_abort(SMFICTX*);
+ extern struct smfiDesc smfilter;
+ 
+ /* struct describing a single network */
+-struct net
++union net
+ {
+-      struct in_addr network;
+-      struct in_addr netmask;
++      struct
++      {
++              uint8_t af;
++      } net;
++      struct
++      {
++              uint8_t af;
++              struct in_addr network;
++              struct in_addr netmask;
++              char *addrstr;
++              char *maskstr;
++      } net4;
++      struct
++      {
++              uint8_t af;
++              struct in6_addr network;
++              int netmask; /* Just the number of bits for IPv6 */
++              char *addrstr;
++              char *maskstr;
++      } net6;
+ };
+ 
+ /* an array of networks */
+ struct networklist
+ {
+-      struct net *nets;
++      union net *nets;
+       int num_nets;
+ };
+ 
+@@ -162,7 +180,7 @@ public:  
+ /* Private data structure to carry per-client data between calls */
+ struct context
+ {
+-      struct in_addr connect_ip;      // remote IP address
++      char connect_ip[64];    // remote IP address
+       char *helo;
+       char *our_fqdn;
+       char *sender_address;
+@@ -184,7 +202,7 @@ string::size_type find_nocase(const stri
+ int cmp_nocase_partial(const string&, const string&);
+ void closeall(int fd);
+ void parse_networklist(char *string, struct networklist *list);
+-int ip_in_networklist(struct in_addr ip, struct networklist *list);
++int ip_in_networklist(struct sockaddr *addr, struct networklist *list);
+ void parse_debuglevel(char* string);
+ char *strlwr(char *str);
+ void warnmacro(const char *macro, const char *scope);
================================================================
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to