View | Details | Raw Unified | Return to bug 51953
Collapse All | Expand All

(-)a/java/org/apache/catalina/valves/RemoteNetmaskValve.java (+86 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 * 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 * 
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
19
package org.apache.catalina.valves;
20
21
22
import org.apache.catalina.connector.Request;
23
import org.apache.catalina.connector.Response;
24
25
import javax.servlet.ServletException;
26
import java.io.IOException;
27
28
29
/**
30
 * Concrete implementation of <code>RequestFilterValve</code> that filters
31
 * based on the string representation of the remote client's IP address.
32
 *
33
 * @author Craig R. McClanahan
34
 * @version $Id$
35
 */
36
37
public final class RemoteNetmaskValve
38
    extends RequestNetmaskValve
39
{
40
41
42
    // ----------------------------------------------------- Instance Variables
43
44
45
    /**
46
     * The descriptive information related to this implementation.
47
     */
48
    private static final String info =
49
        "org.apache.catalina.valves.RemoteNetmaskValve/1.0";
50
51
52
    // ------------------------------------------------------------- Properties
53
54
55
    /**
56
     * Return descriptive information about this Valve implementation.
57
     */
58
    @Override
59
    public String getInfo() {
60
        return (info);
61
    }
62
63
64
    // --------------------------------------------------------- Public Methods
65
66
67
    /**
68
     * Extract the desired request property, and pass it (along with the
69
     * specified request and response objects) to the protected
70
     * <code>process()</code> method to perform the actual filtering.
71
     * This method must be implemented by a concrete subclass.
72
     *
73
     * @param request The servlet request to be processed
74
     * @param response The servlet response to be created
75
     *
76
     * @exception java.io.IOException if an input/output error occurs
77
     * @exception javax.servlet.ServletException if a servlet error occurs
78
     */
79
    @Override
80
    public void invoke(Request request, Response response)
81
        throws IOException, ServletException {
82
        process(request.getRequest().getRemoteAddr(), request, response);
83
    }
84
85
86
}
(-)a/java/org/apache/catalina/valves/RequestNetmaskValve.java (-1 / +220 lines)
Line 0 Link Here
0
- 
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 * 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
10
 * 
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
19
package org.apache.catalina.valves;
20
21
22
import org.apache.catalina.connector.Request;
23
import org.apache.catalina.connector.Response;
24
import org.apache.catalina.util.NetMask;
25
26
import javax.servlet.ServletException;
27
import javax.servlet.http.HttpServletResponse;
28
import java.io.IOException;
29
import java.math.BigInteger;
30
import java.net.InetAddress;
31
import java.net.UnknownHostException;
32
import java.util.ArrayList;
33
import java.util.Arrays;
34
import java.util.Collections;
35
import java.util.List;
36
37
/**
38
 * Implementation of a Valve that performs IP filtering of a remote host
39
 * based on the remote's IP address. This valve replicates (some of) Apache's
40
 * "Order", "Allow from" and "Deny" directives with a few limitations:
41
 * <ul>
42
 *     <li>"Order" will always be "deny, allow";</li>
43
 *     <li>the netmasks in the "allow" and "deny" properties must be fully
44
 *     qualified CIDR netmasks, and the CIDR <b>must</b> be an integer
45
 *     (expressions like "10.", "13.0.0.0/255.255.192.0" or ".foo.bar" will
46
 *     not work);</li>
47
 *     <li>as a side effect of using @{link java.net.InetAddress},
48
 *     expressions like "my.host.com/27" <b>will</b> work,
49
 *     however their use is discouraged.</li>
50
 * </ul>
51
 * <p>Note that IPv6 is supported. Also note that invalid netmasks will be
52
 * ignored.</p>
53
 * <p>
54
 * This Valve may be attached to any Container, depending on the granularity
55
 * of the filtering you wish to perform.</p>
56
 *
57
 * @author Francis Galiegue
58
 */
59
60
public abstract class RequestNetmaskValve
61
    extends ValveBase {
62
63
    //------------------------------------------------------ Constructor
64
    public RequestNetmaskValve() {
65
        super(true);
66
    }
67
68
    // ----------------------------------------------------- Class Variables
69
70
71
    /**
72
     * The descriptive information related to this implementation.
73
     */
74
    private static final String info =
75
        "org.apache.catalina.valves.RequestNetmaskValve/1.0";
76
77
    // ----------------------------------------------------- Instance Variables
78
79
    /**
80
     * List of allowed netmasks, if any
81
     */
82
83
    protected final List<NetMask> allow = new ArrayList<NetMask>();
84
85
    /**
86
     * List of denied netmasks, if any
87
     */
88
89
    protected final List<NetMask> deny = new ArrayList<NetMask>();
90
91
    // ------------------------------------------------------------- Properties
92
93
94
    /**
95
     * Return the allowed netmask list as a string.
96
     */
97
    public String getAllow() {
98
        return allow.toString();
99
    }
100
101
102
    /**
103
     * Fills the allowed Netmask list.
104
     *
105
     * @param input The input expression
106
     */
107
    public void setAllow(final String input) {
108
        if (input == null || input.length() == 0)
109
            return;
110
111
        NetMask nm;
112
113
        for (final String s: input.split("\\s*,\\s*"))
114
            try {
115
                nm = new NetMask(s);
116
                this.allow.add(nm);
117
            } catch (IllegalArgumentException e) {
118
                // FIXME: log
119
            }
120
    }
121
122
123
    /**
124
     * Return the denied netmask list as a string.
125
     */
126
    public String getDeny() {
127
        return deny.toString();
128
    }
129
130
131
    /**
132
     * Set the regular expression used to test for denied requests for this
133
     * Valve, if any.
134
     *
135
     * @param input The new input expression
136
     */
137
    public void setDeny(final String input) {
138
       if (input == null || input.length() == 0)
139
           return;
140
141
        NetMask nm;
142
143
        for (final String s: input.split("\\s*,\\s*"))
144
            try {
145
                nm = new NetMask(s);
146
                this.deny.add(nm);
147
            } catch (IllegalArgumentException e) {
148
                // FIXME: log
149
            }
150
    }
151
152
153
    /**
154
     * Return descriptive information about this Valve implementation.
155
     */
156
    @Override
157
    public String getInfo() {
158
        return (info);
159
    }
160
161
162
    // --------------------------------------------------------- Public Methods
163
164
165
    /**
166
     * Extract the desired request property, and pass it (along with the
167
     * specified request and response objects) to the protected
168
     * <code>process()</code> method to perform the actual filtering.
169
     * This method must be implemented by a concrete subclass.
170
     *
171
     * @param request The servlet request to be processed
172
     * @param response The servlet response to be created
173
     *
174
     * @exception java.io.IOException if an input/output error occurs
175
     * @exception javax.servlet.ServletException if a servlet error occurs
176
     */
177
    @Override
178
    public abstract void invoke(Request request, Response response)
179
        throws IOException, ServletException;
180
181
182
    // ------------------------------------------------------ Protected Methods
183
184
185
    /**
186
     * Perform the filtering that has been configured for this Valve, matching
187
     * against the specified request property.
188
     *
189
     * @param property The request property on which to filter
190
     * @param request The servlet request to be processed
191
     * @param response The servlet response to be processed
192
     *
193
     * @exception java.io.IOException if an input/output error occurs
194
     * @exception javax.servlet.ServletException if a servlet error occurs
195
     */
196
    protected void process(String property, Request request, Response response)
197
        throws IOException, ServletException {
198
199
        final InetAddress addr = InetAddress.getByName(property);
200
201
        for (final NetMask nm: deny)
202
            if (nm.matches(addr)) {
203
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
204
                return;
205
            }
206
207
        if (allow.isEmpty()) {
208
            getNext().invoke(request, response);
209
            return;
210
        }
211
212
        for (final NetMask nm: allow)
213
            if (nm.matches(addr)) {
214
                getNext().invoke(request, response);
215
                return;
216
            }
217
218
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
219
    }
220
}

Return to bug 51953