chiark / gitweb /
support masks
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 3 Jun 2012 11:19:19 +0000 (12:19 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 3 Jun 2012 11:19:19 +0000 (12:19 +0100)
authbind.1
helper.c

index 52f0204..46abb3a 100644 (file)
@@ -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
index db815c1..a58e7aa 100644 (file)
--- 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<addrlen_any; i++) {
+         int pfxlen_thisbyte = pfxlen_remain < 8 ? pfxlen_remain : 8;
+         pfxlen_remain -= pfxlen_thisbyte;
+         unsigned mask_thisbyte = 0xff ^ (0xff >> 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 (hport<pmin || hport>pmax) continue;