qmail/qmail-1.03-moreipme-0.6.patch

398 lines
13 KiB
Diff

diff -ur --new-file qmail-1.03/Makefile qmail-1.03-moreipme-0.6/Makefile
--- qmail-1.03/Makefile Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/Makefile Sat May 22 18:38:48 2004
@@ -783,20 +783,31 @@
ipme.o: \
compile ipme.c hassalen.h byte.h ip.h ipalloc.h ip.h gen_alloc.h \
-stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h
+stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h readwrite.h
./compile ipme.c
ipmeprint: \
-load ipmeprint.o ipme.o ip.o ipalloc.o stralloc.a alloc.a substdio.a \
+load ipmeprint.o ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a substdio.a \
error.a str.a fs.a socket.lib
- ./load ipmeprint ipme.o ip.o ipalloc.o stralloc.a alloc.a \
+ ./load ipmeprint ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a \
substdio.a error.a str.a fs.a `cat socket.lib`
ipmeprint.o: \
compile ipmeprint.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \
-ipalloc.h ip.h gen_alloc.h exit.h
+ipalloc.h ip.h gen_alloc.h exit.h auto_qmail.h
./compile ipmeprint.c
+ipmetest: \
+load ipmetest.o ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a substdio.a \
+error.a str.a fs.a env.a socket.lib
+ ./load ipmetest ipme.o ip.o ipalloc.o auto_qmail.o open.a getln.a stralloc.a alloc.a \
+ substdio.a error.a env.a str.a fs.a `cat socket.lib`
+
+ipmetest.o: \
+compile ipmetest.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \
+ipalloc.h ip.h gen_alloc.h exit.h auto_qmail.h
+ ./compile ipmetest.c
+
it: \
qmail-local qmail-lspawn qmail-getpw qmail-remote qmail-rspawn \
qmail-clean qmail-send qmail-start splogger qmail-queue qmail-inject \
@@ -804,7 +815,7 @@
qmail-pw2u qmail-qread qmail-qstat qmail-tcpto qmail-tcpok \
qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \
qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast dnscname \
-dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \
+dnsptr dnsip dnsmxip dnsfq hostname ipmeprint ipmetest qreceipt qsmhook qbiff \
forward preline condredirect bouncesaying except maildirmake \
maildir2mbox maildirwatch qail elq pinq idedit install-big install \
instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
@@ -1779,7 +1790,7 @@
qmail-qread.c qmail-qstat.sh qmail-queue.c qmail-remote.c \
qmail-rspawn.c qmail-send.c qmail-showctl.c qmail-smtpd.c \
qmail-start.c qmail-tcpok.c qmail-tcpto.c spawn.c dnscname.c dnsfq.c \
-dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c tcp-env.c \
+dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c ipmetest.c tcp-env.c \
sendmail.c qreceipt.c qsmhook.c qbiff.c forward.c preline.c predate.c \
except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \
maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \
diff -ur --new-file qmail-1.03/TARGETS qmail-1.03-moreipme-0.6/TARGETS
--- qmail-1.03/TARGETS Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/TARGETS Sat May 22 18:38:48 2004
@@ -276,6 +276,8 @@
hostname
ipmeprint.o
ipmeprint
+ipmetest.o
+ipmetest
qreceipt.o
qreceipt
qsmhook.o
diff -ur --new-file qmail-1.03/ipme.c qmail-1.03-moreipme-0.6/ipme.c
--- qmail-1.03/ipme.c Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/ipme.c Sat May 22 19:04:25 2004
@@ -14,23 +14,65 @@
#include "ipalloc.h"
#include "stralloc.h"
#include "ipme.h"
+#include "substdio.h"
+#include "readwrite.h"
static int ipmeok = 0;
ipalloc ipme = {0};
+ipalloc ipme_mask = {0};
+ipalloc notipme = {0};
+ipalloc notipme_mask = {0};
int ipme_is(ip)
struct ip_address *ip;
{
- int i;
if (ipme_init() != 1) return -1;
- for (i = 0;i < ipme.len;++i)
- if (byte_equal(&ipme.ix[i].ip,4,ip))
- return 1;
- return 0;
+ return ipme_match(&ipme,&ipme_mask,ip) > ipme_match(&notipme,&notipme_mask,ip);
}
+int ipme_match(ipa, ipa_mask, ip)
+struct ipalloc *ipa, *ipa_mask;
+struct ip_address *ip;
+{
+ int i,j;
+ struct ip_address masked;
+ int masklen, longest_masklen=-1;
+
+ for(i=0;i < ipa->len;++i)
+ {
+ masklen = 0;
+ for(j=0;j<4;++j)
+ {
+ switch(ipa_mask->ix[i].ip.d[j])
+ {
+ case 255: masklen += 8; break;
+ case 254: masklen += 7; break;
+ case 252: masklen += 6; break;
+ case 248: masklen += 5; break;
+ case 240: masklen += 4; break;
+ case 224: masklen += 3; break;
+ case 192: masklen += 2; break;
+ case 128: masklen += 1; break;
+ default: masklen += 0; break;
+ }
+ if (ipa->ix[i].ip.d[j] != (ip->d[j] & ipa_mask->ix[i].ip.d[j]))
+ break;
+ }
+ if ( (j == 4) && (masklen > longest_masklen) )
+ {
+ longest_masklen = masklen;
+ }
+ }
+ return longest_masklen;
+}
static stralloc buf = {0};
+#define ipme_init_retclean(ret) { \
+ if (moreipme.ix) alloc_free(moreipme.ix); \
+ if (moreipme_mask.ix) alloc_free(moreipme_mask.ix); \
+ if (buf.s) alloc_free(buf.s); \
+ return ret; }
+
int ipme_init()
{
struct ifconf ifc;
@@ -39,18 +81,45 @@
struct sockaddr_in *sin;
int len;
int s;
- struct ip_mx ix;
-
+ struct ip_mx ix, ix_mask;
+ ipalloc moreipme = {0};
+ ipalloc moreipme_mask = {0};
+ int i;
+
if (ipmeok) return 1;
- if (!ipalloc_readyplus(&ipme,0)) return 0;
+ if (!ipalloc_readyplus(&ipme,0)) ipme_init_retclean(0);
+ if (!ipalloc_readyplus(&ipme_mask,0)) ipme_init_retclean(0);
+ if (!ipalloc_readyplus(&notipme,0)) ipme_init_retclean(0);
+ if (!ipalloc_readyplus(&notipme_mask,0)) ipme_init_retclean(0);
+ if (!ipalloc_readyplus(&moreipme,0)) ipme_init_retclean(0);
+ if (!ipalloc_readyplus(&moreipme_mask,0)) ipme_init_retclean(0);
+
ipme.len = 0;
- ix.pref = 0;
-
- if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1;
+ ix.pref = ix_mask.pref = 0;
+
+ if (!ipme_readipfile(&notipme, &notipme_mask, "control/notipme")) ipme_init_retclean(0);
+
+ /* 127.0.0.0/255.0.0.0 is the localhost network. Linux will treat
+ every address in this range as a local interface, even if it
+ isn't explicitly configured.
+ */
+ byte_copy(&ix.ip,4,"\x7f\0\0\0");
+ byte_copy(&ix_mask.ip,4,"\xff\0\0\0");
+ if (!ipalloc_append(&ipme,&ix)) ipme_init_retclean(0);
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) ipme_init_retclean(0);
+
+ /* 0.0.0.0 is a special address which always refers to
+ * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a. */
+ byte_copy(&ix.ip,4,"\0\0\0\0");
+ byte_copy(&ix_mask.ip,4,"\xff\xff\xff\xff");
+ if (!ipalloc_append(&ipme,&ix)) ipme_init_retclean(0);
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) ipme_init_retclean(0);
+
+ if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) ipme_init_retclean(-1);
len = 256;
for (;;) {
- if (!stralloc_ready(&buf,len)) { close(s); return 0; }
+ if (!stralloc_ready(&buf,len)) { close(s); ipme_init_retclean(0); }
buf.len = 0;
ifc.ifc_buf = buf.s;
ifc.ifc_len = len;
@@ -59,7 +128,7 @@
buf.len = ifc.ifc_len;
break;
}
- if (len > 200000) { close(s); return -1; }
+ if (len > 200000) { close(s); ipme_init_retclean(-1); }
len += 100 + (len >> 2);
}
x = buf.s;
@@ -74,7 +143,10 @@
byte_copy(&ix.ip,4,&sin->sin_addr);
if (ioctl(s,SIOCGIFFLAGS,x) == 0)
if (ifr->ifr_flags & IFF_UP)
- if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
+ {
+ if (!ipalloc_append(&ipme,&ix)) { close(s); ipme_init_retclean(0); }
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) { close(s); ipme_init_retclean(0); }
+ }
}
#else
len = sizeof(*ifr);
@@ -84,12 +156,60 @@
if (ifr->ifr_addr.sa_family == AF_INET) {
sin = (struct sockaddr_in *) &ifr->ifr_addr;
byte_copy(&ix.ip,4,&sin->sin_addr);
- if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; }
+ if (!ipalloc_append(&ipme,&ix)) { close(s); ipme_init_retclean(0); }
+ if (!ipalloc_append(&ipme_mask,&ix_mask)) { close(s); ipme_init_retclean(0); }
}
#endif
x += len;
}
close(s);
+
+ if (!ipme_readipfile(&moreipme, &moreipme_mask, "control/moreipme")) ipme_init_retclean(0);
+ for(i = 0;i < moreipme.len;++i)
+ {
+ if (!ipalloc_append(&ipme,&moreipme.ix[i])) ipme_init_retclean(0);
+ if (!ipalloc_append(&ipme_mask,&moreipme_mask.ix[i])) ipme_init_retclean(0);
+ }
ipmeok = 1;
- return 1;
+ ipme_init_retclean(1);
}
+
+
+int ipme_readipfile(ipa, ipa_mask, fn)
+ ipalloc *ipa, *ipa_mask;
+ char *fn;
+{
+ int fd = -1;
+ char inbuf[1024];
+ substdio ss;
+ stralloc l = {0};
+ int match;
+ struct ip_mx ix, ix_mask;
+ int ret = 1;
+ int slash = 0;
+
+ if ( (fd = open_read(fn)) != -1) {
+ substdio_fdbuf(&ss, read, fd, inbuf, sizeof(inbuf));
+ while ( (getln(&ss,&l,&match,'\n') != -1) && (match || l.len) ) {
+ l.len--;
+ if (!stralloc_0(&l)) { ret = 0; break; }
+ if (l.s[slash=str_chr(l.s,'/')]!='\0')
+ {
+ l.s[slash]='\0';
+ if (!ip_scan(l.s+slash+1,&ix_mask.ip))
+ continue;
+ }
+ else
+ if (!ip_scan("255.255.255.255",&ix_mask.ip)) { ret = 0; break; }
+
+ if (!ip_scan(l.s, &ix.ip)) continue;
+ if (!ipalloc_append(ipa,&ix)) { ret = 0; break; }
+ if (!ipalloc_append(ipa_mask,&ix_mask.ip)) { ret = 0; break; }
+ }
+ if (l.s) alloc_free(l.s);
+ if ( (fd >= 0) && (close(fd) == -1) )
+ ret = 0;
+ }
+ return ret;
+}
+
diff -ur --new-file qmail-1.03/ipme.h qmail-1.03-moreipme-0.6/ipme.h
--- qmail-1.03/ipme.h Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/ipme.h Sat May 22 18:38:48 2004
@@ -4,7 +4,7 @@
#include "ip.h"
#include "ipalloc.h"
-extern ipalloc ipme;
+extern ipalloc ipme, ipme_mask, notipme, notipme_mask;
extern int ipme_init();
extern int ipme_is();
diff -ur --new-file qmail-1.03/ipmeprint.c qmail-1.03-moreipme-0.6/ipmeprint.c
--- qmail-1.03/ipmeprint.c Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/ipmeprint.c Sat May 22 18:38:48 2004
@@ -3,12 +3,15 @@
#include "ip.h"
#include "ipme.h"
#include "exit.h"
+#include "auto_qmail.h"
char temp[IPFMT];
void main()
{
- int j;
+ int j,k;
+
+ chdir(auto_qmail);
switch(ipme_init())
{
case 0: substdio_putsflush(subfderr,"out of memory\n"); _exit(111);
@@ -17,8 +20,18 @@
for (j = 0;j < ipme.len;++j)
{
substdio_put(subfdout,temp,ip_fmt(temp,&ipme.ix[j].ip));
- substdio_puts(subfdout,"\n");
+ substdio_puts(subfdout,"/");
+ substdio_put(subfdout,temp,ip_fmt(temp,&ipme_mask.ix[j].ip));
+ substdio_puts(subfdout," is me\n");
+ }
+ for (j = 0;j < notipme.len;++j)
+ {
+ substdio_put(subfdout,temp,ip_fmt(temp,&notipme.ix[j].ip));
+ substdio_puts(subfdout,"/");
+ substdio_put(subfdout,temp,ip_fmt(temp,&notipme_mask.ix[j].ip));
+ substdio_puts(subfdout," is not me\n");
}
+
substdio_flush(subfdout);
_exit(0);
}
diff -ur --new-file qmail-1.03/ipmetest.c qmail-1.03-moreipme-0.6/ipmetest.c
--- qmail-1.03/ipmetest.c Wed Dec 31 19:00:00 1969
+++ qmail-1.03-moreipme-0.6/ipmetest.c Sat May 22 18:38:48 2004
@@ -0,0 +1,38 @@
+#include "subfd.h"
+#include "substdio.h"
+#include "ip.h"
+#include "ipme.h"
+#include "exit.h"
+#include "auto_qmail.h"
+#include "env.h"
+
+void main(int argc, char *argv[])
+{
+ struct ip_address ip;
+
+ if (!env_get("IPMETEST_HERE"))
+ chdir(auto_qmail);
+
+ if (argc < 2)
+ {
+ substdio_puts(subfdout,"invalid usage\n");
+ substdio_flush(subfdout);
+ exit(1);
+ }
+ if (!ip_scan(argv[1],&ip))
+ {
+ substdio_puts(subfdout,"invalid IP address\n");
+ substdio_flush(subfdout);
+ exit(1);
+ }
+ if (ipme_is(&ip))
+ {
+ substdio_puts(subfdout,"me\n");
+ }
+ else
+ {
+ substdio_puts(subfdout,"not me\n");
+ }
+ substdio_flush(subfdout);
+ exit(0);
+}
diff -ur --new-file qmail-1.03/qmail-showctl.c qmail-1.03-moreipme-0.6/qmail-showctl.c
--- qmail-1.03/qmail-showctl.c Mon Jun 15 06:53:16 1998
+++ qmail-1.03-moreipme-0.6/qmail-showctl.c Sat May 22 18:38:48 2004
@@ -230,6 +230,8 @@
do_str("localiphost",1,"localiphost","Local IP address becomes ");
do_lst("locals","Messages for me are delivered locally.","Messages for "," are delivered locally.");
do_str("me",0,"undefined! Uh-oh","My name is ");
+ do_lst("moreipme","No additional IP addresses are me.","IP address "," is me.");
+ do_lst("notipme","All of my IP addresses are me.","IP address "," is not me.");
do_lst("percenthack","The percent hack is not allowed.","The percent hack is allowed for user%host@",".");
do_str("plusdomain",1,"plusdomain","Plus domain name is ");
do_lst("qmqpservers","No QMQP servers.","QMQP server: ",".");
@@ -283,8 +285,10 @@
if (str_equal(d->d_name,"localiphost")) continue;
if (str_equal(d->d_name,"locals")) continue;
if (str_equal(d->d_name,"me")) continue;
+ if (str_equal(d->d_name,"moreipme")) continue;
if (str_equal(d->d_name,"morercpthosts")) continue;
if (str_equal(d->d_name,"morercpthosts.cdb")) continue;
+ if (str_equal(d->d_name,"notipme")) continue;
if (str_equal(d->d_name,"percenthack")) continue;
if (str_equal(d->d_name,"plusdomain")) continue;
if (str_equal(d->d_name,"qmqpservers")) continue;