From: Ian Jackson Date: Sun, 3 Jun 2012 11:19:19 +0000 (+0100) Subject: support masks X-Git-Tag: debian/2.1.0~2 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=authbind.git;a=commitdiff_plain;h=1fe15d20963240b9cf021602eac927dfe97f7aaa support masks --- diff --git a/authbind.1 b/authbind.1 index 52f0204..46abb3a 100644 --- a/authbind.1 +++ b/authbind.1 @@ -105,21 +105,23 @@ will return .RI ( "Operation not permitted" ", or " "Not owner" ). If the file does exist it will be searched for a line of the form .nf -.IR addrmin [\fB\-\fR addrmax ]\fB,\fR portmin \fB\-\fR portmax +.IR addrmin [\fB\-\fR addrmax ]\fB,\fR portmin [\fB\-\fR portmax ] +.IR addr [\fB/\fR length ]\fB,\fR portmin [\fB\-\fR portmax ] .IB addr4 / length : portmin , portmax .fi matching the request. The first form requires that the address lies in the relevant range (inclusive at both ends). -The second form requires that the initial +The second and third forms require that the initial .I length bits of .I addr match those in the proposed .B bind -call and is only available for IPv4. -Addresses can -be in any form acceptable to inet_pton. In both cases +call. The third form is only available for IPv4 since IPv6 addresses +contain colons. +Addresses in the byuid file can +be in any form acceptable to inet_pton. In all cases the proposed port number must lie is in the inclusive range specified. If such a line is found then the binding is authorised. Otherwise it is not, and diff --git a/helper.c b/helper.c index db815c1..a58e7aa 100644 --- a/helper.c +++ b/helper.c @@ -196,30 +196,68 @@ int main(int argc, const char *const *argv) { if (!comma) continue; *comma++ = '\0'; + char *slash = strchr(fnbuf,'/'); char *hyphen = strchr(fnbuf,'-'); - const char *min, *max; - if (hyphen) { - *hyphen++ = '\0'; - min = fnbuf; - max = hyphen; + + if (slash && hyphen) + continue; + + if (slash) { + int alen; + *slash++ = '\0'; + nchar = -1; + sscanf(slash," %u %n",&alen,&nchar); + if (nchar != strlen(slash)) + continue; + unsigned char thaddr[addrlen_any]; + if (inet_pton(af,fnbuf,thaddr) != 1) + continue; + int pfxlen_remain = alen; + int i; + for (i=0; i> pfxlen_thisbyte); + unsigned thaddr_thisbyte = thaddr[i]; + unsigned addr_thisbyte = ((unsigned char*)addr_any)[i]; + if ((addr_thisbyte & mask_thisbyte) != thaddr_thisbyte) + goto badline; + } + if (pfxlen_remain) badline: continue; + /* hooray */ } else { - min = fnbuf; - max = fnbuf; + const char *min, *max; + if (hyphen) { + *hyphen++ = '\0'; + min = fnbuf; + max = hyphen; + } else { + min = fnbuf; + max = fnbuf; + } + unsigned char minaddr[addrlen_any]; + unsigned char maxaddr[addrlen_any]; + if (inet_pton(af,min,minaddr) != 1 || + inet_pton(af,max,maxaddr) != 1) + continue; + if (memcmp(addr_any,minaddr,addrlen_any) < 0 || + memcmp(addr_any,maxaddr,addrlen_any) > 0) + continue; } - unsigned char minaddr[addrlen_any]; - unsigned char maxaddr[addrlen_any]; - if (inet_pton(af,min,minaddr) != 1 || - inet_pton(af,max,maxaddr) != 1) - continue; - if (memcmp(addr_any,minaddr,addrlen_any) < 0 || - memcmp(addr_any,maxaddr,addrlen_any) > 0) - continue; - nchar = -1; - sscanf(comma," %u-%u %n", - &pmin,&pmax,&nchar); - if (nchar != strlen(comma)) + if (nchar = -1, + sscanf(comma," %u-%u %n", + &pmin,&pmax,&nchar), + nchar == strlen(comma)) { + /* good */ + } else if (nchar = -1, + sscanf(comma," %u %n", + &pmin,&nchar), + nchar == strlen(comma)) { + pmax = pmin; + } else { continue; + } } if (hportpmax) continue;