else _exit(0);
}
+static void checkexecflagfile(const char *file) {
+ if (!access(file,X_OK)) authorised();
+ if (errno != ENOENT) exiterrno(errno);
+}
+
static void hex2bytes(const char *string, unsigned char *out, int len) {
int i;
for (i=0; i<len; i++) {
if (errno != ENOENT) exiterrno(errno);
char npbuf[INET_ADDRSTRLEN + INET6_ADDRSTRLEN];
- np= inet_ntop(af,addr_any,npbuf,addrlen_any);
+ np= inet_ntop(af,addr_any,npbuf,sizeof(npbuf));
assert(np);
if (af == AF_INET) {
- snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s%s:%u",np,tophalfchar,hport);
- if (!access(fnbuf,X_OK)) authorised();
- if (errno != ENOENT) exiterrno(errno);
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s%s:%u",tophalfchar,np,hport);
+ checkexecflagfile(fnbuf);
}
- snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s%s,%u",np,tophalfchar,hport);
- if (!access(fnbuf,X_OK)) authorised();
- if (errno != ENOENT) exiterrno(errno);
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s%s,%u",tophalfchar,np,hport);
+ checkexecflagfile(fnbuf);
+
+ if (af == AF_INET6) {
+ char sbuf[addrlen_any*3+1], *sp = sbuf;
+ const unsigned char *ip = addr_any;
+ int i;
+ for (i=0; i<8; i++) {
+ unsigned val = 0;
+ val |= *ip++; val <<= 8;
+ val |= *ip++;
+ if (i) *sp++ = ':';
+ sp += sprintf(sp,"%x",val);
+ }
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s%s,%u",tophalfchar,sbuf,hport);
+ checkexecflagfile(fnbuf);
+ }
uid= getuid(); if (uid==(uid_t)-1) perrorfail("getuid");
snprintf(fnbuf,sizeof(fnbuf)-1,"byuid/%s%lu",tophalfchar,(unsigned long)uid);
while (fgets(fnbuf,sizeof(fnbuf)-1,file)) {
unsigned int a1,a2,a3,a4, alen,pmin,pmax;
- int nchar= -1;
+ int nchar;
if (af == AF_INET &&
- (sscanf(fnbuf," %u.%u.%u.%u/%u: %u,%u %n",
+ (nchar = -1,
+ sscanf(fnbuf," %u.%u.%u.%u/%u: %u,%u %n",
&a1,&a2,&a3,&a4,&alen,&pmin,&pmax,&nchar),
nchar == strlen(fnbuf))) {
unsigned long thaddr, thmask;
thaddr= (a1<<24)|(a2<<16)|(a3<<8)|(a4);
- thmask= 0x0ffffffffUL<<(32-alen);
+ thmask= alen ? 0x0ffffffffUL<<(32-alen) : 0;
if ((haddr4&thmask) != thaddr) continue;
} else {
char *comma = strchr(fnbuf,',');
- if (comma) continue;
+ 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;
- 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;