httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@hyperreal.org>
Subject cvs commit: apache/src CHANGES http_core.c http_core.h http_protocol.c httpd.h mod_access.c
Date Wed, 30 Jul 1997 18:41:58 GMT
dgaudet     97/07/30 11:41:58

  Modified:    htdocs/manual/misc  compat_notes.html
               htdocs/manual/mod  core.html mod_access.html
               src       CHANGES http_core.c http_core.h http_protocol.c
                        httpd.h  mod_access.c
  Log:
  mod_access overhaul.  Network/netmask and CIDR syntax.  Critical path
  speedups.  Forced double-reverse DNS.  Deprecate the "allow from
  user-agents" syntax.  "HostnameLookups double" support.
  
  PR:		762, 860
  Reviewed by:	Paul Sutton, Marc Slemko (well he liked the double reverse part)
  
  Revision  Changes    Path
  1.14      +5 -0      apache/htdocs/manual/misc/compat_notes.html
  
  Index: compat_notes.html
  ===================================================================
  RCS file: /export/home/cvs/apache/htdocs/manual/misc/compat_notes.html,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- compat_notes.html	1997/07/14 03:24:27	1.13
  +++ compat_notes.html	1997/07/30 18:41:44	1.14
  @@ -127,6 +127,11 @@
     <a href="../mod/core.html#errordocument"><code>ErrorDocument</code></a>
     instead.
   
  +  <LI>Apache (as of 1.3) always performs the equivalent of
  +  <CODE>HostnameLookups minimal</CODE>.  <code>minimal</code> is
not an
  +  option to <a href="../mod/core.html#hostnamelookups"><code>
  +  HostnameLookups</code></a>.
  +
   </OL>
   
   More to come when we notice them....
  
  
  
  1.68      +31 -7     apache/htdocs/manual/mod/core.html
  
  Index: core.html
  ===================================================================
  RCS file: /export/home/cvs/apache/htdocs/manual/mod/core.html,v
  retrieving revision 1.67
  retrieving revision 1.68
  diff -u -r1.67 -r1.68
  --- core.html	1997/07/21 21:26:55	1.67
  +++ core.html	1997/07/30 18:41:46	1.68
  @@ -575,16 +575,40 @@
   
   <h2><A name="hostnamelookups">HostNameLookups directive</A></h2>
   <!--%plaintext &lt;?INDEX {\tt HostNameLookups} directive&gt; -->
  -<strong>Syntax:</strong> HostNameLookups <em>boolean</em><br>
  -<strong>Default:</strong> <code>HostNameLookups on</code><br>
  +<strong>Syntax:</strong> HostNameLookups <em>on | off | double</em><br>
  +<strong>Default:</strong> <code>HostNameLookups off</code><br>
   <strong>Context:</strong> server config, virtual host<br>
  -<strong>Status:</strong> core<p>
  +<strong>Status:</strong> core<br>
  +<strong>Compatibility:</strong> <code>double</code> available only
in Apache
  +1.3 and above.<br>
  +<strong>Compatibility:</strong> Default was <code>on</code> prior
to Apache
  +1.3.<p>
   
  -This directive enables DNS lookups so that host names can be logged.
  -Having this directive set <code>on</code> also enables the use of names
  -in &lt;Limit&gt; blocks for access control.<p>
  +This directive enables DNS lookups so that host names can be logged (and
  +passed to CGIs/SSIs in <code>REMOTE_HOST</code>).
  +The value <code>double</code> refers to doing double-reverse DNS.
  +That is, after a reverse lookup is performed, a forward lookup is then
  +performed on that result.  At least one of the ip addresses in the forward
  +lookup must match the original address.  (In "tcpwrappers" terminology
  +this is called <code>PARANOID</code>.)<p>
   
  -Heavily loaded sites should set this directive <code>off</code>, since DNS
  +Regardless of the setting, when <a href="mod_access.html">mod_access</a>
  +is used for controlling access by hostname, a double reverse lookup
  +will be performed.  This is necessary for security.  Note that the
  +result of this double-reverse isn't generally available unless
  +you set <code>HostnameLookups double</code>.  For example, if only
  +<code>HostnameLookups on</code> and a request is made to an object that
  +is protected by hostname restrictions, regardless of whether the
  +double-reverse fails or not, CGIs will still be passed the single-reverse
  +result in <code>REMOTE_HOST</code>.<p>
  +
  +The default for this directive was previously <code>on</code> in
  +versions of Apache prior to 1.3.  It was changed to <code>off</code>
  +in order to save the network traffic for those sites that don't truly
  +need the reverse lookups done.  It is also better for the end users
  +because they don't have to suffer the extra latency that a lookup
  +entails.
  +Heavily loaded sites should leave this directive <code>off</code>, since DNS
   lookups can take considerable amounts of time. The utility <i>logresolve</i>,
   provided in the <i>/support</i> directory, can be used to look up host names
   from logged IP addresses offline.<p><hr>
  
  
  
  1.10      +12 -0     apache/htdocs/manual/mod/mod_access.html
  
  Index: mod_access.html
  ===================================================================
  RCS file: /export/home/cvs/apache/htdocs/manual/mod/mod_access.html,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- mod_access.html	1997/07/06 17:19:14	1.9
  +++ mod_access.html	1997/07/30 18:41:47	1.10
  @@ -53,6 +53,12 @@
   <dd>An IP address of a host allowed access
   <dt>A partial IP address
   <dd>The first 1 to 3 bytes of an IP address, for subnet restriction.
  +<dt>A network/netmask pair
  +<dd>A network a.b.c.d, and a netmask w.x.y.z.  For more fine-grained subnet
  +    restriction.  (i.e. 10.1.0.0/255.255.0.0)
  +<dt>A network/nnn CIDR specification
  +<dd>Similar to the previous case, except the netmask consists of nnn 
  +    high-order 1 bits.  (i.e. 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0)
   </dl>
   <P>
   Example:
  @@ -121,6 +127,12 @@
   <dd>An IP address of a host denied access
   <dt>A partial IP address
   <dd>The first 1 to 3 bytes of an IP address, for subnet restriction.
  +<dt>A network/netmask pair
  +<dd>A network a.b.c.d, and a netmask w.x.y.z.  For more fine-grained subnet
  +    restriction.  (i.e. 10.1.0.0/255.255.0.0)
  +<dt>A network/nnn CIDR specification
  +<dd>Similar to the previous case, except the netmask consists of nnn 
  +    high-order 1 bits.  (i.e. 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0)
   </dl>
   <P>
   Example:
  
  
  
  1.372     +17 -0     apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.371
  retrieving revision 1.372
  diff -u -r1.371 -r1.372
  --- CHANGES	1997/07/29 06:52:25	1.371
  +++ CHANGES	1997/07/30 18:41:50	1.372
  @@ -1,5 +1,22 @@
   Changes with Apache 1.3a2
   
  +  *) "HostnameLookups double" forces double-reverse DNS to succeed.
  +     The old define MAXIMUM_DNS has been deprecated.  [Dean Gaudet]
  +
  +  *) mod_access overhaul:
  +     - Now understands network/netmask syntax (i.e.  10.1.0.0/255.255.0.0)
  +	and cidr syntax (i.e. 10.1.0.0/16).  PR#762
  +     - Critical path was sped up by pre-computing a few things at config
  +	time.
  +     - The undocumented syntax "allow user-agents" was removed,
  +	the replacement is "allow from env=foobar" combined with mod_browser.
  +     - When used with hostnames it now forces a double-reverse lookup
  +	no matter what the directory settings are.  This double-reverse
  +	doesn't affect any of the other routines that use the remote
  +	hostname.  In particular it's still passed to CGIs and the log
  +	without the double-reverse check.  Related PR#860.
  +     [Dean Gaudet]
  +
     *) When a large bwrite() occurs (larger than the internal buffer size),
        while there is already something in the buffer, apache will combine
        the large write and the buffer into a single writev().  (This is
  
  
  
  1.102     +62 -30    apache/src/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.c,v
  retrieving revision 1.101
  retrieving revision 1.102
  diff -u -r1.101 -r1.102
  --- http_core.c	1997/07/28 18:22:44	1.101
  +++ http_core.c	1997/07/30 18:41:51	1.102
  @@ -84,7 +84,7 @@
       if (!dir || dir[strlen(dir) - 1] == '/') conf->d = dir;
       else if (strncmp(dir,"proxy:",6)==0) conf->d = pstrdup (a, dir);
       else conf->d = pstrcat (a, dir, "/", NULL);
  -    conf->d_is_matchexp = conf->d ? is_matchexp( conf->d ) : 0;
  +    conf->d_is_matchexp = conf->d ? (is_matchexp( conf->d ) != 0) : 0;
   
   
       conf->opts = dir ? OPT_UNSET : OPT_ALL;
  @@ -93,7 +93,7 @@
   
       conf->content_md5 = 2;
   
  -    conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on" */
  +    conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET;
       conf->do_rfc1413 = DEFAULT_RFC1413 | 2;  /* set bit 1 to indicate default */
       conf->satisfy = SATISFY_NOSPEC;
   
  @@ -155,7 +155,7 @@
   		conf->response_code_strings[i] = new->response_code_strings[i];
   	}
       }
  -    if (new->hostname_lookups != 2)
  +    if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET)
   	conf->hostname_lookups = new->hostname_lookups;
       if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
       if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
  @@ -324,20 +324,46 @@
       return conf->response_code_strings[error_index];
   }
   
  +
  +/* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
  +static void inline do_double_reverse (conn_rec *conn)
  +{
  +    struct hostent *hptr;
  +    char **haddr;
  +
  +    if (conn->double_reverse) {
  +	/* already done */
  +	return;
  +    }
  +    hptr = gethostbyname(conn->remote_host);
  +    if (hptr) {
  +	for (haddr = hptr->h_addr_list; *haddr; haddr++) {
  +	    if (((struct in_addr *)(*haddr))->s_addr
  +		== conn->remote_addr.sin_addr.s_addr) {
  +		break;
  +	    }
  +	}
  +    }
  +    if (!hptr || !*haddr) {
  +	conn->double_reverse = -1;
  +    } else {
  +	conn->double_reverse = 1;
  +    }
  +}
  +
   API_EXPORT(const char *) get_remote_host(conn_rec *conn, void *dir_config, int type)
   {
       struct in_addr *iaddr;
       struct hostent *hptr;
  -#ifdef MAXIMUM_DNS
  -    char **haddr;
  -#endif
       core_dir_config *dir_conf = NULL;
   
   /* If we haven't checked the host name, and we want to */
       if (dir_config) 
   	dir_conf = (core_dir_config *)get_module_config(dir_config, &core_module);
   
  -   if ((!dir_conf) || (type != REMOTE_NOLOOKUP && conn->remote_host == NULL
&& dir_conf->hostname_lookups))
  +   if ((!dir_conf) || (type != REMOTE_NOLOOKUP && conn->remote_host == NULL
  +	&& (type == REMOTE_DOUBLE_REV
  +	    || dir_conf->hostname_lookups != HOSTNAME_LOOKUP_OFF)))
       {
   #ifdef STATUS
   	int old_stat = update_child_status(conn->child_num,
  @@ -346,25 +372,17 @@
   #endif /* STATUS */
   	iaddr = &(conn->remote_addr.sin_addr);
   	hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
  -	if (hptr != NULL)
  -	{
  +	if (hptr != NULL) {
   	    conn->remote_host = pstrdup(conn->pool, (void *)hptr->h_name);
   	    str_tolower (conn->remote_host);
   	   
  -#ifdef MAXIMUM_DNS
  -    /* Grrr. Check THAT name to make sure it's really the name of the addr. */
  -    /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
  -
  -	    hptr = gethostbyname(conn->remote_host);
  -	    if (hptr)
  -	    {
  -		for(haddr=hptr->h_addr_list; *haddr; haddr++)
  -		    if(((struct in_addr *)(*haddr))->s_addr == iaddr->s_addr)
  -			break;
  +	    if (dir_conf
  +		&& dir_conf->hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
  +		do_double_reverse (conn);
  +		if (conn->double_reverse != 1) {
  +		    conn->remote_host = NULL;
  +		}
   	    }
  -	    if((!hptr) || (!(*haddr)))
  -		conn->remote_host = NULL;
  -#endif
   	}
   /* if failed, set it to the NULL string to indicate error */
   	if (conn->remote_host == NULL) conn->remote_host = "";
  @@ -372,6 +390,12 @@
   	(void)update_child_status(conn->child_num,old_stat,(request_rec*)NULL);
   #endif /* STATUS */
       }
  +    if (type == REMOTE_DOUBLE_REV) {
  +	do_double_reverse (conn);
  +	if (conn->double_reverse == -1) {
  +	    return NULL;
  +	}
  +    }
   
   /*
    * Return the desired information; either the remote DNS name, if found,
  @@ -382,7 +406,7 @@
   	return conn->remote_host;
       else
       {
  -	if (type == REMOTE_HOST) return NULL;
  +	if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) return NULL;
   	else return conn->remote_ip;
       }
   }
  @@ -695,7 +719,7 @@
   
       conf = (core_dir_config *)get_module_config(new_url_conf, &core_module);
       conf->d = pstrdup(cmd->pool, cmd->path);	/* No mangling, please */
  -    conf->d_is_matchexp = is_matchexp( conf->d );
  +    conf->d_is_matchexp = is_matchexp( conf->d ) != 0;
       conf->r = r;
   
       add_per_url_conf (cmd->server, new_url_conf);
  @@ -751,7 +775,7 @@
   
       conf = (core_dir_config *)get_module_config(new_file_conf, &core_module);
       conf->d = pstrdup(cmd->pool, cmd->path);
  -    conf->d_is_matchexp = is_matchexp( conf->d );
  +    conf->d_is_matchexp = is_matchexp( conf->d ) != 0;
       conf->r = r;
   
       add_file_conf (c, new_file_conf);
  @@ -985,13 +1009,21 @@
   }
   
   const char *set_idcheck (cmd_parms *cmd, core_dir_config *d, int arg) {
  -    d->do_rfc1413 = arg;
  +    d->do_rfc1413 = arg != 0;
       return NULL;
   }
   
  -const char *set_hostname_lookups (cmd_parms *cmd, core_dir_config *d, int arg)
  +const char *set_hostname_lookups (cmd_parms *cmd, core_dir_config *d, char *arg)
   {
  -    d->hostname_lookups = arg;
  +    if (!strcasecmp (arg, "on")) {
  +	d->hostname_lookups = HOSTNAME_LOOKUP_ON;
  +    } else if (!strcasecmp (arg, "off")) {
  +	d->hostname_lookups = HOSTNAME_LOOKUP_OFF;
  +    } else if (!strcasecmp (arg, "double")) {
  +	d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE;
  +    } else {
  +	return "parameter must be 'on', 'off', or 'double'";
  +    }
       return NULL;
   }
   
  @@ -1002,7 +1034,7 @@
   }
   
   const char *set_content_md5 (cmd_parms *cmd, core_dir_config *d, int arg) {
  -    d->content_md5 = arg;
  +    d->content_md5 = arg != 0;
       return NULL;
   }
   
  @@ -1245,7 +1277,7 @@
   
   { "ServerType", server_type, NULL, RSRC_CONF, TAKE1,"'inetd' or 'standalone'"},
   { "Port", server_port, NULL, RSRC_CONF, TAKE1, "A TCP port number"},
  -{ "HostnameLookups", set_hostname_lookups, NULL, ACCESS_CONF|RSRC_CONF, FLAG, "\"on\" to
enable or \"off\" to disable reverse DNS lookups" },
  +{ "HostnameLookups", set_hostname_lookups, NULL, ACCESS_CONF|RSRC_CONF, TAKE1, "\"on\"
to enable, \"off\" to disable reverse DNS lookups, or \"double\" to enable double-reverse
DNS lookups" },
   { "User", set_user, NULL, RSRC_CONF, TAKE1, "Effective user id for this server"},
   { "Group", set_group, NULL, RSRC_CONF, TAKE1, "Effective group id for this server"},
   { "ServerAdmin", set_server_string_slot,
  
  
  
  1.25      +17 -9     apache/src/http_core.h
  
  Index: http_core.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.h,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- http_core.h	1997/07/16 00:41:21	1.24
  +++ http_core.h	1997/07/30 18:41:51	1.25
  @@ -77,6 +77,7 @@
   #define REMOTE_HOST (0)
   #define REMOTE_NAME (1)
   #define REMOTE_NOLOOKUP (2)
  +#define REMOTE_DOUBLE_REV (3)
   
   #define SATISFY_ALL 0
   #define SATISFY_ANY 1
  @@ -128,12 +129,8 @@
   typedef unsigned char overrides_t;
   
   typedef struct {
  +    /* path of the directory/regex/etc.  see also d_is_matchexp below */
       char *d;
  -    /* since is_matchexp(conf->d) was being called so frequently in
  -     * directory_walk() and its relatives, this field was created and
  -     * is set to the result of that call.
  -     */
  -    int d_is_matchexp;
   
       allow_options_t opts;
       allow_options_t opts_add;
  @@ -154,8 +151,6 @@
       char *auth_name;
       array_header *requires;
   
  -    int content_md5;
  -    
       /* Custom response config. These can contain text or a URL to redirect to.
        * if response_code_strings is NULL then there are none in the config,
        * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES.
  @@ -165,8 +160,21 @@
       char **response_code_strings;
   
       /* Hostname resolution etc */
  -    int hostname_lookups;
  -    int do_rfc1413;   /* See if client is advertising a username? */
  +#define HOSTNAME_LOOKUP_OFF	0
  +#define HOSTNAME_LOOKUP_ON	1
  +#define HOSTNAME_LOOKUP_DOUBLE	2
  +#define HOSTNAME_LOOKUP_UNSET	3
  +    int hostname_lookups : 4;
  +
  +    int do_rfc1413 : 2;   /* See if client is advertising a username? */
  +
  +    int content_md5 : 2;  /* calculate Content-MD5? */
  +
  +    /* since is_matchexp(conf->d) was being called so frequently in
  +     * directory_walk() and its relatives, this field was created and
  +     * is set to the result of that call.
  +     */
  +    int d_is_matchexp : 1;
   
       /* System Resource Control */
   #ifdef RLIMIT_CPU
  
  
  
  1.146     +1 -1      apache/src/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_protocol.c,v
  retrieving revision 1.145
  retrieving revision 1.146
  diff -u -r1.145 -r1.146
  --- http_protocol.c	1997/07/24 04:23:58	1.145
  +++ http_protocol.c	1997/07/30 18:41:52	1.146
  @@ -772,7 +772,7 @@
       r->server = conn->server;
       r->pool = make_sub_pool(conn->pool);
   
  -    conn->keptalive = conn->keepalive;
  +    conn->keptalive = conn->keepalive == 1;
       conn->keepalive = 0;
   
       conn->user = NULL;
  
  
  
  1.135     +6 -3      apache/src/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/httpd.h,v
  retrieving revision 1.134
  retrieving revision 1.135
  diff -u -r1.134 -r1.135
  --- httpd.h	1997/07/27 18:44:05	1.134
  +++ httpd.h	1997/07/30 18:41:53	1.135
  @@ -581,7 +581,6 @@
   
     int child_num;                /* The number of the child handling conn_rec */
     BUFF *client;			/* Connection to the guy */
  -  int aborted;			/* Are we still talking? */
     
     /* Who is the client? */
     
  @@ -602,8 +601,12 @@
   				 */
     char *auth_type;		/* Ditto. */
   
  -  int keepalive;		/* Are we using HTTP Keep-Alive? */
  -  int keptalive;		/* Did we use HTTP Keep-Alive? */
  +  int aborted : 1;		/* Are we still talking? */
  +  int keepalive : 2;		/* Are we using HTTP Keep-Alive?
  +                                 * -1 fatal error, 0 undecided, 1 yes */
  +  int keptalive : 1;		/* Did we use HTTP Keep-Alive? */
  +  int double_reverse : 2;	/* have we done double-reverse DNS?
  +				 * -1 yes/failure, 0 not yet, 1 yes/success */
     int keepalives;		/* How many times have we used it? */
   };
   
  
  
  
  1.22      +136 -49   apache/src/mod_access.c
  
  Index: mod_access.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_access.c,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- mod_access.c	1997/07/28 18:22:48	1.21
  +++ mod_access.c	1997/07/30 18:41:53	1.22
  @@ -63,9 +63,24 @@
   #include "http_log.h"
   #include "http_request.h"
   
  +enum allowdeny_type {
  +    T_ENV,
  +    T_ALL,
  +    T_IP,
  +    T_HOST,
  +    T_FAIL
  +};
  +
   typedef struct {
  -    char *from;
       int limited;
  +    union {
  +	char *from;
  +	struct {
  +	    unsigned long net;
  +	    unsigned long mask;
  +	} ip;
  +    } x;
  +    enum allowdeny_type type;
   } allowdeny;
   
   /* things in the 'order' array */
  @@ -111,17 +126,104 @@
       return NULL;
   }
   
  +static int is_ip(const char *host)
  +{
  +    while ((*host == '.') || isdigit(*host))
  +        host++;
  +    return (*host == '\0');
  +}
  +
   static const char *allow_cmd (cmd_parms *cmd, void *dv, char *from, char *where)
   {
       access_dir_conf *d = (access_dir_conf *)dv;
       allowdeny *a;
  +    char *s;
     
       if (strcasecmp (from, "from"))
           return "allow and deny must be followed by 'from'";
       
       a = (allowdeny *)push_array (cmd->info ? d->allows : d->denys);
  -    a->from = pstrdup (cmd->pool, where);
  +    a->x.from = where = pstrdup (cmd->pool, where);
       a->limited = cmd->limited;
  +    
  +    if (!strncmp (where, "env=", 4)) {
  +	a->type = T_ENV;
  +	a->x.from += 4;
  +
  +    } else if (!strcmp (where, "all")) {
  +	a->type = T_ALL;
  +
  +    } else if ((s = strchr (where, '/'))) {
  +	unsigned long 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->type = T_FAIL;
  +	    return "syntax error in network portion of network/netmask";
  +	}
  +
  +	/* is_ip just tests if it matches [\d.]+ */
  +	if (!is_ip (s)) {
  +	    a->type = T_FAIL;
  +	    return "syntax error in mask portion of network/netmask";
  +	}
  +	/* is it in /a.b.c.d form? */
  +	if (strchr (s, '.')) {
  +	    mask = ap_inet_addr (s);
  +	    if (mask == INADDR_NONE) {
  +		a->type = T_FAIL;
  +		return "syntax error in mask portion of network/netmask";
  +	    }
  +	} else {
  +	    /* assume it's in /nnn form */
  +	    mask = atoi (s);
  +	    if (mask > 32 || mask <= 0) {
  +		a->type = T_FAIL;
  +		return "invalid mask in network/netmask";
  +	    }
  +	    mask = 0xFFFFFFFFUL << (32 - mask);
  +	    mask = htonl (mask);
  +	}
  +	a->x.ip.mask = mask;
  +
  +    } else if (isdigit (*where) && is_ip (where)) {
  +	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
  +	int shift;
  +	char *t;
  +
  +	a->type = T_IP;
  +	/* parse components */
  +	s = where;
  +	a->x.ip.net = 0;
  +	shift = 0;
  +	while (*s) {
  +	    t = s;
  +	    if (!isdigit (*t)) {
  +		a->type = T_FAIL;
  +		return "invalid ip address";
  +	    }
  +	    while (isdigit (*t)) {
  +		++t;
  +	    }
  +	    if (*t == '.') {
  +		*t++ = 0;
  +	    } else if (*t) {
  +		a->type = T_FAIL;
  +		return "invalid ip address";
  +	    }
  +	    a->x.ip.net |= atoi(s) << shift;
  +	    a->x.ip.mask |= 0xFFUL << shift;
  +	    shift += 8;
  +	    s = t;
  +	}
  +    } else {
  +	a->type = T_HOST;
  +    }
  +
       return NULL;
   }
   
  @@ -155,25 +257,6 @@
           return 0;
   }
   
  -static int in_ip(char *domain, char *what) {
  -
  -    /* Check a similar screw case to the one checked above ---
  -     * "allow from 204.26.2" shouldn't let in people from 204.26.23
  -     */
  -    
  -    int l = strlen(domain);
  -    if (strncmp(domain,what,l) != 0) return 0;
  -    if (domain[l - 1] == '.') return 1;
  -    return (what[l] == '\0' || what[l] == '.');
  -}
  -
  -static int is_ip(const char *host)
  -{
  -    while ((*host == '.') || isdigit(*host))
  -        host++;
  -    return (*host == '\0');
  -}
  -
   static int find_allowdeny (request_rec *r, array_header *a, int method)
   {
       allowdeny *ap = (allowdeny *)a->elts;
  @@ -186,39 +269,43 @@
           if (!(mmask & ap[i].limited))
   	    continue;
   
  -	if (!strncmp(ap[i].from,"env=",4) && table_get(r->subprocess_env,ap[i].from+4))
  +	switch (ap[i].type) {
  +	case T_ENV:
  +	    if (table_get (r->subprocess_env, ap[i].x.from)) {
  +		return 1;
  +	    }
  +	    break;
  +
  +	case T_ALL:
   	    return 1;
  -	    
  -        if (ap[i].from && !strcmp(ap[i].from, "user-agents")) {
  -	    char * this_agent = table_get(r->headers_in, "User-Agent");
  -	    int j;
  -  
  -	    if (!this_agent) return 0;
  -  
  -	    for (j = i+1; j < a->nelts; ++j) {
  -	        if (strstr(this_agent, ap[j].from)) return 1;
  +
  +	case T_IP:
  +	    if (ap[i].x.ip.net != INADDR_NONE
  +		&& (r->connection->remote_addr.sin_addr.s_addr
  +		    & ap[i].x.ip.mask) == ap[i].x.ip.net) {
  +		return 1;
   	    }
  -	    return 0;
  -	}
  +	    break;
   	
  -	if (!strcmp (ap[i].from, "all"))
  -	    return 1;
  +	case T_HOST:
  +	    if (!gothost) {
  +		remotehost = get_remote_host(r->connection, r->per_dir_config,
  +					    REMOTE_DOUBLE_REV);
  +
  +		if ((remotehost == NULL) || is_ip(remotehost))
  +		    gothost = 1;
  +		else
  +		    gothost = 2;
  +	    }
   
  -	if (!gothost) {
  -	    remotehost = get_remote_host(r->connection, r->per_dir_config,
  -	                                 REMOTE_HOST);
  -
  -	    if ((remotehost == NULL) || is_ip(remotehost))
  -	        gothost = 1;
  -	    else
  -	        gothost = 2;
  +	    if ((gothost == 2) && in_domain(ap[i].x.from, remotehost))
  +		return 1;
  +	    break;
  +
  +	case T_FAIL:
  +	    /* do nothing? */
  +	    break;
   	}
  -
  -        if ((gothost == 2) && in_domain(ap[i].from, remotehost))
  -            return 1;
  -
  -        if (in_ip (ap[i].from, r->connection->remote_ip))
  -            return 1;
       }
   
       return 0;
  
  
  

Mime
View raw message