]> git.pld-linux.org Git - packages/spamass-milter.git/blob - spamass-milter-ipv6.patch
- release 2
[packages/spamass-milter.git] / spamass-milter-ipv6.patch
1 diff -up spamass-milter-0.3.1/spamass-milter.cpp.ipv6 spamass-milter-0.3.1/spamass-milter.cpp
2 --- spamass-milter-0.3.1/spamass-milter.cpp.ipv6        2010-09-23 16:26:36.227224902 +0100
3 +++ spamass-milter-0.3.1/spamass-milter.cpp     2010-09-23 17:25:22.307099331 +0100
4 @@ -88,6 +88,7 @@
5  #include "subst_poll.h"
6  #endif
7  #include <errno.h>
8 +#include <netdb.h>
9  
10  #include <grp.h>
11  
12 @@ -718,12 +719,18 @@ mlfi_connect(SMFICTX * ctx, char *hostna
13         sctx = (struct context *)malloc(sizeof(*sctx));
14         if (!hostaddr)
15         {
16 +               static struct sockaddr_in localhost;
17 +               
18                 /* not a socket; probably a local user calling sendmail directly */
19                 /* set to 127.0.0.1 */
20 -               sctx->connect_ip.s_addr = htonl(INADDR_LOOPBACK);
21 +               strcpy(sctx->connect_ip, "127.0.0.1");
22 +               localhost.sin_family = AF_INET;
23 +               localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
24 +               hostaddr = (struct sockaddr*) &localhost;
25         } else
26         {
27 -               sctx->connect_ip = ((struct sockaddr_in *) hostaddr)->sin_addr;
28 +               getnameinfo(hostaddr, sizeof(struct sockaddr_in6),
29 +                           sctx->connect_ip, 63, NULL, 0, NI_NUMERICHOST);
30         }
31         sctx->assassin = NULL;
32         sctx->helo = NULL;
33 @@ -758,12 +765,12 @@ mlfi_connect(SMFICTX * ctx, char *hostna
34                 debug(D_ALWAYS, "smfi_setpriv failed!");
35                 return SMFIS_TEMPFAIL;
36         }
37 -       /* debug(D_ALWAYS, "ZZZ set private context to %p", sctx); */
38  
39 -       if (ip_in_networklist(sctx->connect_ip, &ignorenets))
40 +       debug(D_NET, "Checking %s against:", sctx->connect_ip);
41 +       if (ip_in_networklist(hostaddr, &ignorenets))
42         {
43                 debug(D_NET, "%s is in our ignore list - accepting message",
44 -                   inet_ntoa(sctx->connect_ip));
45 +                     sctx->connect_ip);
46                 debug(D_FUNC, "mlfi_connect: exit ignore");
47                 return SMFIS_ACCEPT;
48         }
49 @@ -807,7 +814,6 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
50      debug(D_ALWAYS, "smfi_getpriv failed!");
51      return SMFIS_TEMPFAIL;
52    }
53 -  /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
54  
55    if (ignore_authenticated_senders)
56    {
57 @@ -835,7 +841,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
58        return SMFIS_TEMPFAIL;
59      };
60    
61 -  assassin->set_connectip(string(inet_ntoa(sctx->connect_ip)));
62 +  assassin->set_connectip(string(sctx->connect_ip));
63  
64    // Store a pointer to the assassin object in our context struct
65    sctx->assassin = assassin;
66 @@ -2128,69 +2134,135 @@ void parse_networklist(char *string, str
67         {
68                 char *tnet = strsep(&token, "/");
69                 char *tmask = token;
70 -               struct in_addr net, mask;
71 +               struct in_addr net;
72 +               struct in6_addr net6;
73  
74                 if (list->num_nets % 10 == 0)
75 -                       list->nets = (struct net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
76 +                       list->nets = (union net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
77  
78 -               if (!inet_aton(tnet, &net))
79 +               if (inet_pton(AF_INET, tnet, &net))
80                 {
81 -                       fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
82 -                       exit(1);
83 -               }
84 +                       struct in_addr mask;
85 +                       
86 +                       if (tmask)
87 +                       {
88 +                               if (strchr(tmask, '.') == NULL)
89 +                               {
90 +                                       /* CIDR */
91 +                                       unsigned int bits;
92 +                                       int ret;
93 +                                       ret = sscanf(tmask, "%u", &bits);
94 +                                       if (ret != 1 || bits > 32)
95 +                                       {
96 +                                               fprintf(stderr,"%s: bad CIDR value", tmask);
97 +                                               exit(1);
98 +                                       }
99 +                                       mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
100 +                               } else if (!inet_pton(AF_INET6, tmask, &mask))
101 +                               {
102 +                                       fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
103 +                                       exit(1);
104 +                               }
105 +                       } else
106 +                               mask.s_addr = 0xffffffff;
107  
108 -               if (tmask)
109 -               {
110 -                       if (strchr(tmask, '.') == NULL)
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;
115 +               } else if (inet_pton(AF_INET6, tnet, &net6))
116 +               {
117 +                       int mask;
118 +                       
119 +                       if (tmask)
120                         {
121 -                               /* CIDR */
122 -                               unsigned int bits;
123 -                               int ret;
124 -                               ret = sscanf(tmask, "%u", &bits);
125 -                               if (ret != 1 || bits > 32)
126 +                               if (sscanf(tmask, "%d", &mask) != 1 || mask > 128)
127                                 {
128                                         fprintf(stderr,"%s: bad CIDR value", tmask);
129                                         exit(1);
130                                 }
131 -                               mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
132 -                       } else if (!inet_aton(tmask, &mask))
133 -                       {
134 -                               fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
135 -                               exit(1);
136 -                       }
137 +                       } else
138 +                               mask = 128;
139 +                       
140 +                       list->nets[list->num_nets].net6.af = AF_INET6;
141 +                       list->nets[list->num_nets].net6.network = net6;
142 +                       list->nets[list->num_nets].net6.netmask = mask;
143                 } else
144 -                       mask.s_addr = 0xffffffff;
145 +               {
146 +                       fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
147 +                       exit(1);
148 +               }
149  
150                 {
151 -                       char *snet = strdup(inet_ntoa(net));
152 -                       debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
153 -                       free(snet);
154 +                       int af = list->nets[list->num_nets].net.af;
155 +                       char addrbuf[INET6_ADDRSTRLEN];
156 +                       char maskbuf[4];
157 +                       char *maskstr;
158 +
159 +                       if (af == AF_INET6) {
160 +                               inet_ntop(af, &list->nets[list->num_nets].net6.network,
161 +                                       addrbuf, INET6_ADDRSTRLEN);
162 +                               sprintf(maskbuf, "%d", list->nets[list->num_nets].net6.netmask);
163 +                               maskstr = maskbuf;
164 +                               list->nets[list->num_nets].net6.addrstr = strdup(addrbuf);
165 +                               list->nets[list->num_nets].net6.maskstr = strdup(maskbuf);
166 +                       } else
167 +                       {
168 +                               inet_ntop(af, &list->nets[list->num_nets].net4.network,
169 +                                       addrbuf, INET6_ADDRSTRLEN);
170 +                               maskstr = inet_ntoa(list->nets[list->num_nets].net4.netmask);
171 +                               list->nets[list->num_nets].net4.addrstr = strdup(addrbuf);
172 +                               list->nets[list->num_nets].net4.maskstr = strdup(maskstr);
173 +                       }
174 +                       debug(D_MISC, "Added %s/%s to network list", addrbuf, maskstr);
175                 }
176  
177 -               net.s_addr = net.s_addr & mask.s_addr;
178 -               list->nets[list->num_nets].network = net;
179 -               list->nets[list->num_nets].netmask = mask;
180                 list->num_nets++;
181         }
182         free(string);
183  }
184  
185 -int ip_in_networklist(struct in_addr ip, struct networklist *list)
186 +int ip_in_networklist(struct sockaddr *addr, struct networklist *list)
187  {
188         int i;
189  
190         if (list->num_nets == 0)
191                 return 0;
192 -               
193 -       debug(D_NET, "Checking %s against:", inet_ntoa(ip));
194 +       
195         for (i = 0; i < list->num_nets; i++)
196         {
197 -               debug(D_NET, "%s", inet_ntoa(list->nets[i].network));
198 -               debug(D_NET, "/%s", inet_ntoa(list->nets[i].netmask));
199 -               if ((ip.s_addr & list->nets[i].netmask.s_addr) == list->nets[i].network.s_addr)
200 -        {
201 -               debug(D_NET, "Hit!");
202 -                       return 1;
203 +               if (list->nets[i].net.af == AF_INET && addr->sa_family == AF_INET)
204 +               {
205 +                       struct in_addr ip = ((struct sockaddr_in *)addr)->sin_addr;
206 +                       
207 +                       debug(D_NET, "%s/%s", list->nets[i].net4.addrstr, list->nets[i].net4.maskstr);
208 +                       if ((ip.s_addr & list->nets[i].net4.netmask.s_addr) == list->nets[i].net4.network.s_addr)
209 +                       {
210 +                               debug(D_NET, "Hit!");
211 +                               return 1;
212 +                       }
213 +               } else if (list->nets[i].net.af == AF_INET6 && addr->sa_family == AF_INET6)
214 +               {
215 +                       u_int8_t *ip = ((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr;
216 +                       int mask, j;
217 +
218 +                       debug(D_NET, "%s/%s", list->nets[i].net6.addrstr, list->nets[i].net6.maskstr);
219 +                       mask = list->nets[i].net6.netmask;
220 +                       for (j = 0; j < 16 && mask > 0; j++, mask -= 8)
221 +                       {
222 +                               unsigned char bytemask;
223 +                               
224 +                               bytemask = (mask < 8) ? ~((1L << (8 - mask)) - 1) : 0xff;
225 +                               
226 +                               if ((ip[j] & bytemask) != (list->nets[i].net6.network.s6_addr[j] & bytemask))
227 +                                       break;
228 +                       }
229 +                       
230 +                       if (mask <= 0)
231 +                       {
232 +                               debug(D_NET, "Hit!");
233 +                               return 1;
234 +                       }
235                 }
236         }
237  
238 diff -up spamass-milter-0.3.1/spamass-milter.h.ipv6 spamass-milter-0.3.1/spamass-milter.h
239 --- spamass-milter-0.3.1/spamass-milter.h.ipv6  2010-09-23 16:26:36.224160445 +0100
240 +++ spamass-milter-0.3.1/spamass-milter.h       2010-09-23 17:00:16.487410690 +0100
241 @@ -56,16 +56,34 @@ sfsistat mlfi_abort(SMFICTX*);
242  extern struct smfiDesc smfilter;
243  
244  /* struct describing a single network */
245 -struct net
246 +union net
247  {
248 -       struct in_addr network;
249 -       struct in_addr netmask;
250 +       struct
251 +       {
252 +               uint8_t af;
253 +       } net;
254 +       struct
255 +       {
256 +               uint8_t af;
257 +               struct in_addr network;
258 +               struct in_addr netmask;
259 +               char *addrstr;
260 +               char *maskstr;
261 +       } net4;
262 +       struct
263 +       {
264 +               uint8_t af;
265 +               struct in6_addr network;
266 +               int netmask; /* Just the number of bits for IPv6 */
267 +               char *addrstr;
268 +               char *maskstr;
269 +       } net6;
270  };
271  
272  /* an array of networks */
273  struct networklist
274  {
275 -       struct net *nets;
276 +       union net *nets;
277         int num_nets;
278  };
279  
280 @@ -162,7 +180,7 @@ public:  
281  /* Private data structure to carry per-client data between calls */
282  struct context
283  {
284 -       struct in_addr connect_ip;      // remote IP address
285 +       char connect_ip[64];    // remote IP address
286         char *helo;
287         char *our_fqdn;
288         char *sender_address;
289 @@ -184,7 +202,7 @@ string::size_type find_nocase(const stri
290  int cmp_nocase_partial(const string&, const string&);
291  void closeall(int fd);
292  void parse_networklist(char *string, struct networklist *list);
293 -int ip_in_networklist(struct in_addr ip, struct networklist *list);
294 +int ip_in_networklist(struct sockaddr *addr, struct networklist *list);
295  void parse_debuglevel(char* string);
296  char *strlwr(char *str);
297  void warnmacro(const char *macro, const char *scope);
This page took 0.051829 seconds and 3 git commands to generate.