summaryrefslogtreecommitdiff
path: root/usr.sbin/httpd
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2003-11-21 18:12:50 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2003-11-21 18:12:50 +0000
commit664c888f84c96719ac69239aeff21b5cddff4206 (patch)
tree88b08531fb6e83c502b64a3341dbb7634c7de36b /usr.sbin/httpd
parent86adfae0e33527eb43cda997ae105e35c1db89f3 (diff)
Allow and Deny rules with IP addresses outside the class A range
(e.g. 192.168.1.1) where parsed incorrectly on sparc64. It only affected IP addresses with no netmask definition. The cause of this was: a) use of the wrong type -- unsigned long instead of a 32bit value b) implicit casts from int to unsigned long with sign extension While doing that fix also some other obvious bugs. from claudio jeker
Diffstat (limited to 'usr.sbin/httpd')
-rw-r--r--usr.sbin/httpd/src/modules/standard/mod_access.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/usr.sbin/httpd/src/modules/standard/mod_access.c b/usr.sbin/httpd/src/modules/standard/mod_access.c
index 41884ca1e24..68dec7aa3d9 100644
--- a/usr.sbin/httpd/src/modules/standard/mod_access.c
+++ b/usr.sbin/httpd/src/modules/standard/mod_access.c
@@ -82,8 +82,8 @@ typedef struct {
union {
char *from;
struct {
- unsigned long net;
- unsigned long mask;
+ struct in_addr net;
+ struct in_addr mask;
} ip;
} x;
enum allowdeny_type type;
@@ -167,14 +167,14 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
}
else if ((s = strchr(where, '/'))) {
- unsigned long mask;
+ struct in_addr mask;
a->type = T_IP;
/* trample on where, we won't be using it any more */
*s++ = '\0';
if (!is_ip(where)
- || (a->x.ip.net = ap_inet_addr(where)) == INADDR_NONE) {
+ || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
a->type = T_FAIL;
return "syntax error in network portion of network/netmask";
}
@@ -186,24 +186,26 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
}
/* is it in /a.b.c.d form? */
if (strchr(s, '.')) {
- mask = ap_inet_addr(s);
- if (mask == INADDR_NONE) {
+ mask.s_addr = ap_inet_addr(s);
+ if (mask.s_addr == INADDR_NONE) {
a->type = T_FAIL;
return "syntax error in mask portion of network/netmask";
}
}
else {
+ int i;
+
/* assume it's in /nnn form */
- mask = atoi(s);
- if (mask > 32 || mask <= 0) {
+ i = atoi(s);
+ if (i > 32 || i <= 0) {
a->type = T_FAIL;
return "invalid mask in network/netmask";
}
- mask = 0xFFFFFFFFUL << (32 - mask);
- mask = htonl(mask);
+ mask.s_addr = 0xFFFFFFFFUL << (32 - i);
+ mask.s_addr = htonl(mask.s_addr);
}
a->x.ip.mask = mask;
- a->x.ip.net = (a->x.ip.net & mask); /* pjr - This fixes PR 4770 */
+ a->x.ip.net.s_addr = (a->x.ip.net.s_addr & mask.s_addr); /* pjr - This fixes PR 4770 */
}
else if (ap_isdigit(*where) && is_ip(where)) {
/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
@@ -214,8 +216,8 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
a->type = T_IP;
/* parse components */
s = where;
- a->x.ip.net = 0;
- a->x.ip.mask = 0;
+ a->x.ip.net.s_addr = 0;
+ a->x.ip.mask.s_addr = 0;
shift = 24;
while (*s) {
t = s;
@@ -234,6 +236,7 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
return "invalid ip address";
}
if (shift < 0) {
+ a->type = T_FAIL;
return "invalid ip address, only 4 octets allowed";
}
octet = atoi(s);
@@ -241,13 +244,13 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
a->type = T_FAIL;
return "each octet must be between 0 and 255 inclusive";
}
- a->x.ip.net |= octet << shift;
- a->x.ip.mask |= 0xFFUL << shift;
+ a->x.ip.net.s_addr |= (unsigned int)octet << shift;
+ a->x.ip.mask.s_addr |= 0xFFUL << shift;
s = t;
shift -= 8;
}
- a->x.ip.net = ntohl(a->x.ip.net);
- a->x.ip.mask = ntohl(a->x.ip.mask);
+ a->x.ip.net.s_addr = htonl(a->x.ip.net.s_addr);
+ a->x.ip.mask.s_addr = htonl(a->x.ip.mask.s_addr);
}
else {
a->type = T_HOST;
@@ -315,9 +318,9 @@ static int find_allowdeny(request_rec *r, array_header *a, int method)
return 1;
case T_IP:
- if (ap[i].x.ip.net != INADDR_NONE
+ if (ap[i].x.ip.net.s_addr != INADDR_NONE
&& (r->connection->remote_addr.sin_addr.s_addr
- & ap[i].x.ip.mask) == ap[i].x.ip.net) {
+ & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
return 1;
}
break;