You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Taketo Kabe <ka...@sra-tohoku.co.jp> on 2001/03/14 08:10:34 UTC

mod_access/7407: [PATCH] access control ineffective on IPv6/IPv4 mixed environment (port of PR#7323 for 2.0.14-alpha)

>Number:         7407
>Category:       mod_access
>Synopsis:       [PATCH] access control ineffective on IPv6/IPv4 mixed environment (port of PR#7323 for 2.0.14-alpha)
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    apache
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          duplicate
>Submitter-Id:   apache
>Arrival-Date:   Tue Mar 13 23:20:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     kabe@sra-tohoku.co.jp
>Release:        2.0.14-alpha
>Organization:
apache
>Environment:
SunOS 5.8 Generic_108528-05 sun4u sparc SUNW,Ultra-60
gcc version 2.95.2 19991024 (release)

>Description:
(This is an forward-port of a patch in PR#7232 to 2.0.14-alpha; 
 Jeff is under work including this issue)

If the server accept()ed the client's socket with IPv6-mapped IPv4 address,
the Allow/Deny directives fail to match, rendering most of the
access control ineffective.

This is because
*) IPv6-mapped-IPv4 address has different sockaddr_in format and
   always fails to match with "Allow: IPADDR/MASK" format.
*) For access controls, double-lookups are made (accept()addr->FQDN->addr)
   but nowadays this rarely yields IPv6 address (AAAA record/sockaddr_in6)
   which differs from sockaddr_in, so it never matches.

These cause only "allow all" "deny all" to be effective;
the access control "allow all / deny from.badguys"
allows anyone including badguys.

As commented in modules/aaa/mod_access.c:find_allowdeny(),this is marked
XXX in the comment and looks like an open issue; a good solution
should be adding generic matching func in APR.

>How-To-Repeat:
Configure
* on an OS which accept()s IPv4 connections with IPv6-mapped-IPv4 address
* with IPv6 enabled
* put .htaccess or whatever saying
        order allow,deny
        allow from all
        deny from badguys.domain
  and try getting something there from badguys.domain
  (should be denyed but actually not)

SPARC Solaris 8 falls on this by default.
>Fix:
This patch corrects the problem in hand but should be TEMPORAL/QUIKHACK;
real solutions should be adding generic address parse/match functions
in APR level.

(Hmm, is there a way to configure explicitly disabling IPv6?)

***************************************** IPv6-mod_access.patch
=============================== {{{
diff -u httpd-2_0_14-alpha/modules/aaa/mod_access.c.dist httpd-2_0_14-alpha/modules/aaa/mod_access.c
--- httpd-2_0_14-alpha/modules/aaa/mod_access.c.dist	Fri Feb 16 13:26:34 2001
+++ httpd-2_0_14-alpha/modules/aaa/mod_access.c	Fri Mar  9 06:46:14 2001
@@ -332,10 +332,26 @@
 	case T_IP:
             /* XXX handle IPv6 with separate T_IP6 type or add common 
              *     address masking operations to APR */
-	    if (ap[i].x.ip.net != APR_INADDR_NONE
-		&& (r->connection->remote_addr->sa.sin.sin_addr.s_addr
-		    & ap[i].x.ip.mask) == ap[i].x.ip.net) {
-		return 1;
+	    /* XXX kabe: for now, try match if its's V4 mapped address */
+	    /* XXX yes we should have some generic matching routine */
+	    if (ap[i].x.ip.net == APR_INADDR_NONE)
+		break;
+	    switch (r->connection->remote_addr->sa.sin.sin_family) {
+		case APR_INET:
+		    if ((r->connection->remote_addr->sa.sin.sin_addr.s_addr
+			& ap[i].x.ip.mask) == ap[i].x.ip.net) {
+			return 1;
+		    }
+		    break;
+#if APR_HAVE_IPV6
+		case APR_INET6:
+		    if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)r->connection->remote_addr->ipaddr_ptr)
+			&& ((*(unsigned long*)&r->connection->remote_addr->sa.sin6.sin6_addr.s6_addr[12]
+			    & ap[i].x.ip.mask) == ap[i].x.ip.net)) {
+			return 1;
+		    }
+#endif
+		    break;
 	    }
 	    break;
 
diff -u httpd-2_0_14-alpha/server/core.c.dist httpd-2_0_14-alpha/server/core.c
--- httpd-2_0_14-alpha/server/core.c.dist	Sun Mar  4 15:27:27 2001
+++ httpd-2_0_14-alpha/server/core.c	Fri Mar  9 05:36:34 2001
@@ -600,6 +600,20 @@
                 conn->double_reverse = 1;
                 return;
             }
+#if APR_HAVE_IPV6
+	    /* XXX kabe: match V6-mapped V4 clientaddr with V4 A record */
+	    /* XXX apr_sockaddr_t does not have socket family desc;
+	     *     so had to use sa.sin.sin_family */
+	    if (conn->remote_addr->sa.sin.sin_family == APR_INET6
+		&& IN6_IS_ADDR_V4MAPPED((struct in6_addr *)conn->remote_addr->ipaddr_ptr)
+		&& sa->sa.sin.sin_family == APR_INET
+		&& !memcmp( &((struct in6_addr *)conn->remote_addr->ipaddr_ptr)->s6_addr[12],
+			    sa->ipaddr_ptr,
+			    sizeof (((struct in_addr *)0)->s_addr))) {
+		conn->double_reverse = 1;
+		return;
+	    }
+#endif
             sa = sa->next;
         }
     }
=============================== }

>Release-Note:
>Audit-Trail:
>Unformatted:
 [In order for any reply to be added to the PR database, you need]
 [to include <ap...@Apache.Org> in the Cc line and make sure the]
 [subject line starts with the report component and number, with ]
 [or without any 'Re:' prefixes (such as "general/1098:" or      ]
 ["Re: general/1098:").  If the subject doesn't match this       ]
 [pattern, your message will be misfiled and ignored.  The       ]
 ["apbugs" address is not added to the Cc line of messages from  ]
 [the database automatically because of the potential for mail   ]
 [loops.  If you do not include this Cc, your reply may be ig-   ]
 [nored unless you are responding to an explicit request from a  ]
 [developer.  Reply only with text; DO NOT SEND ATTACHMENTS!     ]
 
 


Re: mod_access/7407: [PATCH] access control ineffective on IPv6/IPv4 mixed environment (port of PR#7323 for 2.0.14-alpha)

Posted by Jeff Trawick <tr...@bellsouth.net>.
Taketo Kabe <ka...@sra-tohoku.co.jp> writes:

> >Number:         7407
> >Category:       mod_access
> >Synopsis:       [PATCH] access control ineffective on IPv6/IPv4 mixed environment (port of PR#7323 for 2.0.14-alpha)

You may wish to look at apr_ipsubnet_create() and
apr_ipsubnet_test(), which have been added to resolve this problem as
well as to add IPv6 address support for mod_access.

A test program for these APIs is in srclib/apr/test/testipsub.c.  The
prototypes are in srclib/apr/include/apr_network_io.h.  The
implementation is in srclib/apr/network_io/unix/sa_common.c.

After some more testing and the addition of more testcases to
testipsub.c I'll commit the changes to mod_access so that it uses the
new APR routines.

I expect to commit your patch to server/core.c as-is.

Thanks for your report,

Jeff

-- 
Jeff Trawick | trawickj@bellsouth.net | PGP public key at web site:
       http://www.geocities.com/SiliconValley/Park/9289/
             Born in Roswell... married an alien...