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 52f0204f38eeb39440e50d9085749895867801b0..46abb3ab132b5d04b2759a8838bb216c68daf713 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
 .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).
 .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
 .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
 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 db815c11a322606d6081189b3893e673d24671aa..a58e7aae666f30899a9673f2efbaf7b070b8bdd2 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';
 
       if (!comma) continue;
       *comma++ = '\0';
 
+      char *slash = strchr(fnbuf,'/');
       char *hyphen = 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 {
       } 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;
        continue;
+      }
 
     }
     if (hport<pmin || hport>pmax) continue;
 
     }
     if (hport<pmin || hport>pmax) continue;