packages: spamass-milter/spamass-milter-ipv6.patch (NEW) - IPv6 support, ta...
hawk
hawk at pld-linux.org
Thu Jul 14 21:16:30 CEST 2011
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);
================================================================
More information about the pld-cvs-commit
mailing list