You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/05/24 19:41:06 UTC

svn commit: r1832193 - in /tomcat/trunk: java/org/apache/catalina/filters/ java/org/apache/catalina/valves/ webapps/docs/ webapps/docs/config/

Author: markt
Date: Thu May 24 19:41:06 2018
New Revision: 1832193

URL: http://svn.apache.org/viewvc?rev=1832193&view=rev
Log:
Add the RemoteCIDRFilter and RemoteCIDRValve that can be used to allow/deny requests based on IPv4 and/or IPv6 client address where the IP ranges are defined using CIDR notation.
Based on a patch by Francis Galiegue.

Added:
    tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java   (with props)
    tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties
    tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties
    tomcat/trunk/webapps/docs/changelog.xml
    tomcat/trunk/webapps/docs/config/filter.xml
    tomcat/trunk/webapps/docs/config/valve.xml

Modified: tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties?rev=1832193&r1=1832192&r2=1832193&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/filters/LocalStrings.properties Thu May 24 19:41:06 2018
@@ -49,6 +49,9 @@ expiresFilter.invalidDurationUnit=Invali
 httpHeaderSecurityFilter.committed=Unable to add HTTP headers since response is already committed on entry to the HTTP header security Filter
 httpHeaderSecurityFilter.clickjack.invalid=An invalid value [{0}] was specified for the anti click-jacking header
 
+remoteCidrFilter.invalid=Invalid configuration provided for [{0}]. See previous messages for details.
+remoteCidrFilter.noRemoteIp=Client does not have an IP address. Request denied.
+
 requestFilter.deny=Denied request for [{0}] based on property [{1}]
 
 restCsrfPreventionFilter.invalidNonce=CSRF nonce validation failed
\ No newline at end of file

Added: tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java?rev=1832193&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java (added)
+++ tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java Thu May 24 19:41:06 2018
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.filters;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.util.NetMask;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public final class RemoteCIDRFilter extends FilterBase {
+
+    /**
+     * text/plain MIME type: this is the MIME type we return when a
+     * {@link ServletResponse} is not an {@link HttpServletResponse}
+     */
+    private static final String PLAIN_TEXT_MIME_TYPE = "text/plain";
+
+    /**
+     * Our logger
+     */
+    private final Log log = LogFactory.getLog(RemoteCIDRFilter.class);
+
+    /**
+     * The list of allowed {@link NetMask}s
+     */
+    private final List<NetMask> allow = new ArrayList<>();
+
+    /**
+     * The list of denied {@link NetMask}s
+     */
+    private final List<NetMask> deny = new ArrayList<>();
+
+
+    /**
+     * Return a string representation of the {@link NetMask} list in #allow.
+     *
+     * @return the #allow list as a string, without the leading '[' and trailing
+     *         ']'
+     */
+    public String getAllow() {
+        return allow.toString().replace("[", "").replace("]", "");
+    }
+
+
+    /**
+     * Fill the #allow list with the list of netmasks provided as an argument,
+     * if any. Calls #fillFromInput.
+     *
+     * @param input The list of netmasks, as a comma separated string
+     * @throws IllegalArgumentException One or more netmasks are invalid
+     */
+    public void setAllow(final String input) {
+        final List<String> messages = fillFromInput(input, allow);
+
+        if (messages.isEmpty()) {
+            return;
+        }
+
+        for (final String message : messages) {
+            log.error(message);
+        }
+
+        throw new IllegalArgumentException(sm.getString("remoteCidrFilter.invalid", "allow"));
+    }
+
+
+    /**
+     * Return a string representation of the {@link NetMask} list in #deny.
+     *
+     * @return the #deny list as string, without the leading '[' and trailing
+     *         ']'
+     */
+    public String getDeny() {
+        return deny.toString().replace("[", "").replace("]", "");
+    }
+
+
+    /**
+     * Fill the #deny list with the list of netmasks provided as an argument, if
+     * any. Calls #fillFromInput.
+     *
+     * @param input The list of netmasks, as a comma separated string
+     * @throws IllegalArgumentException One or more netmasks are invalid
+     */
+    public void setDeny(final String input) {
+        final List<String> messages = fillFromInput(input, deny);
+
+        if (messages.isEmpty())
+            return;
+
+        for (final String message : messages) {
+            log.error(message);
+        }
+
+        throw new IllegalArgumentException(sm.getString("remoteCidrFilter.invalid", "deny"));
+    }
+
+
+
+    @Override
+    protected boolean isConfigProblemFatal() {
+        // Failure to configure a security related component should always be
+        // fatal.
+        return true;
+    }
+
+
+    @Override
+    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
+            throws IOException, ServletException {
+
+        if (isAllowed(request.getRemoteAddr())) {
+            chain.doFilter(request, response);
+            return;
+        }
+
+        if (!(response instanceof HttpServletResponse)) {
+            sendErrorWhenNotHttp(response);
+            return;
+        }
+
+        ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN);
+    }
+
+
+    @Override
+    public Log getLogger() {
+        return log;
+    }
+
+
+    /**
+     * Test if a remote's IP address is allowed to proceed.
+     *
+     * @param property The remote's IP address, as a string
+     * @return true if allowed
+     */
+    private boolean isAllowed(final String property) {
+        final InetAddress addr;
+
+        try {
+            addr = InetAddress.getByName(property);
+        } catch (UnknownHostException e) {
+            // This should be in the 'could never happen' category but handle it
+            // to be safe.
+            log.error(sm.getString("remoteCidrFilter.noRemoteIp"), e);
+            return false;
+        }
+
+        for (final NetMask nm : deny) {
+            if (nm.matches(addr)) {
+                return false;
+            }
+        }
+
+        for (final NetMask nm : allow) {
+            if (nm.matches(addr)) {
+                return true;
+            }
+        }
+
+        // Allow if deny is specified but allow isn't
+        if (!deny.isEmpty() && allow.isEmpty()) {
+            return true;
+        }
+
+        // Deny this request
+        return false;
+    }
+
+
+    private void sendErrorWhenNotHttp(ServletResponse response) throws IOException {
+        final PrintWriter writer = response.getWriter();
+        response.setContentType(PLAIN_TEXT_MIME_TYPE);
+        writer.write(sm.getString("http.403"));
+        writer.flush();
+    }
+
+
+    /**
+     * Fill a {@link NetMask} list from a string input containing a
+     * comma-separated list of (hopefully valid) {@link NetMask}s.
+     *
+     * @param input The input string
+     * @param target The list to fill
+     * @return a string list of processing errors (empty when no errors)
+     */
+    private List<String> fillFromInput(final String input, final List<NetMask> target) {
+        target.clear();
+        if (input == null || input.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        final List<String> messages = new LinkedList<>();
+        NetMask nm;
+
+        for (final String s : input.split("\\s*,\\s*")) {
+            try {
+                nm = new NetMask(s);
+                target.add(nm);
+            } catch (IllegalArgumentException e) {
+                messages.add(s + ": " + e.getMessage());
+            }
+        }
+
+        return Collections.unmodifiableList(messages);
+    }
+}

Propchange: tomcat/trunk/java/org/apache/catalina/filters/RemoteCIDRFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties?rev=1832193&r1=1832192&r2=1832193&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties (original)
+++ tomcat/trunk/java/org/apache/catalina/valves/LocalStrings.properties Thu May 24 19:41:06 2018
@@ -47,6 +47,9 @@ errorReportValve.noDescription=No descri
 errorReportValve.errorPageIOException=Unable to display error page at [{0}] due to an exception
 errorReportValve.errorPageNotFound=Unable to find a static error page at [{0}]
 
+remoteCidrValve.invalid=Invalid configuration provided for [{0}]. See previous messages for details.
+remoteCidrValve.noRemoteIp=Client does not have an IP address. Request denied.
+
 # Remote IP valve
 remoteIpValve.invalidPortHeader=Invalid value [{0}] found for port in HTTP header [{1}]
 

Added: tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java?rev=1832193&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java (added)
+++ tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java Thu May 24 19:41:06 2018
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.valves;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.util.NetMask;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+public final class RemoteCIDRValve extends ValveBase {
+
+    /**
+     * Our logger
+     */
+    private static final Log log = LogFactory.getLog(RemoteCIDRValve.class);
+
+    /**
+     * The list of allowed {@link NetMask}s
+     */
+    private final List<NetMask> allow = new ArrayList<>();
+
+    /**
+     * The list of denied {@link NetMask}s
+     */
+    private final List<NetMask> deny = new ArrayList<>();
+
+
+    public RemoteCIDRValve() {
+        super(true);
+    }
+
+
+    /**
+     * Return a string representation of the {@link NetMask} list in #allow.
+     *
+     * @return the #allow list as a string, without the leading '[' and trailing
+     *         ']'
+     */
+    public String getAllow() {
+        return allow.toString().replace("[", "").replace("]", "");
+    }
+
+
+    /**
+     * Fill the #allow list with the list of netmasks provided as an argument,
+     * if any. Calls #fillFromInput.
+     *
+     * @param input The list of netmasks, as a comma separated string
+     * @throws IllegalArgumentException One or more netmasks are invalid
+     */
+    public void setAllow(final String input) {
+        final List<String> messages = fillFromInput(input, allow);
+
+        if (messages.isEmpty()) {
+            return;
+        }
+
+        for (final String message : messages) {
+            log.error(message);
+        }
+
+        throw new IllegalArgumentException(sm.getString("remoteCidrValve.invalid", "allow"));
+    }
+
+
+    /**
+     * Return a string representation of the {@link NetMask} list in #deny.
+     *
+     * @return the #deny list as a string, without the leading '[' and trailing
+     *         ']'
+     */
+    public String getDeny() {
+        return deny.toString().replace("[", "").replace("]", "");
+    }
+
+
+    /**
+     * Fill the #deny list with the list of netmasks provided as an argument, if
+     * any. Calls #fillFromInput.
+     *
+     * @param input The list of netmasks, as a comma separated string
+     * @throws IllegalArgumentException One or more netmasks are invalid
+     */
+
+    public void setDeny(final String input) {
+        final List<String> messages = fillFromInput(input, deny);
+
+        if (messages.isEmpty()) {
+            return;
+        }
+
+        for (final String message : messages) {
+            log.error(message);
+        }
+
+        throw new IllegalArgumentException(sm.getString("remoteCidrValve.invalid", "deny"));
+    }
+
+
+    @Override
+    public void invoke(final Request request, final Response response) throws IOException, ServletException {
+
+        if (isAllowed(request.getRequest().getRemoteAddr())) {
+            getNext().invoke(request, response);
+        } else {
+            response.sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+    }
+
+    private boolean isAllowed(final String property) {
+        final InetAddress addr;
+
+        try {
+            addr = InetAddress.getByName(property);
+        } catch (UnknownHostException e) {
+            // This should be in the 'could never happen' category but handle it
+            // to be safe.
+            log.error(sm.getString("remoteCidrValve.noRemoteIp"), e);
+            return false;
+        }
+
+        for (final NetMask nm : deny) {
+            if (nm.matches(addr)) {
+                return false;
+            }
+        }
+
+        for (final NetMask nm : allow) {
+            if (nm.matches(addr)) {
+                return true;
+            }
+        }
+
+        // Allow if deny is specified but allow isn't
+        if (!deny.isEmpty() && allow.isEmpty()) {
+            return true;
+        }
+
+        // Deny this request
+        return false;
+    }
+
+
+    /**
+     * Fill a {@link NetMask} list from a string input containing a
+     * comma-separated list of (hopefully valid) {@link NetMask}s.
+     *
+     * @param input The input string
+     * @param target The list to fill
+     * @return a string list of processing errors (empty when no errors)
+     */
+
+    private List<String> fillFromInput(final String input, final List<NetMask> target) {
+        target.clear();
+        if (input == null || input.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        final List<String> messages = new LinkedList<>();
+        NetMask nm;
+
+        for (final String s : input.split("\\s*,\\s*")) {
+            try {
+                nm = new NetMask(s);
+                target.add(nm);
+            } catch (IllegalArgumentException e) {
+                messages.add(s + ": " + e.getMessage());
+            }
+        }
+
+        return Collections.unmodifiableList(messages);
+    }
+}

Propchange: tomcat/trunk/java/org/apache/catalina/valves/RemoteCIDRValve.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1832193&r1=1832192&r2=1832193&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu May 24 19:41:06 2018
@@ -97,6 +97,12 @@
         <code>AccessLogValve</code> that causes IPv6 addresses to be output in
         canonical form defined by RFC 5952. (ognjen/markt)
       </add>
+      <add>
+        <bug>51953</bug>: Add the <code>RemoteCIDRFilter</code> and
+        <code>RemoteCIDRValve</code> that can be used to allow/deny requests
+        based on IPv4 and/or IPv6 client address where the IP ranges are defined
+        using CIDR notation. Based on a patch by Francis Galiegue. (markt)
+      </add>
       <fix>
         <bug>62343</bug>: Make CORS filter defaults more secure. This is the fix
         for CVE-2018-8014. (markt)

Modified: tomcat/trunk/webapps/docs/config/filter.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=1832193&r1=1832192&r2=1832193&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/filter.xml (original)
+++ tomcat/trunk/webapps/docs/config/filter.xml Thu May 24 19:41:06 2018
@@ -1100,6 +1100,108 @@ FINE: Request "/docs/config/manager.html
 
 </section>
 
+<section name="Remote CIDR Filter">
+
+  <subsection name="Introduction">
+
+    <p>The <strong>Remote CIDR Filter</strong> allows you to compare the
+      IP address of the client that submitted this request against one or more
+      netmasks following the CIDR notation, and either allow the request to
+      continue or refuse to process the request from this client. IPv4 and
+      IPv6 are both fully supported.
+    </p>
+
+    <p>This filter mimicks Apache httpd's <code>Order</code>,
+      <code>Allow from</code> and <code>Deny from</code> directives,
+      with the following limitations:
+    </p>
+
+    <ul>
+      <li><code>Order</code> will always be <code>allow, deny</code>;</li>
+      <li>dotted quad notations for netmasks are not supported (that is, you
+        cannot write <code>192.168.1.0/255.255.255.0</code>, you must write
+        <code>192.168.1.0/24</code>;
+      </li>
+      <li>shortcuts, like <code>10.10.</code>, which is equivalent to
+        <code>10.10.0.0/16</code>, are not supported;
+      </li>
+      <li>as the filter name says, this is a CIDR only filter,
+        therefore subdomain notations like <code>.mydomain.com</code> are not
+        supported either.
+      </li>
+    </ul>
+
+    <p>Some more features of this filter are:
+    </p>
+
+    <ul>
+      <li>if you omit the CIDR prefix, this filter becomes a single IP
+      filter;</li>
+      <li>unlike the <a href="#Remote_Host_Filter">Remote Host Filter</a>,
+      it can handle IPv6 addresses in condensed form (<code>::1</code>,
+      <code>fe80::/71</code>, etc).</li>
+    </ul>
+
+  </subsection>
+
+  <subsection name="Filter Class Name">
+
+    <p>The filter class name for the Remote Address Filter is
+      <strong><code>org.apache.catalina.filters.RemoteCIDRFilter</code>
+      </strong>.</p>
+
+  </subsection>
+
+  <subsection name="Initialisation parameters">
+
+    <p>The <strong>Remote CIDR Filter</strong> supports the following
+      initialisation parameters:</p>
+
+    <attributes>
+
+      <attribute name="allow" required="false">
+        <p>A comma-separated list of IPv4 or IPv6 netmasks or addresses
+          that the remote client&apos;s IP address is matched against.
+          If this attribute is specified, the remote address MUST match
+          for this request to be accepted. If this attribute is not specified,
+          all requests will be accepted UNLESS the remote IP is matched by a
+          netmask in the <code>deny</code> attribute.
+        </p>
+      </attribute>
+
+      <attribute name="deny" required="false">
+        <p>A comma-separated list of IPv4 or IPv6 netmasks or addresses
+          that the remote client&apos;s IP address is matched against.
+          If this attribute is specified, the remote address MUST NOT match
+          for this request to be accepted. If this attribute is not specified,
+          request acceptance is governed solely by the <code>accept</code>
+          attribute.
+        </p>
+      </attribute>
+
+    </attributes>
+
+  </subsection>
+
+  <subsection name="Example">
+    <p>To allow access only for the clients connecting from localhost:</p>
+    <pre>
+      &lt;filter>
+      &lt;filter-name>Remote CIDR Filter&lt;/filter-name>
+      &lt;filter-class>org.apache.catalina.filters.RemoteCIDRFilter&lt;/filter-class>
+      &lt;init-param>
+      &lt;param-name>allow&lt;/param-name>
+      &lt;param-value>127.0.0.0/8, ::1&lt;/param-value>
+      &lt;/init-param>
+      &lt;/filter>
+      &lt;filter-mapping>
+      &lt;filter-name>Remote CIDR Filter&lt;/filter-name>
+      &lt;url-pattern>/*&lt;/url-pattern>
+      &lt;/filter-mapping>
+    </pre>
+  </subsection>
+
+</section>
 
 <section name="Remote IP Filter">
 

Modified: tomcat/trunk/webapps/docs/config/valve.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=1832193&r1=1832192&r2=1832193&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/valve.xml (original)
+++ tomcat/trunk/webapps/docs/config/valve.xml Thu May 24 19:41:06 2018
@@ -647,7 +647,7 @@
     header. This is useful in combination with the context attribute
     <code>preemptiveAuthentication="true"</code>.</p>
 
-    <p><strong>Note:</strong> This filter processes the value returned by
+    <p><strong>Note:</strong> This valve processes the value returned by
     method <code>ServletRequest.getRemoteHost()</code>. To allow the method
     to return proper host names, you have to enable "DNS lookups" feature on
     a <strong>Connector</strong>.</p>
@@ -718,6 +718,100 @@
 
 </subsection>
 
+<subsection name="Remote CIDR Valve">
+
+  <subsection name="Introduction">
+
+    <p>The <strong>Remote CIDR Valve</strong> allows you to compare the
+      IP address of the client that submitted this request against one or more
+      netmasks following the CIDR notation, and either allow the request to
+      continue or refuse to process the request from this client. IPv4 and
+      IPv6 are both fully supported. A Remote CIDR Valve can be associated
+      with any Catalina container (<a href="engine.html">Engine</a>,
+      <a href="host.html">Host</a>, or <a href="context.html">Context</a>), and
+      must accept any request presented to this container for processing before
+      it will be passed on.
+    </p>
+
+    <p>This valve mimicks Apache's <code>Order</code>,
+      <code>Allow from</code> and <code>Deny from</code> directives,
+      with the following limitations:
+    </p>
+
+    <ul>
+      <li><code>Order</code> will always be <code>allow, deny</code>;</li>
+      <li>dotted quad notations for netmasks are not supported (that is, you
+        cannot write <code>192.168.1.0/255.255.255.0</code>, you must write
+        <code>192.168.1.0/24</code>;
+      </li>
+      <li>shortcuts, like <code>10.10.</code>, which is equivalent to
+        <code>10.10.0.0/16</code>, are not supported;
+      </li>
+      <li>as the valve name says, this is a CIDR only valve,
+        therefore subdomain notations like <code>.mydomain.com</code> are not
+        supported either.
+      </li>
+    </ul>
+
+    <p>Some more features of this valve are:
+    </p>
+
+    <ul>
+      <li>if you omit the CIDR prefix, this valve becomes a single IP
+        valve;</li>
+      <li>unlike the <a href="#Remote_Host_Valve">Remote Host Valve</a>,
+      it can handle IPv6 addresses in condensed form (<code>::1</code>,
+      <code>fe80::/71</code>, etc).</li>
+    </ul>
+
+  </subsection>
+
+  <subsection name="Attributes">
+
+    <p>The <strong>Remote CIDR Valve</strong> supports the following
+      configuration attributes:</p>
+
+    <attributes>
+
+      <attribute name="className" required="true">
+        <p>Java class name of the implementation to use.  This MUST be set to
+          <strong>org.apache.catalina.valves.RemoteCIDRValve</strong>.</p>
+      </attribute>
+
+      <attribute name="allow" required="false">
+        <p>A comma-separated list of IPv4 or IPv6 netmasks or addresses
+          that the remote client&apos;s IP address is matched against.
+          If this attribute is specified, the remote address MUST match
+          for this request to be accepted. If this attribute is not specified,
+          all requests will be accepted UNLESS the remote IP is matched by a
+          netmask in the <code>deny</code> attribute.
+        </p>
+      </attribute>
+
+      <attribute name="deny" required="false">
+        <p>A comma-separated list of IPv4 or IPv6 netmasks or addresses
+          that the remote client&apos;s IP address is matched against.
+          If this attribute is specified, the remote address MUST NOT match
+          for this request to be accepted. If this attribute is not specified,
+          request acceptance is governed solely by the <code>accept</code>
+          attribute.
+        </p>
+      </attribute>
+
+    </attributes>
+
+  </subsection>
+
+  <subsection name="Example">
+    <p>To allow access only for the clients connecting from localhost:</p>
+    <pre>
+      &lt;Valve className="org.apache.catalina.valves.RemoteCIDRValve"
+      allow="127.0.0.1, ::1"/&gt;
+    </pre>
+  </subsection>
+
+</subsection>
+
 
 </section>
 
@@ -1014,7 +1108,6 @@
 
 </section>
 
-
 <section name="Single Sign On Valve">
 
   <subsection name="Introduction">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org