www-apache-bugdb mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From John Holden <jo...@psychvax.psych.usyd.edu.au>
Subject Re: mod_access/2079: Enhanced security - Checking IP/hardware address aginst ARP entry in kernel
Date Tue, 21 Apr 1998 02:50:00 GMT
The following reply was made to PR mod_access/2079; it has been noted by GNATS.

From: John Holden <johnh@psychvax.psych.usyd.edu.au>
To: brian@hyperreal.org
Cc: apbugs@Apache.Org
Subject: Re: mod_access/2079: Enhanced security - Checking IP/hardware address aginst ARP
entry in kernel
Date: Tue, 21 Apr 1998 12:47:50 +1000

 > It'd be great if you could hack up a patch for 1.3
 
 I have grafted the required changes to allow for ip/mac address checks in
 V1.3. I have allowed an expanded syntax the mac address :-
 
 	only from 123.123.123 0123456789av
 			or
 	only from 123.123.123 01-23-45-67-89-ab
 			or
 	only from 123.123.123 01:23:45:67:89:ab
 
 There may be more work required for different UNix kernels or Windows, for
 the ARP lookup.
 
 The general .htaccess handling is FAR more efficient that version 1.2.6.
 We mere mortals appreciate the excellent work!
 
 				regards John
 
 diff -c patch follows :-
 :r /user9/t
 
 *** src/modules/standard/OLDmod_access.c	Sat Apr 11 22:00:43 1998
 --- src/modules/standard/mod_access.c	Tue Apr 21 12:23:11 1998
 ***************
 *** 68,78 ****
 --- 68,88 ----
   #include "http_log.h"
   #include "http_request.h"
   
 + #include <sys/file.h>
 + #include <sys/socket.h>
 + #include <sys/ioctl.h>
 +  
 + #include <netdb.h>
 + #include <netinet/in.h>
 + #include <net/if.h>
 + #include <netinet/if_ether.h>
 + 
   enum allowdeny_type {
       T_ENV,
       T_ALL,
       T_IP,
       T_HOST,
 +     T_ONLY,
       T_FAIL
   };
   
 ***************
 *** 84,89 ****
 --- 94,103 ----
   	    unsigned long net;
   	    unsigned long mask;
   	} ip;
 +         struct {
 +             unsigned long ipaddr;
 + 	    unsigned char macaddr[6];
 +         } ip_mac;
       } x;
       enum allowdeny_type type;
   } allowdeny;
 ***************
 *** 143,148 ****
 --- 157,214 ----
       return (*host == '\0');
   }
   
 + /*
 + **	get mac address in 12 digit hex form. Allow :-
 + **	0123456789ab or 01:23:45:67:89:ab or  01-23-45-67-89-ab
 + */
 + 
 + static int cvt_hex (unsigned char *m, const char *mac)
 + {
 +     unsigned int val, bin;
 +     char c;
 +     int c1, c2;
 + 
 +     for(c1 = 0; c1 < 6; c1++)
 +     {
 + 	val = 0;
 + 	for(c2 = 0; c2 < 2; c2++)
 + 	{
 + 		c = *mac++;
 + 		if(c == '-' || c == ':')
 + 			c = *mac++;
 + 		if(isdigit(c))
 + 			bin = c - '0';
 + 		else if(c >= 'a' && c <= 'f')
 + 			bin = c - 'a' + 10;
 + 		else if(c >= 'A' && c <= 'F')
 + 			bin = c - 'A' + 10;
 + 		else
 + 			return 0;
 + 		val = val * 0x10 + bin;
 + 	}
 + 	*m++ = val;
 +     }
 +     return 1;
 + }
 + 		
 + const char *only_cmd (cmd_parms *cmd, void *dv, char *from, char *ip, char *mac)
 + {
 +     access_dir_conf *d = (access_dir_conf *)dv;
 +     allowdeny *a;
 + 
 +     if (strcasecmp (from, "from"))
 +         return "'only' must be followed by 'from'";
 +     a = (allowdeny *)ap_push_array (d->allows);
 +     a->type = T_FAIL;
 +     if(!is_ip(ip) || (a->x.ip_mac.ipaddr = inet_addr(ip)) == -1)
 +         return "'only' must have numeric IP address";
 +     if (!cvt_hex(a->x.ip_mac.macaddr, mac))
 +         return "'only' must have 12 digit hex MAC address";
 +     a->limited = cmd->limited;
 +     a->type = T_ONLY;
 +     return NULL;
 + }
 + 
   static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where)
   {
       access_dir_conf *d = (access_dir_conf *) dv;
 ***************
 *** 263,268 ****
 --- 329,336 ----
        "'allow,deny', 'deny,allow', or 'mutual-failure'"},
       {"allow", allow_cmd, &its_an_allow, OR_LIMIT, ITERATE2,
        "'from' followed by hostnames or IP-address wildcards"},
 +     { "only", only_cmd, NULL, OR_LIMIT, TAKE3,
 +      "'only' followed by IP-address and MAC address" },
       {"deny", allow_cmd, NULL, OR_LIMIT, ITERATE2,
        "'from' followed by hostnames or IP-address wildcards"},
       {NULL}
 ***************
 *** 291,296 ****
 --- 359,406 ----
   	return 0;
   }
   
 + static int match_mac(const unsigned long ip, const unsigned char *mac)
 + {
 + 	struct sockaddr_in *sin;
 + 	struct arpreq ar;
 + 	unsigned char *ptr;
 + 	int s, err;
 + /*
 + **	setup buffer
 + */
 + 	bzero((caddr_t)&ar, sizeof ar);
 + 	ar.arp_pa.sa_family = AF_INET;
 + 	sin = (struct sockaddr_in *)&ar.arp_pa;
 + 	sin->sin_family = AF_INET;
 + 	sin->sin_addr.s_addr = ip;
 + /*
 + **	get a socket and then collect ARP entry
 + */
 + 	if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 + 		return 0;
 + 	err = ioctl(s, SIOCGARP, (caddr_t)&ar);
 + 	close(s);
 + 	if(err < 0)
 + 		return 0;
 + /*
 + **	we may have an address. Is it complete ?
 + */
 + 	if (!(ar.arp_flags & ATF_COM))
 + 		return 0;
 + /*
 + **	try for match
 + */
 + 	ptr = (unsigned char *)ar.arp_ha.sa_data;
 + 
 + 	for(s = 0; s < 5; s++)
 + 	    	if(*ptr++ != *mac++)
 + 			return 0;
 + /*
 + **	A hit!
 + */
 + 	return 1;
 + }
 + 
   static int find_allowdeny(request_rec *r, array_header *a, int method)
   {
       allowdeny *ap = (allowdeny *) a->elts;
 ***************
 *** 320,326 ****
   		return 1;
   	    }
   	    break;
 ! 
   	case T_HOST:
   	    if (!gothost) {
   		remotehost = ap_get_remote_host(r->connection, r->per_dir_config,
 --- 430,440 ----
   		return 1;
   	    }
   	    break;
 ! 	case T_ONLY:
 ! 	    if(r->connection->remote_addr.sin_addr.s_addr == ap[i].x.ip_mac.ipaddr)
 ! 		if(match_mac(ap[i].x.ip_mac.ipaddr, ap[i].x.ip_mac.macaddr))
 ! 		    return 1;
 ! 	    break;
   	case T_HOST:
   	    if (!gothost) {
   		remotehost = ap_get_remote_host(r->connection, r->per_dir_config,

Mime
View raw message