diff options
| author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-11 23:40:34 +0100 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-11 23:40:34 +0100 |
| commit | fd277c053d8cbc1b9bbd930670e032c1427ea0a8 (patch) | |
| tree | 81b4ea06c185ac77257a4e0a2e992ffb4c1a2483 | |
| parent | 50e617f8b60b61e98538cb8ccb09958740defb9a (diff) | |
| download | plan9front-fd277c053d8cbc1b9bbd930670e032c1427ea0a8.tar.xz | |
upas/smtpd: implement ipv6 support for ip blacklist, replace v4parsecidr() with parseipandmask()
| -rw-r--r-- | sys/src/cmd/upas/smtp/greylist.c | 40 | ||||
| -rw-r--r-- | sys/src/cmd/upas/smtp/mkfile | 3 | ||||
| -rw-r--r-- | sys/src/cmd/upas/smtp/smtpd.c | 21 | ||||
| -rw-r--r-- | sys/src/cmd/upas/smtp/smtpd.h | 2 | ||||
| -rw-r--r-- | sys/src/cmd/upas/smtp/spam.c | 52 |
5 files changed, 28 insertions, 90 deletions
diff --git a/sys/src/cmd/upas/smtp/greylist.c b/sys/src/cmd/upas/smtp/greylist.c index 3bbe9f586..b536a6973 100644 --- a/sys/src/cmd/upas/smtp/greylist.c +++ b/sys/src/cmd/upas/smtp/greylist.c @@ -42,54 +42,20 @@ static char whitelist[] = "/mail/grey/whitelist"; static int onwhitelist(void) { - int lnlen; - char *line, *parse, *p; - char input[128]; - uchar *mask; - uchar mask4[IPaddrlen], addr4[IPaddrlen]; - uchar rmask[IPaddrlen], addr[IPaddrlen]; - uchar ipmasked[IPaddrlen], addrmasked[IPaddrlen]; + char *line, *p; Biobuf *wl; wl = Bopen(whitelist, OREAD); if (wl == nil) return 0; while ((line = Brdline(wl, '\n')) != nil) { - lnlen = Blinelen(wl); - line[lnlen-1] = '\0'; /* clobber newline */ - + line[Blinelen(wl)-1] = '\0'; /* clobber newline */ p = strpbrk(line, " \t"); if (p) *p = 0; if (line[0] == '#' || line[0] == 0) continue; - - /* default mask is /24 (v4) or /128 (v6) for bare IP */ - parse = line; - if (strchr(line, '/') == nil) { - strecpy(input, input + sizeof input - 5, line); - if (strchr(line, ':') != nil) /* v6? */ - strcat(input, "/128"); - else if (strchr(line, '.') != nil) - strcat(input, "/24"); /* was /32 */ - parse = input; - } - mask = rmask; - if (strchr(line, ':') != nil) { /* v6? */ - parseip(addr, parse); - p = strchr(parse, '/'); - if (p != nil) - parseipmask(mask, p); - else - mask = IPallbits; - } else { - v4parsecidr(addr4, mask4, parse); - v4tov6(addr, addr4); - v4tov6(mask, mask4); - } - maskip(addr, mask, addrmasked); - maskip(rsysip, mask, ipmasked); - if (equivip6(ipmasked, addrmasked)) + if(ipcheck(line)) break; } Bterm(wl); diff --git a/sys/src/cmd/upas/smtp/mkfile b/sys/src/cmd/upas/smtp/mkfile index 9f02f8ae2..538e99083 100644 --- a/sys/src/cmd/upas/smtp/mkfile +++ b/sys/src/cmd/upas/smtp/mkfile @@ -1,5 +1,4 @@ </$objtype/mkfile -<../mkupas TARG = smtpd\ smtp\ @@ -55,3 +54,5 @@ clean:V: ../common/libcommon.a$O: cd ../common && mk + +<../mkupas diff --git a/sys/src/cmd/upas/smtp/smtpd.c b/sys/src/cmd/upas/smtp/smtpd.c index 93926cdba..677717509 100644 --- a/sys/src/cmd/upas/smtp/smtpd.c +++ b/sys/src/cmd/upas/smtp/smtpd.c @@ -238,6 +238,19 @@ reply(char *fmt, ...) return n; } +int +ipcheck(char *s) +{ + uchar ip[IPaddrlen], mask[IPaddrlen]; + uchar net[IPaddrlen], rnet[IPaddrlen]; + + if(parseipandmask(ip, mask, s, strchr(s, '/')) == -1) + return 0; + maskip(ip, mask, net); + maskip(rsysip, mask, rnet); + return ipcmp(net, rnet) == 0; +} + void reset(void) { @@ -611,8 +624,7 @@ senderok(char *rcpt) * if not, perhaps a later entry's domain will. */ mentioned = 1; - if (parseip(dnsip, snd->domain) != -1 && - memcmp(rsysip, dnsip, IPaddrlen) == 0) + if (parseip(dnsip, snd->domain) != -1 && ipcmp(rsysip, dnsip) == 0) return 1; /* * NB: nt->line links form a circular list(!). @@ -622,9 +634,8 @@ senderok(char *rcpt) if (first == nil) continue; do { - if (strcmp(nt->attr, "ip") == 0 && - parseip(dnsip, nt->val) != -1 && - memcmp(rsysip, dnsip, IPaddrlen) == 0) + if (strcmp(nt->attr, "ip") == 0 + && parseip(dnsip, nt->val) != -1 && ipcmp(rsysip, dnsip) == 0) matched = 1; next = nt->line; free(nt); diff --git a/sys/src/cmd/upas/smtp/smtpd.h b/sys/src/cmd/upas/smtp/smtpd.h index be2a1523e..b16c8fbda 100644 --- a/sys/src/cmd/upas/smtp/smtpd.h +++ b/sys/src/cmd/upas/smtp/smtpd.h @@ -38,6 +38,8 @@ extern List senders; extern List rcvers; extern uchar rsysip[]; +int ipcheck(char*); + void addbadguy(char*); void auth(String *, String *); int blocked(String*); diff --git a/sys/src/cmd/upas/smtp/spam.c b/sys/src/cmd/upas/smtp/spam.c index 20ef9f944..b326520b8 100644 --- a/sys/src/cmd/upas/smtp/spam.c +++ b/sys/src/cmd/upas/smtp/spam.c @@ -44,10 +44,8 @@ static Keyword actions[] = { static int hisaction; static List ourdoms; static List badguys; -static ulong v4peerip; static char* getline(Biobuf*); -static int cidrcheck(char*); static int findkey(char *val, Keyword *p) @@ -110,10 +108,6 @@ getconf(void) char *cp, *p; String *s; char buf[512]; - uchar addr[4]; - - v4parseip(addr, nci->rsys); - v4peerip = nhgetl(addr); trusted = istrusted(nci->rsys); hisaction = getaction(nci->rsys, "ip"); @@ -149,8 +143,10 @@ getconf(void) dom = strdup(p); break; case OURNETS: - if (trusted == 0) - trusted = cidrcheck(p); + while(trusted == 0 && *p){ + trusted = ipcheck(p); + p += strlen(p) + 1; + } break; case OURDOMS: while(*p){ @@ -398,44 +394,6 @@ masquerade(String *path, char *him) return rv; } -/* this is a v4 only check */ -static int -cidrcheck(char *cp) -{ - char *p; - ulong a, m; - uchar addr[IPv4addrlen]; - uchar mask[IPv4addrlen]; - - if(v4peerip == 0) - return 0; - - /* parse a list of CIDR addresses comparing each to the peer IP addr */ - while(cp && *cp){ - v4parsecidr(addr, mask, cp); - a = nhgetl(addr); - m = nhgetl(mask); - /* - * if a mask isn't specified, we build a minimal mask - * instead of using the default mask for that net. in this - * case we never allow a class A mask (0xff000000). - */ - if(strchr(cp, '/') == 0){ - m = 0xff000000; - p = cp; - for(p = strchr(p, '.'); p && p[1]; p = strchr(p + 1, '.')) - m = (m>>8)|0xff000000; - - /* force at least a class B */ - m |= 0xffff0000; - } - if((v4peerip & m) == a) - return 1; - cp += strlen(cp) + 1; - } - return 0; -} - int isbadguy(void) { @@ -443,7 +401,7 @@ isbadguy(void) /* check if this IP address is banned */ for(l = badguys.first; l; l = l->next) - if(cidrcheck(s_to_c(l->p))) + if(ipcheck(s_to_c(l->p))) return 1; return 0; |
