1 |
diff -ur --new-file qmail-1.03/Makefile qmail-1.03-moreipme-0.6/Makefile |
2 |
--- qmail-1.03/Makefile Mon Jun 15 06:53:16 1998 |
3 |
+++ qmail-1.03-moreipme-0.6/Makefile Sat May 22 18:38:48 2004 |
4 |
@@ -783,20 +783,31 @@ |
5 |
|
6 |
ipme.o: \ |
7 |
compile ipme.c hassalen.h byte.h ip.h ipalloc.h ip.h gen_alloc.h \ |
8 |
-stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h |
9 |
+stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h readwrite.h |
10 |
./compile ipme.c |
11 |
|
12 |
ipmeprint: \ |
13 |
-load ipmeprint.o ipme.o ip.o ipalloc.o stralloc.a alloc.a substdio.a \ |
14 |
+load ipmeprint.o ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a substdio.a \ |
15 |
error.a str.a fs.a socket.lib |
16 |
- ./load ipmeprint ipme.o ip.o ipalloc.o stralloc.a alloc.a \ |
17 |
+ ./load ipmeprint ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a \ |
18 |
substdio.a error.a str.a fs.a `cat socket.lib` |
19 |
|
20 |
ipmeprint.o: \ |
21 |
compile ipmeprint.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \ |
22 |
-ipalloc.h ip.h gen_alloc.h exit.h |
23 |
+ipalloc.h ip.h gen_alloc.h exit.h auto_qmail.h |
24 |
./compile ipmeprint.c |
25 |
|
26 |
+ipmetest: \ |
27 |
+load ipmetest.o ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a substdio.a \ |
28 |
+error.a str.a fs.a env.a socket.lib |
29 |
+ ./load ipmetest ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a \ |
30 |
+ substdio.a error.a env.a str.a fs.a `cat socket.lib` |
31 |
+ |
32 |
+ipmetest.o: \ |
33 |
+compile ipmetest.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \ |
34 |
+ipalloc.h ip.h gen_alloc.h exit.h auto_qmail.h |
35 |
+ ./compile ipmetest.c |
36 |
+ |
37 |
it: \ |
38 |
qmail-local qmail-lspawn qmail-getpw qmail-remote qmail-rspawn \ |
39 |
qmail-clean qmail-send qmail-start splogger qmail-queue qmail-inject \ |
40 |
@@ -804,7 +815,7 @@ |
41 |
qmail-pw2u qmail-qread qmail-qstat qmail-tcpto qmail-tcpok \ |
42 |
qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \ |
43 |
qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast dnscname \ |
44 |
-dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \ |
45 |
+dnsptr dnsip dnsmxip dnsfq hostname ipmeprint ipmetest qreceipt qsmhook qbiff \ |
46 |
forward preline condredirect bouncesaying except maildirmake \ |
47 |
maildir2mbox maildirwatch qail elq pinq idedit install-big install \ |
48 |
instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ |
49 |
@@ -1779,7 +1790,7 @@ |
50 |
qmail-qread.c qmail-qstat.sh qmail-queue.c qmail-remote.c \ |
51 |
qmail-rspawn.c qmail-send.c qmail-showctl.c qmail-smtpd.c \ |
52 |
qmail-start.c qmail-tcpok.c qmail-tcpto.c spawn.c dnscname.c dnsfq.c \ |
53 |
-dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c tcp-env.c \ |
54 |
+dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c ipmetest.c tcp-env.c \ |
55 |
sendmail.c qreceipt.c qsmhook.c qbiff.c forward.c preline.c predate.c \ |
56 |
except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \ |
57 |
maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \ |
58 |
diff -ur --new-file qmail-1.03/TARGETS qmail-1.03-moreipme-0.6/TARGETS |
59 |
--- qmail-1.03/TARGETS Mon Jun 15 06:53:16 1998 |
60 |
+++ qmail-1.03-moreipme-0.6/TARGETS Sat May 22 18:38:48 2004 |
61 |
@@ -276,6 +276,8 @@ |
62 |
hostname |
63 |
ipmeprint.o |
64 |
ipmeprint |
65 |
+ipmetest.o |
66 |
+ipmetest |
67 |
qreceipt.o |
68 |
qreceipt |
69 |
qsmhook.o |
70 |
diff -ur --new-file qmail-1.03/ipme.c qmail-1.03-moreipme-0.6/ipme.c |
71 |
--- qmail-1.03/ipme.c Mon Jun 15 06:53:16 1998 |
72 |
+++ qmail-1.03-moreipme-0.6/ipme.c Sat May 22 19:04:25 2004 |
73 |
@@ -14,23 +14,65 @@ |
74 |
#include "ipalloc.h" |
75 |
#include "stralloc.h" |
76 |
#include "ipme.h" |
77 |
+#include "substdio.h" |
78 |
+#include "readwrite.h" |
79 |
|
80 |
static int ipmeok = 0; |
81 |
ipalloc ipme = {0}; |
82 |
+ipalloc ipme_mask = {0}; |
83 |
+ipalloc notipme = {0}; |
84 |
+ipalloc notipme_mask = {0}; |
85 |
|
86 |
int ipme_is(ip) |
87 |
struct ip_address *ip; |
88 |
{ |
89 |
- int i; |
90 |
if (ipme_init() != 1) return -1; |
91 |
- for (i = 0;i < ipme.len;++i) |
92 |
- if (byte_equal(&ipme.ix[i].ip,4,ip)) |
93 |
- return 1; |
94 |
- return 0; |
95 |
+ return ipme_match(&ipme,&ipme_mask,ip) > ipme_match(¬ipme,¬ipme_mask,ip); |
96 |
} |
97 |
|
98 |
+int ipme_match(ipa, ipa_mask, ip) |
99 |
+struct ipalloc *ipa, *ipa_mask; |
100 |
+struct ip_address *ip; |
101 |
+{ |
102 |
+ int i,j; |
103 |
+ struct ip_address masked; |
104 |
+ int masklen, longest_masklen=-1; |
105 |
+ |
106 |
+ for(i=0;i < ipa->len;++i) |
107 |
+ { |
108 |
+ masklen = 0; |
109 |
+ for(j=0;j<4;++j) |
110 |
+ { |
111 |
+ switch(ipa_mask->ix[i].ip.d[j]) |
112 |
+ { |
113 |
+ case 255: masklen += 8; break; |
114 |
+ case 254: masklen += 7; break; |
115 |
+ case 252: masklen += 6; break; |
116 |
+ case 248: masklen += 5; break; |
117 |
+ case 240: masklen += 4; break; |
118 |
+ case 224: masklen += 3; break; |
119 |
+ case 192: masklen += 2; break; |
120 |
+ case 128: masklen += 1; break; |
121 |
+ default: masklen += 0; break; |
122 |
+ } |
123 |
+ if (ipa->ix[i].ip.d[j] != (ip->d[j] & ipa_mask->ix[i].ip.d[j])) |
124 |
+ break; |
125 |
+ } |
126 |
+ if ( (j == 4) && (masklen > longest_masklen) ) |
127 |
+ { |
128 |
+ longest_masklen = masklen; |
129 |
+ } |
130 |
+ } |
131 |
+ return longest_masklen; |
132 |
+} |
133 |
static stralloc buf = {0}; |
134 |
|
135 |
+#define ipme_init_retclean(ret) { \ |
136 |
+ if (moreipme.ix) alloc_free(moreipme.ix); \ |
137 |
+ if (moreipme_mask.ix) alloc_free(moreipme_mask.ix); \ |
138 |
+ if (buf.s) alloc_free(buf.s); \ |
139 |
+ return ret; } |
140 |
+ |
141 |
int ipme_init() |
142 |
{ |
143 |
struct ifconf ifc; |
144 |
@@ -39,18 +81,45 @@ |
145 |
struct sockaddr_in *sin; |
146 |
int len; |
147 |
int s; |
148 |
- struct ip_mx ix; |
149 |
- |
150 |
+ struct ip_mx ix, ix_mask; |
151 |
+ ipalloc moreipme = {0}; |
152 |
+ ipalloc moreipme_mask = {0}; |
153 |
+ int i; |
154 |
+ |
155 |
if (ipmeok) return 1; |
156 |
- if (!ipalloc_readyplus(&ipme,0)) return 0; |
157 |
+ if (!ipalloc_readyplus(&ipme,0)) ipme_init_retclean(0); |
158 |
+ if (!ipalloc_readyplus(&ipme_mask,0)) ipme_init_retclean(0); |
159 |
+ if (!ipalloc_readyplus(¬ipme,0)) ipme_init_retclean(0); |
160 |
+ if (!ipalloc_readyplus(¬ipme_mask,0)) ipme_init_retclean(0); |
161 |
+ if (!ipalloc_readyplus(&moreipme,0)) ipme_init_retclean(0); |
162 |
+ if (!ipalloc_readyplus(&moreipme_mask,0)) ipme_init_retclean(0); |
163 |
+ |
164 |
ipme.len = 0; |
165 |
- ix.pref = 0; |
166 |
- |
167 |
- if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1; |
168 |
+ ix.pref = ix_mask.pref = 0; |
169 |
+ |
170 |
+ if (!ipme_readipfile(¬ipme, ¬ipme_mask, "control/notipme")) ipme_init_retclean(0); |
171 |
+ |
172 |
+ /* 127.0.0.0/255.0.0.0 is the localhost network. Linux will treat |
173 |
+ every address in this range as a local interface, even if it |
174 |
+ isn't explicitly configured. |
175 |
+ */ |
176 |
+ byte_copy(&ix.ip,4,"\x7f\0\0\0"); |
177 |
+ byte_copy(&ix_mask.ip,4,"\xff\0\0\0"); |
178 |
+ if (!ipalloc_append(&ipme,&ix)) ipme_init_retclean(0); |
179 |
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) ipme_init_retclean(0); |
180 |
+ |
181 |
+ /* 0.0.0.0 is a special address which always refers to |
182 |
+ * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a. */ |
183 |
+ byte_copy(&ix.ip,4,"\0\0\0\0"); |
184 |
+ byte_copy(&ix_mask.ip,4,"\xff\xff\xff\xff"); |
185 |
+ if (!ipalloc_append(&ipme,&ix)) ipme_init_retclean(0); |
186 |
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) ipme_init_retclean(0); |
187 |
+ |
188 |
+ if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) ipme_init_retclean(-1); |
189 |
|
190 |
len = 256; |
191 |
for (;;) { |
192 |
- if (!stralloc_ready(&buf,len)) { close(s); return 0; } |
193 |
+ if (!stralloc_ready(&buf,len)) { close(s); ipme_init_retclean(0); } |
194 |
buf.len = 0; |
195 |
ifc.ifc_buf = buf.s; |
196 |
ifc.ifc_len = len; |
197 |
@@ -59,7 +128,7 @@ |
198 |
buf.len = ifc.ifc_len; |
199 |
break; |
200 |
} |
201 |
- if (len > 200000) { close(s); return -1; } |
202 |
+ if (len > 200000) { close(s); ipme_init_retclean(-1); } |
203 |
len += 100 + (len >> 2); |
204 |
} |
205 |
x = buf.s; |
206 |
@@ -74,7 +143,10 @@ |
207 |
byte_copy(&ix.ip,4,&sin->sin_addr); |
208 |
if (ioctl(s,SIOCGIFFLAGS,x) == 0) |
209 |
if (ifr->ifr_flags & IFF_UP) |
210 |
- if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } |
211 |
+ { |
212 |
+ if (!ipalloc_append(&ipme,&ix)) { close(s); ipme_init_retclean(0); } |
213 |
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) { close(s); ipme_init_retclean(0); } |
214 |
+ } |
215 |
} |
216 |
#else |
217 |
len = sizeof(*ifr); |
218 |
@@ -84,12 +156,60 @@ |
219 |
if (ifr->ifr_addr.sa_family == AF_INET) { |
220 |
sin = (struct sockaddr_in *) &ifr->ifr_addr; |
221 |
byte_copy(&ix.ip,4,&sin->sin_addr); |
222 |
- if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } |
223 |
+ if (!ipalloc_append(&ipme,&ix)) { close(s); ipme_init_retclean(0); } |
224 |
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) { close(s); ipme_init_retclean(0); } |
225 |
} |
226 |
#endif |
227 |
x += len; |
228 |
} |
229 |
close(s); |
230 |
+ |
231 |
+ if (!ipme_readipfile(&moreipme, &moreipme_mask, "control/moreipme")) ipme_init_retclean(0); |
232 |
+ for(i = 0;i < moreipme.len;++i) |
233 |
+ { |
234 |
+ if (!ipalloc_append(&ipme,&moreipme.ix[i])) ipme_init_retclean(0); |
235 |
+ if (!ipalloc_append(&ipme_mask,&moreipme_mask.ix[i])) ipme_init_retclean(0); |
236 |
+ } |
237 |
ipmeok = 1; |
238 |
- return 1; |
239 |
+ ipme_init_retclean(1); |
240 |
} |
241 |
+ |
242 |
+ |
243 |
+int ipme_readipfile(ipa, ipa_mask, fn) |
244 |
+ ipalloc *ipa, *ipa_mask; |
245 |
+ char *fn; |
246 |
+{ |
247 |
+ int fd = -1; |
248 |
+ char inbuf[1024]; |
249 |
+ substdio ss; |
250 |
+ stralloc l = {0}; |
251 |
+ int match; |
252 |
+ struct ip_mx ix, ix_mask; |
253 |
+ int ret = 1; |
254 |
+ int slash = 0; |
255 |
+ |
256 |
+ if ( (fd = open_read(fn)) != -1) { |
257 |
+ substdio_fdbuf(&ss, read, fd, inbuf, sizeof(inbuf)); |
258 |
+ while ( (getln(&ss,&l,&match,'\n') != -1) && (match || l.len) ) { |
259 |
+ l.len--; |
260 |
+ if (!stralloc_0(&l)) { ret = 0; break; } |
261 |
+ if (l.s[slash=str_chr(l.s,'/')]!='\0') |
262 |
+ { |
263 |
+ l.s[slash]='\0'; |
264 |
+ if (!ip_scan(l.s+slash+1,&ix_mask.ip)) |
265 |
+ continue; |
266 |
+ } |
267 |
+ else |
268 |
+ if (!ip_scan("255.255.255.255",&ix_mask.ip)) { ret = 0; break; } |
269 |
+ |
270 |
+ if (!ip_scan(l.s, &ix.ip)) continue; |
271 |
+ if (!ipalloc_append(ipa,&ix)) { ret = 0; break; } |
272 |
+ if (!ipalloc_append(ipa_mask,&ix_mask.ip)) { ret = 0; break; } |
273 |
+ } |
274 |
+ if (l.s) alloc_free(l.s); |
275 |
+ if ( (fd >= 0) && (close(fd) == -1) ) |
276 |
+ ret = 0; |
277 |
+ } |
278 |
+ return ret; |
279 |
+} |
280 |
+ |
281 |
diff -ur --new-file qmail-1.03/ipme.h qmail-1.03-moreipme-0.6/ipme.h |
282 |
--- qmail-1.03/ipme.h Mon Jun 15 06:53:16 1998 |
283 |
+++ qmail-1.03-moreipme-0.6/ipme.h Sat May 22 18:38:48 2004 |
284 |
@@ -4,7 +4,7 @@ |
285 |
#include "ip.h" |
286 |
#include "ipalloc.h" |
287 |
|
288 |
-extern ipalloc ipme; |
289 |
+extern ipalloc ipme, ipme_mask, notipme, notipme_mask; |
290 |
|
291 |
extern int ipme_init(); |
292 |
extern int ipme_is(); |
293 |
diff -ur --new-file qmail-1.03/ipmeprint.c qmail-1.03-moreipme-0.6/ipmeprint.c |
294 |
--- qmail-1.03/ipmeprint.c Mon Jun 15 06:53:16 1998 |
295 |
+++ qmail-1.03-moreipme-0.6/ipmeprint.c Sat May 22 18:38:48 2004 |
296 |
@@ -3,12 +3,15 @@ |
297 |
#include "ip.h" |
298 |
#include "ipme.h" |
299 |
#include "exit.h" |
300 |
+#include "auto_qmail.h" |
301 |
|
302 |
char temp[IPFMT]; |
303 |
|
304 |
void main() |
305 |
{ |
306 |
- int j; |
307 |
+ int j,k; |
308 |
+ |
309 |
+ chdir(auto_qmail); |
310 |
switch(ipme_init()) |
311 |
{ |
312 |
case 0: substdio_putsflush(subfderr,"out of memory\n"); _exit(111); |
313 |
@@ -17,8 +20,18 @@ |
314 |
for (j = 0;j < ipme.len;++j) |
315 |
{ |
316 |
substdio_put(subfdout,temp,ip_fmt(temp,&ipme.ix[j].ip)); |
317 |
- substdio_puts(subfdout,"\n"); |
318 |
+ substdio_puts(subfdout,"/"); |
319 |
+ substdio_put(subfdout,temp,ip_fmt(temp,&ipme_mask.ix[j].ip)); |
320 |
+ substdio_puts(subfdout," is me\n"); |
321 |
+ } |
322 |
+ for (j = 0;j < notipme.len;++j) |
323 |
+ { |
324 |
+ substdio_put(subfdout,temp,ip_fmt(temp,¬ipme.ix[j].ip)); |
325 |
+ substdio_puts(subfdout,"/"); |
326 |
+ substdio_put(subfdout,temp,ip_fmt(temp,¬ipme_mask.ix[j].ip)); |
327 |
+ substdio_puts(subfdout," is not me\n"); |
328 |
} |
329 |
+ |
330 |
substdio_flush(subfdout); |
331 |
_exit(0); |
332 |
} |
333 |
diff -ur --new-file qmail-1.03/ipmetest.c qmail-1.03-moreipme-0.6/ipmetest.c |
334 |
--- qmail-1.03/ipmetest.c Wed Dec 31 19:00:00 1969 |
335 |
+++ qmail-1.03-moreipme-0.6/ipmetest.c Sat May 22 18:38:48 2004 |
336 |
@@ -0,0 +1,38 @@ |
337 |
+#include "subfd.h" |
338 |
+#include "substdio.h" |
339 |
+#include "ip.h" |
340 |
+#include "ipme.h" |
341 |
+#include "exit.h" |
342 |
+#include "auto_qmail.h" |
343 |
+#include "env.h" |
344 |
+ |
345 |
+void main(int argc, char *argv[]) |
346 |
+{ |
347 |
+ struct ip_address ip; |
348 |
+ |
349 |
+ if (!env_get("IPMETEST_HERE")) |
350 |
+ chdir(auto_qmail); |
351 |
+ |
352 |
+ if (argc < 2) |
353 |
+ { |
354 |
+ substdio_puts(subfdout,"invalid usage\n"); |
355 |
+ substdio_flush(subfdout); |
356 |
+ exit(1); |
357 |
+ } |
358 |
+ if (!ip_scan(argv[1],&ip)) |
359 |
+ { |
360 |
+ substdio_puts(subfdout,"invalid IP address\n"); |
361 |
+ substdio_flush(subfdout); |
362 |
+ exit(1); |
363 |
+ } |
364 |
+ if (ipme_is(&ip)) |
365 |
+ { |
366 |
+ substdio_puts(subfdout,"me\n"); |
367 |
+ } |
368 |
+ else |
369 |
+ { |
370 |
+ substdio_puts(subfdout,"not me\n"); |
371 |
+ } |
372 |
+ substdio_flush(subfdout); |
373 |
+ exit(0); |
374 |
+} |
375 |
diff -ur --new-file qmail-1.03/qmail-showctl.c qmail-1.03-moreipme-0.6/qmail-showctl.c |
376 |
--- qmail-1.03/qmail-showctl.c Mon Jun 15 06:53:16 1998 |
377 |
+++ qmail-1.03-moreipme-0.6/qmail-showctl.c Sat May 22 18:38:48 2004 |
378 |
@@ -230,6 +230,8 @@ |
379 |
do_str("localiphost",1,"localiphost","Local IP address becomes "); |
380 |
do_lst("locals","Messages for me are delivered locally.","Messages for "," are delivered locally."); |
381 |
do_str("me",0,"undefined! Uh-oh","My name is "); |
382 |
+ do_lst("moreipme","No additional IP addresses are me.","IP address "," is me."); |
383 |
+ do_lst("notipme","All of my IP addresses are me.","IP address "," is not me."); |
384 |
do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@","."); |
385 |
do_str("plusdomain",1,"plusdomain","Plus domain name is "); |
386 |
do_lst("qmqpservers","No QMQP servers.","QMQP server: ","."); |
387 |
@@ -283,8 +285,10 @@ |
388 |
if (str_equal(d->d_name,"localiphost")) continue; |
389 |
if (str_equal(d->d_name,"locals")) continue; |
390 |
if (str_equal(d->d_name,"me")) continue; |
391 |
+ if (str_equal(d->d_name,"moreipme")) continue; |
392 |
if (str_equal(d->d_name,"morercpthosts")) continue; |
393 |
if (str_equal(d->d_name,"morercpthosts.cdb")) continue; |
394 |
+ if (str_equal(d->d_name,"notipme")) continue; |
395 |
if (str_equal(d->d_name,"percenthack")) continue; |
396 |
if (str_equal(d->d_name,"plusdomain")) continue; |
397 |
if (str_equal(d->d_name,"qmqpservers")) continue; |