View | Details | Raw Unified | Return to bug 155979 | Differences between
and this patch

Collapse All | Expand All

(-)Makefile (-1 / +6 lines)
Lines 25-31 Link Here
25
OPTIONS=	ADDAUTH_PATCH "Bypass checks for SMTP AUTH connections" off \
25
OPTIONS=	ADDAUTH_PATCH "Bypass checks for SMTP AUTH connections" off \
26
		REJECTTEXT_PATCH "Customize SMTP reject message" off \
26
		REJECTTEXT_PATCH "Customize SMTP reject message" off \
27
		LDAP "LDAP support" off \
27
		LDAP "LDAP support" off \
28
		SENDMAIL_PORT "Build against sendmail port" off
28
		SENDMAIL_PORT "Build against sendmail port" off \
29
                IPV6 "Apply IPv6 whitelist patch" off
29
30
30
.include <bsd.port.pre.mk>
31
.include <bsd.port.pre.mk>
31
32
Lines 42-47 Link Here
42
NEW_ARGS:=	${NEW_ARGS}R:
43
NEW_ARGS:=	${NEW_ARGS}R:
43
.endif
44
.endif
44
45
46
.if defined(WITH_IPV6)
47
EXTRA_PATCHES+= ${FILESDIR}/extra-patch-ipv6
48
.endif
49
45
# extra-patch-options is modified in pre-patch
50
# extra-patch-options is modified in pre-patch
46
.if ${ORIG_ARGS} != ${NEW_ARGS}
51
.if ${ORIG_ARGS} != ${NEW_ARGS}
47
EXTRA_PATCHES+=	${WRKDIR}/extra-patch-options
52
EXTRA_PATCHES+=	${WRKDIR}/extra-patch-options
(-)files/extra-patch-ipv6 (+270 lines)
Added Link Here
1
diff -ur orig/spamass-milter.cpp spamass-milter.cpp
2
--- orig/spamass-milter.cpp	2010-01-31 11:35:47.000000000 +0000
3
+++ spamass-milter.cpp	2008-01-09 01:20:38.000000000 +0000
4
@@ -88,6 +88,7 @@
5
 #include "subst_poll.h"
6
 #endif
7
 #include <errno.h>
8
+#include <netdb.h>
9
 
10
 // C++ includes
11
 #include <cstdio>
12
@@ -721,12 +722,19 @@
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
+		debug(D_FUNC, "Remote address: %s", sctx->connect_ip);
31
 	}
32
 	sctx->assassin = NULL;
33
 	sctx->helo = NULL;
34
@@ -740,10 +748,12 @@
35
 	}
36
 	/* debug(D_ALWAYS, "ZZZ set private context to %p", sctx); */
37
 
38
-	if (ip_in_networklist(sctx->connect_ip, &ignorenets))
39
+	//debug(D_FUNC, "sctx->connect_ip: `%d'", sctx->connect_ip.sin_family);
40
+
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
@@ -815,7 +825,7 @@
50
       return SMFIS_TEMPFAIL;
51
     };
52
   
53
-  assassin->set_connectip(string(inet_ntoa(sctx->connect_ip)));
54
+  assassin->set_connectip(string(sctx->connect_ip));
55
 
56
   // Store a pointer to the assassin object in our context struct
57
   sctx->assassin = assassin;
58
@@ -2089,69 +2099,119 @@
59
 	{
60
 		char *tnet = strsep(&token, "/");
61
 		char *tmask = token;
62
-		struct in_addr net, mask;
63
+		struct in_addr net;
64
+		struct in6_addr net6;
65
 
66
 		if (list->num_nets % 10 == 0)
67
-			list->nets = (struct net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
68
+			list->nets = (union net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
69
 
70
-		if (!inet_aton(tnet, &net))
71
+		if (inet_pton(AF_INET, tnet, &net))
72
 		{
73
-			fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
74
-			exit(1);
75
-		}
76
+			struct in_addr mask;
77
+			
78
+			if (tmask)
79
+			{
80
+				if (strchr(tmask, '.') == NULL)
81
+				{
82
+					/* CIDR */
83
+					unsigned int bits;
84
+					int ret;
85
+					ret = sscanf(tmask, "%u", &bits);
86
+					if (ret != 1 || bits > 32)
87
+					{
88
+						fprintf(stderr,"%s: bad CIDR value", tmask);
89
+						exit(1);
90
+					}
91
+					mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
92
+				} else if (!inet_pton(AF_INET6, tmask, &mask))
93
+				{
94
+					fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
95
+					exit(1);
96
+				}
97
+			} else
98
+				mask.s_addr = 0xffffffff;
99
+
100
+			{
101
+				char *snet = strdup(inet_ntoa(net));
102
+				debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
103
+				free(snet);
104
+			}
105
 
106
-		if (tmask)
107
+			net.s_addr = net.s_addr & mask.s_addr;
108
+			list->nets[list->num_nets].net4.af = AF_INET;
109
+			list->nets[list->num_nets].net4.network = net;
110
+			list->nets[list->num_nets].net4.netmask = mask;
111
+			list->num_nets++;
112
+		} else if (inet_pton(AF_INET6, tnet, &net6))
113
 		{
114
-			if (strchr(tmask, '.') == NULL)
115
+			int mask;
116
+			
117
+			if (tmask)
118
 			{
119
-				/* CIDR */
120
-				unsigned int bits;
121
-				int ret;
122
-				ret = sscanf(tmask, "%u", &bits);
123
-				if (ret != 1 || bits > 32)
124
+				if (sscanf(tmask, "%d", &mask) != 1 || mask > 128)
125
 				{
126
 					fprintf(stderr,"%s: bad CIDR value", tmask);
127
 					exit(1);
128
 				}
129
-				mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
130
-			} else if (!inet_aton(tmask, &mask))
131
-			{
132
-				fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
133
-				exit(1);
134
-			}
135
+			} else
136
+				mask = 128;
137
+			
138
+			list->nets[list->num_nets].net6.af = AF_INET6;
139
+			list->nets[list->num_nets].net6.network = net6;
140
+			list->nets[list->num_nets].net6.netmask = mask;
141
+			list->num_nets++;
142
 		} else
143
-			mask.s_addr = 0xffffffff;
144
-
145
 		{
146
-			char *snet = strdup(inet_ntoa(net));
147
-			debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
148
-			free(snet);
149
+			fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
150
+			exit(1);
151
 		}
152
 
153
-		net.s_addr = net.s_addr & mask.s_addr;
154
-		list->nets[list->num_nets].network = net;
155
-		list->nets[list->num_nets].netmask = mask;
156
-		list->num_nets++;
157
 	}
158
 	free(string);
159
 }
160
 
161
-int ip_in_networklist(struct in_addr ip, struct networklist *list)
162
+int ip_in_networklist(struct sockaddr *addr, struct networklist *list)
163
 {
164
 	int i;
165
 
166
 	if (list->num_nets == 0)
167
 		return 0;
168
-		
169
-	debug(D_NET, "Checking %s against:", inet_ntoa(ip));
170
+	
171
+	//debug(D_NET, "Checking %s against:", inet_ntoa(ip));
172
 	for (i = 0; i < list->num_nets; i++)
173
 	{
174
-		debug(D_NET, "%s", inet_ntoa(list->nets[i].network));
175
-		debug(D_NET, "/%s", inet_ntoa(list->nets[i].netmask));
176
-		if ((ip.s_addr & list->nets[i].netmask.s_addr) == list->nets[i].network.s_addr)
177
-        {
178
-        	debug(D_NET, "Hit!");
179
-			return 1;
180
+		if (list->nets[i].net.af == AF_INET && addr->sa_family == AF_INET)
181
+		{
182
+			struct in_addr ip = ((struct sockaddr_in *)addr)->sin_addr;
183
+			
184
+			debug(D_NET, "%s", inet_ntoa(list->nets[i].net4.network));
185
+			debug(D_NET, "/%s", inet_ntoa(list->nets[i].net4.netmask));
186
+			if ((ip.s_addr & list->nets[i].net4.netmask.s_addr) == list->nets[i].net4.network.s_addr)
187
+			{
188
+				debug(D_NET, "Hit!");
189
+				return 1;
190
+			}
191
+		} else if (list->nets[i].net.af == AF_INET6 && addr->sa_family == AF_INET6)
192
+		{
193
+			u_int8_t *ip = ((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr;
194
+			int mask, j;
195
+			
196
+			mask = list->nets[i].net6.netmask;
197
+			for (j = 0; j < 16 && mask > 0; j++, mask -= 8)
198
+			{
199
+				unsigned char bytemask;
200
+				
201
+				bytemask = (mask < 8) ? ~((1L << (8 - mask)) - 1) : 0xff;
202
+				
203
+				if ((ip[j] & bytemask) != (list->nets[i].net6.network.s6_addr[j] & bytemask))
204
+					break;
205
+			}
206
+			
207
+			if (mask <= 0)
208
+			{
209
+				debug(D_NET, "Hit!");
210
+				return 1;
211
+			}
212
 		}
213
 	}
214
 
215
diff -ur orig/spamass-milter.h spamass-milter.h
216
--- orig/spamass-milter.h	2006-03-23 22:07:55.000000000 +0000
217
+++ spamass-milter.h	2008-01-01 23:55:44.000000000 +0000
218
@@ -56,16 +56,30 @@
219
 extern struct smfiDesc smfilter;
220
 
221
 /* struct describing a single network */
222
-struct net
223
+union net
224
 {
225
-	struct in_addr network;
226
-	struct in_addr netmask;
227
+	struct
228
+	{
229
+		uint8_t af;
230
+	} net;
231
+	struct
232
+	{
233
+		uint8_t af;
234
+		struct in_addr network;
235
+		struct in_addr netmask;
236
+	} net4;
237
+	struct
238
+	{
239
+		uint8_t af;
240
+		struct in6_addr network;
241
+		int netmask; /* Just the number of bits for IPv6 */
242
+	} net6;
243
 };
244
 
245
 /* an array of networks */
246
 struct networklist
247
 {
248
-	struct net *nets;
249
+	union net *nets;
250
 	int num_nets;
251
 };
252
 
253
@@ -165,7 +179,7 @@
254
 /* Private data structure to carry per-client data between calls */
255
 struct context
256
 {
257
-	struct in_addr connect_ip;	// remote IP address
258
+	char connect_ip[64];	// remote IP address
259
 	char *helo;
260
 	SpamAssassin *assassin; // pointer to the SA object if we're processing a message
261
 };
262
@@ -182,7 +196,7 @@
263
 int cmp_nocase_partial(const string&, const string&);
264
 void closeall(int fd);
265
 void parse_networklist(char *string, struct networklist *list);
266
-int ip_in_networklist(struct in_addr ip, struct networklist *list);
267
+int ip_in_networklist(struct sockaddr *addr, struct networklist *list);
268
 void parse_debuglevel(char* string);
269
 char *strlwr(char *str);
270
 void warnmacro(char *macro, char *scope);

Return to bug 155979