1 Index: spamass-milter/spamass-milter.cpp
2 ===================================================================
3 --- spamass-milter.orig/spamass-milter.cpp 2012-06-21 13:03:25.000000000 -0700
4 +++ spamass-milter/spamass-milter.cpp 2012-06-21 13:03:42.000000000 -0700
6 #include "subst_poll.h"
17 + struct sockaddr_in localhost;
20 debug(D_FUNC, "mlfi_connect: enter");
24 /* not a socket; probably a local user calling sendmail directly */
25 /* set to 127.0.0.1 */
26 - sctx->connect_ip.s_addr = htonl(INADDR_LOOPBACK);
27 + strcpy(sctx->connect_ip, "127.0.0.1");
28 + localhost.sin_family = AF_INET;
29 + localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
30 + hostaddr = (struct sockaddr*) &localhost;
33 - sctx->connect_ip = ((struct sockaddr_in *) hostaddr)->sin_addr;
34 + getnameinfo(hostaddr, sizeof(struct sockaddr_in6),
35 + sctx->connect_ip, 63, NULL, 0, NI_NUMERICHOST);
36 + debug(D_FUNC, "Remote address: %s", sctx->connect_ip);
38 sctx->assassin = NULL;
42 /* debug(D_ALWAYS, "ZZZ set private context to %p", sctx); */
44 - if (ip_in_networklist(sctx->connect_ip, &ignorenets))
45 + if (ip_in_networklist(hostaddr, &ignorenets))
47 debug(D_NET, "%s is in our ignore list - accepting message",
48 - inet_ntoa(sctx->connect_ip));
50 debug(D_FUNC, "mlfi_connect: exit ignore");
54 return SMFIS_TEMPFAIL;
57 - assassin->set_connectip(string(inet_ntoa(sctx->connect_ip)));
58 + assassin->set_connectip(string(sctx->connect_ip));
60 // Store a pointer to the assassin object in our context struct
61 sctx->assassin = assassin;
62 @@ -2033,69 +2041,119 @@
64 char *tnet = strsep(&token, "/");
66 - struct in_addr net, mask;
68 + struct in6_addr net6;
70 if (list->num_nets % 10 == 0)
71 - list->nets = (struct net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
72 + list->nets = (union net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
74 - if (!inet_aton(tnet, &net))
75 + if (inet_pton(AF_INET, tnet, &net))
77 - fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
80 + struct in_addr mask;
84 + if (strchr(tmask, '.') == NULL)
89 + ret = sscanf(tmask, "%u", &bits);
90 + if (ret != 1 || bits > 32)
92 + fprintf(stderr,"%s: bad CIDR value", tmask);
95 + mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
96 + } else if (!inet_pton(AF_INET6, tmask, &mask))
98 + fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
102 + mask.s_addr = 0xffffffff;
106 + char *snet = strdup(inet_ntoa(net));
107 + debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
111 + net.s_addr = net.s_addr & mask.s_addr;
112 + list->nets[list->num_nets].net4.af = AF_INET;
113 + list->nets[list->num_nets].net4.network = net;
114 + list->nets[list->num_nets].net4.netmask = mask;
116 + } else if (inet_pton(AF_INET6, tnet, &net6))
118 - if (strchr(tmask, '.') == NULL)
126 - ret = sscanf(tmask, "%u", &bits);
127 - if (ret != 1 || bits > 32)
128 + if (sscanf(tmask, "%d", &mask) != 1 || mask > 128)
130 fprintf(stderr,"%s: bad CIDR value", tmask);
133 - mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
134 - } else if (!inet_aton(tmask, &mask))
136 - fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
142 + list->nets[list->num_nets].net6.af = AF_INET6;
143 + list->nets[list->num_nets].net6.network = net6;
144 + list->nets[list->num_nets].net6.netmask = mask;
147 - mask.s_addr = 0xffffffff;
150 - char *snet = strdup(inet_ntoa(net));
151 - debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
153 + fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
157 - net.s_addr = net.s_addr & mask.s_addr;
158 - list->nets[list->num_nets].network = net;
159 - list->nets[list->num_nets].netmask = mask;
165 -int ip_in_networklist(struct in_addr ip, struct networklist *list)
166 +int ip_in_networklist(struct sockaddr *addr, struct networklist *list)
170 if (list->num_nets == 0)
173 - debug(D_NET, "Checking %s against:", inet_ntoa(ip));
175 + //debug(D_NET, "Checking %s against:", inet_ntoa(ip));
176 for (i = 0; i < list->num_nets; i++)
178 - debug(D_NET, "%s", inet_ntoa(list->nets[i].network));
179 - debug(D_NET, "/%s", inet_ntoa(list->nets[i].netmask));
180 - if ((ip.s_addr & list->nets[i].netmask.s_addr) == list->nets[i].network.s_addr)
182 - debug(D_NET, "Hit!");
184 + if (list->nets[i].net.af == AF_INET && addr->sa_family == AF_INET)
186 + struct in_addr ip = ((struct sockaddr_in *)addr)->sin_addr;
188 + debug(D_NET, "%s", inet_ntoa(list->nets[i].net4.network));
189 + debug(D_NET, "/%s", inet_ntoa(list->nets[i].net4.netmask));
190 + if ((ip.s_addr & list->nets[i].net4.netmask.s_addr) == list->nets[i].net4.network.s_addr)
192 + debug(D_NET, "Hit!");
195 + } else if (list->nets[i].net.af == AF_INET6 && addr->sa_family == AF_INET6)
197 + u_int8_t *ip = ((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr;
200 + mask = list->nets[i].net6.netmask;
201 + for (j = 0; j < 16 && mask > 0; j++, mask -= 8)
203 + unsigned char bytemask;
205 + bytemask = (mask < 8) ? ~((1L << (8 - mask)) - 1) : 0xff;
207 + if ((ip[j] & bytemask) != (list->nets[i].net6.network.s6_addr[j] & bytemask))
213 + debug(D_NET, "Hit!");
219 Index: spamass-milter/spamass-milter.h
220 ===================================================================
221 --- spamass-milter.orig/spamass-milter.h 2012-06-21 13:03:25.000000000 -0700
222 +++ spamass-milter/spamass-milter.h 2012-06-21 13:03:42.000000000 -0700
224 extern struct smfiDesc smfilter;
226 /* struct describing a single network */
230 - struct in_addr network;
231 - struct in_addr netmask;
239 + struct in_addr network;
240 + struct in_addr netmask;
245 + struct in6_addr network;
246 + int netmask; /* Just the number of bits for IPv6 */
250 /* an array of networks */
259 /* Private data structure to carry per-client data between calls */
262 - struct in_addr connect_ip; // remote IP address
263 + char connect_ip[64]; // remote IP address
265 SpamAssassin *assassin; // pointer to the SA object if we're processing a message
268 int cmp_nocase_partial(const string&, const string&);
269 void closeall(int fd);
270 void parse_networklist(char *string, struct networklist *list);
271 -int ip_in_networklist(struct in_addr ip, struct networklist *list);
272 +int ip_in_networklist(struct sockaddr *addr, struct networklist *list);
273 void parse_debuglevel(char* string);
274 char *strlwr(char *str);
275 void warnmacro(char *macro, char *scope);