Implemented newly proposed changes to JIRA issue FTPSERVER-357

git-svn-id: https://svn.apache.org/repos/asf/mina/ftpserver/trunk@934935 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
index de22a80..ec50d80 100644
--- a/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
+++ b/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
@@ -19,18 +19,16 @@
 

 package org.apache.ftpserver.config.spring;

 

-import java.net.InetAddress;

 import java.net.UnknownHostException;

 

 import org.apache.ftpserver.DataConnectionConfiguration;

 import org.apache.ftpserver.DataConnectionConfigurationFactory;

 import org.apache.ftpserver.FtpServerConfigurationException;

-import org.apache.ftpserver.ipfilter.DefaultIpFilter;

 import org.apache.ftpserver.ipfilter.IpFilterType;

+import org.apache.ftpserver.ipfilter.RemoteIpFilter;

 import org.apache.ftpserver.listener.ListenerFactory;

 import org.apache.ftpserver.ssl.SslConfiguration;

 import org.apache.ftpserver.ssl.SslConfigurationFactory;

-import org.apache.mina.filter.firewall.Subnet;

 import org.slf4j.Logger;

 import org.slf4j.LoggerFactory;

 import org.springframework.beans.factory.config.BeanDefinition;

@@ -101,29 +99,37 @@
         Element blacklistElm = SpringUtil.getChildElement(element,

                 FtpServerNamespaceHandler.FTPSERVER_NS, "blacklist");

         if (blacklistElm != null) {

-        	LOG.warn("Element 'blacklist' is deprecated, and may be removed in a future release. Please use 'ip-filter' instead. ");

-        	try {

-				DefaultIpFilter ipFilter = new DefaultIpFilter(IpFilterType.DENY, blacklistElm.getTextContent());

-	            factoryBuilder.addPropertyValue("ipFilter", ipFilter);

-			}

-			catch (UnknownHostException e) {

-				throw new IllegalArgumentException("Invalid IP address or subnet in the 'blacklist' element", e);

-			}

+            LOG

+                    .warn("Element 'blacklist' is deprecated, and may be removed in a future release. Please use 'remote-ip-filter' instead. ");

+            try {

+                RemoteIpFilter remoteIpFilter = new RemoteIpFilter(IpFilterType.DENY,

+                        blacklistElm.getTextContent());

+                factoryBuilder.addPropertyValue("sessionFilter", remoteIpFilter);

+            } catch (UnknownHostException e) {

+                throw new IllegalArgumentException(

+                        "Invalid IP address or subnet in the 'blacklist' element",

+                        e);

+            }

         }

-        

-        Element ipFilterElement = SpringUtil.getChildElement(element, FtpServerNamespaceHandler.FTPSERVER_NS, "ip-filter");

-        if(ipFilterElement != null) {

-        	if(blacklistElm != null) {

-        		throw new FtpServerConfigurationException("Element 'ipFilter' may not be used when 'blacklist' element is specified. ");

-        	}

-        	String filterType = ipFilterElement.getAttribute("type");

-        	try {

-				DefaultIpFilter ipFilter = new DefaultIpFilter(IpFilterType.parse(filterType), ipFilterElement.getTextContent());

-	            factoryBuilder.addPropertyValue("ipFilter", ipFilter);

-			}

-			catch (UnknownHostException e) {

-				throw new IllegalArgumentException("Invalid IP address or subnet in the 'ip-filter' element");

-			}

+

+        Element remoteIpFilterElement = SpringUtil.getChildElement(element,

+                FtpServerNamespaceHandler.FTPSERVER_NS, "remote-ip-filter");

+        if (remoteIpFilterElement != null) {

+            if (blacklistElm != null) {

+                throw new FtpServerConfigurationException(

+                        "Element 'remote-ip-filter' may not be used when 'blacklist' element is specified. ");

+            }

+            String filterType = remoteIpFilterElement.getAttribute("type");

+            try {

+                RemoteIpFilter remoteIpFilter = new RemoteIpFilter(IpFilterType

+                        .parse(filterType), remoteIpFilterElement

+                        .getTextContent());

+                factoryBuilder

+                        .addPropertyValue("sessionFilter", remoteIpFilter);

+            } catch (UnknownHostException e) {

+                throw new IllegalArgumentException(

+                        "Invalid IP address or subnet in the 'remote-ip-filter' element");

+            }

         }

         

         BeanDefinition factoryDefinition = factoryBuilder.getBeanDefinition();

diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java
deleted file mode 100644
index 0eb5528..0000000
--- a/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*

- * 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.ftpserver.ipfilter;

-

-import java.net.InetAddress;

-import java.net.UnknownHostException;

-import java.util.Collection;

-import java.util.HashSet;

-import java.util.concurrent.CopyOnWriteArraySet;

-

-import org.apache.mina.filter.firewall.Subnet;

-import org.slf4j.Logger;

-import org.slf4j.LoggerFactory;

-

-/**

- * Default implementation of the <code>IpFilter</code> interface, which uses

- * specific IP addresses or ranges of IP addresses that can be blocked or

- * allowed.

- * 

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- * 

- */

-

-public class DefaultIpFilter extends CopyOnWriteArraySet<Subnet> implements

-	IpFilter {

-

-	/**

-	 * Logger

-	 */

-	Logger LOGGER = LoggerFactory.getLogger(DefaultIpFilter.class);

-

-	/**

-	 * Serial version UID

-	 */

-	private static final long serialVersionUID = 4887092372700628783L;

-

-	/**

-	 * filter type

-	 */

-	private IpFilterType type = null;

-

-	/**

-	 * Creates a new instance of <code>DefaultIpFilter</code>.

-	 * 

-	 * @param type

-	 *            the filter type

-	 */

-	public DefaultIpFilter(IpFilterType type) {

-		this(type, new HashSet<Subnet>(0));

-	}

-

-	/**

-	 * Creates a new instance of <code>DefaultIpFilter</code>.

-	 * 

-	 * @param type

-	 *            the filter type

-	 * @param collection

-	 *            a collection of <code>Subnet</code>s to filter out/in.

-	 */

-	public DefaultIpFilter(IpFilterType type,

-		Collection<? extends Subnet> collection) {

-		super(collection);

-		this.type = type;

-	}

-

-	/**

-	 * Creates a new instance of <code>DefaultIpFilter</code>.

-	 * 

-	 * @param type

-	 *            the filter type

-	 * @param addresses

-	 *            a comma, space, tab, LF separated list of IP addresses/CIDRs.

-	 * @throws UnknownHostException

-	 *             propagated

-	 * @throws NumberFormatException

-	 *             propagated

-	 */

-	public DefaultIpFilter(IpFilterType type, String addresses)

-		throws NumberFormatException, UnknownHostException {

-		super();

-		this.type = type;

-		if (addresses != null) {

-			String[] tokens = addresses.split("[\\s,]+");

-			for (String token : tokens) {

-				if (token.trim().length() > 0) {

-					add(token);

-				}

-			}

-		}

-		if (LOGGER.isDebugEnabled()) {

-			LOGGER.debug(

-				"Created DefaultIpFilter of type {} with the subnets {}", type,

-				this);

-		}

-	}

-

-	/**

-	 * Returns the type of this filter.

-	 * 

-	 * @return the type of this filter.

-	 */

-	public IpFilterType getType() {

-		return type;

-	}

-

-	/**

-	 * Sets the type of this filter.

-	 * 

-	 * @param type

-	 *            the type of this filter.

-	 */

-	// TODO should we allow changing the filter type once it is created? I don't

-	// think we should.

-	public void setType(IpFilterType type) {

-		this.type = type;

-	}

-

-	/**

-	 * Adds the given string representation of InetAddress or CIDR notation to

-	 * this filter.

-	 * 

-	 * @param str

-	 *            the string representation of InetAddress or CIDR notation

-	 * @return if the given element was added or not. <code>true</code>, if the

-	 *         given element was added to the filter; <code>false</code>, if the

-	 *         element already exists in the filter.

-	 * @throws NumberFormatException

-	 *             propagated

-	 * @throws UnknownHostException

-	 *             propagated

-	 */

-	public boolean add(String str) throws NumberFormatException,

-		UnknownHostException {

-		// This is required so we do not block loopback address if some one adds

-		// a string with blanks as the InetAddress class assumes loopback

-		// address on blank string.

-		if (str.trim().length() < 1) {

-			throw new IllegalArgumentException("Invalid IP Address or Subnet: "

-				+ str);

-		}

-		String[] tokens = str.split("/");

-		if (tokens.length == 2) {

-			return add(new Subnet(InetAddress.getByName(tokens[0]),

-				Integer.parseInt(tokens[1])));

-		}

-		else {

-			return add(new Subnet(InetAddress.getByName(tokens[0]), 32));

-		}

-	}

-

-	public boolean accept(InetAddress address) {

-		switch (type) {

-			case ALLOW:

-				for (Subnet subnet : this) {

-					if (subnet.inSubnet(address)) {

-						if (LOGGER.isDebugEnabled()) {

-							LOGGER.debug(

-								"Allowing connection from {} because it matches with the whitelist subnet {}",

-								new Object[] { address, subnet });

-						}

-						return true;

-					}

-				}

-				if (LOGGER.isDebugEnabled()) {

-					LOGGER.debug(

-						"Denying connection from {} because it does not match any of the whitelist subnets",

-						new Object[] { address });

-				}

-				return false;

-			case DENY:

-				if (isEmpty()) {

-					if (LOGGER.isDebugEnabled()) {

-						LOGGER.debug(

-							"Allowing connection from {} because blacklist is empty",

-							new Object[] { address });

-					}

-					return true;

-				}

-				for (Subnet subnet : this) {

-					if (subnet.inSubnet(address)) {

-						if (LOGGER.isDebugEnabled()) {

-							LOGGER.debug(

-								"Denying connection from {} because it matches with the blacklist subnet {}",

-								new Object[] { address, subnet });

-						}

-						return false;

-					}

-				}

-				if (LOGGER.isDebugEnabled()) {

-					LOGGER.debug(

-						"Allowing connection from {} because it does not match any of the blacklist subnets",

-						new Object[] { address });

-				}

-				return true;

-			default:

-				throw new RuntimeException(

-					"Unknown or unimplemented filter type: " + type);

-		}

-	}

-}

diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java
deleted file mode 100644
index 77451cc..0000000
--- a/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*

- * 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.ftpserver.ipfilter;

-

-import java.net.InetAddress;

-import java.net.InetSocketAddress;

-import java.net.SocketAddress;

-

-import org.apache.mina.core.filterchain.IoFilterAdapter;

-import org.apache.mina.core.session.IoSession;

-

-/**

- * An implementation of Mina Filter to filter clients based on the originating

- * IP address.

- * 

- * @author <a href="http://mina.apache.org">Apache MINA Project</a>

- * 

- */

-

-public class MinaIpFilter extends IoFilterAdapter {

-

-	/**

-	 * The actual <code>IpFilter</code> used by this filter.

-	 */

-	private IpFilter filter = null;

-

-	/**

-	 * Creates a new instance of <code>MinaIpFilter</code>.

-	 * 

-	 * @param filter

-	 *            the filter

-	 */

-	public MinaIpFilter(IpFilter filter) {

-		this.filter = filter;

-	}

-

-	@Override

-	public void sessionCreated(NextFilter nextFilter, IoSession session) {

-		SocketAddress remoteAddress = session.getRemoteAddress();

-		if (remoteAddress instanceof InetSocketAddress) {

-			InetAddress ipAddress = ((InetSocketAddress) remoteAddress).getAddress();

-			// TODO we probably have to check if the InetAddress is a version 4

-			// address, or else, the result would probably be unknown.

-			if (!filter.accept(ipAddress)) {

-				session.close(true);

-			}

-			else {

-				nextFilter.sessionCreated(session);

-			}

-		}

-	}

-}

diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/MinaSessionFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/MinaSessionFilter.java
new file mode 100644
index 0000000..08fcc3a
--- /dev/null
+++ b/core/src/main/java/org/apache/ftpserver/ipfilter/MinaSessionFilter.java
@@ -0,0 +1,58 @@
+/*

+ * 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.ftpserver.ipfilter;

+

+import org.apache.mina.core.filterchain.IoFilterAdapter;

+import org.apache.mina.core.session.IoSession;

+

+/**

+ * A wrapper for <code>SessionFilter</code> so it can be added to the MINA

+ * filter chain.

+ * 

+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>

+ * 

+ */

+

+public class MinaSessionFilter extends IoFilterAdapter {

+

+    /**

+     * The actual (or wrapped) <code>SessionFilter</code> used by this filter.

+     */

+    private SessionFilter filter = null;

+

+    /**

+     * Creates a new instance of <code>MinaSessionFilter</code>.

+     * 

+     * @param filter

+     *            the filter

+     */

+    public MinaSessionFilter(SessionFilter filter) {

+        this.filter = filter;

+    }

+

+    @Override

+    public void sessionCreated(NextFilter nextFilter, IoSession session) {

+        if (!filter.accept(session)) {

+            session.close(true);

+        } else {

+            nextFilter.sessionCreated(session);

+        }

+    }

+}

diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/RemoteIpFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/RemoteIpFilter.java
new file mode 100644
index 0000000..a51b159
--- /dev/null
+++ b/core/src/main/java/org/apache/ftpserver/ipfilter/RemoteIpFilter.java
@@ -0,0 +1,223 @@
+/*

+ * 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.ftpserver.ipfilter;

+

+import java.net.InetAddress;

+import java.net.InetSocketAddress;

+import java.net.UnknownHostException;

+import java.util.Collection;

+import java.util.HashSet;

+import java.util.concurrent.CopyOnWriteArraySet;

+

+import org.apache.mina.core.session.IoSession;

+import org.apache.mina.filter.firewall.Subnet;

+import org.slf4j.Logger;

+import org.slf4j.LoggerFactory;

+

+/**

+ * An implementation of the <code>SessionFilter</code> interface, to filter

+ * sessions based on the remote IP address.

+ * 

+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>

+ * 

+ */

+

+public class RemoteIpFilter extends CopyOnWriteArraySet<Subnet> implements

+        SessionFilter {

+

+    /**

+     * Logger

+     */

+    Logger LOGGER = LoggerFactory.getLogger(RemoteIpFilter.class);

+

+    /**

+     * Serial version UID

+     */

+    private static final long serialVersionUID = 4887092372700628783L;

+

+    /**

+     * filter type

+     */

+    private IpFilterType type = null;

+

+    /**

+     * Creates a new instance of <code>RemoteIpFilter</code>.

+     * 

+     * @param type

+     *            the filter type

+     */

+    public RemoteIpFilter(IpFilterType type) {

+        this(type, new HashSet<Subnet>(0));

+    }

+

+    /**

+     * Creates a new instance of <code>RemoteIpFilter</code>.

+     * 

+     * @param type

+     *            the filter type

+     * @param collection

+     *            a collection of <code>Subnet</code>s to filter out/in.

+     */

+    public RemoteIpFilter(IpFilterType type,

+            Collection<? extends Subnet> collection) {

+        super(collection);

+        this.type = type;

+    }

+

+    /**

+     * Creates a new instance of <code>RemoteIpFilter</code>.

+     * 

+     * @param type

+     *            the filter type

+     * @param addresses

+     *            a comma, space, tab, CR, LF separated list of IP

+     *            addresses/CIDRs.

+     * @throws UnknownHostException

+     *             propagated

+     * @throws NumberFormatException

+     *             propagated

+     */

+    public RemoteIpFilter(IpFilterType type, String addresses)

+            throws NumberFormatException, UnknownHostException {

+        super();

+        this.type = type;

+        if (addresses != null) {

+            String[] tokens = addresses.split("[\\s,]+");

+            for (String token : tokens) {

+                if (token.trim().length() > 0) {

+                    add(token);

+                }

+            }

+        }

+        if (LOGGER.isDebugEnabled()) {

+            LOGGER.debug(

+                    "Created DefaultIpFilter of type {} with the subnets {}",

+                    type, this);

+        }

+    }

+

+    /**

+     * Returns the type of this filter.

+     * 

+     * @return the type of this filter.

+     */

+    public IpFilterType getType() {

+        return type;

+    }

+

+    /**

+     * Sets the type of this filter.

+     * 

+     * @param type

+     *            the type of this filter.

+     */

+    public void setType(IpFilterType type) {

+        this.type = type;

+    }

+

+    /**

+     * Adds the given string representation of InetAddress or CIDR notation to

+     * this filter.

+     * 

+     * @param str

+     *            the string representation of InetAddress or CIDR notation

+     * @return if the given element was added or not. <code>true</code>, if the

+     *         given element was added to the filter; <code>false</code>, if the

+     *         element already exists in the filter.

+     * @throws NumberFormatException

+     *             propagated

+     * @throws UnknownHostException

+     *             propagated

+     */

+    public boolean add(String str) throws NumberFormatException,

+            UnknownHostException {

+        // This is required so we do not block loopback address if some one adds

+        // a string with blanks as the InetAddress class assumes loopback

+        // address on a blank string.

+        if (str.trim().length() < 1) {

+            throw new IllegalArgumentException("Invalid IP Address or Subnet: "

+                    + str);

+        }

+        String[] tokens = str.split("/");

+        if (tokens.length == 2) {

+            return add(new Subnet(InetAddress.getByName(tokens[0]), Integer

+                    .parseInt(tokens[1])));

+        } else {

+            return add(new Subnet(InetAddress.getByName(tokens[0]), 32));

+        }

+    }

+

+    public boolean accept(IoSession session) {

+        InetAddress address = ((InetSocketAddress) session.getRemoteAddress())

+                .getAddress();

+        switch (type) {

+        case ALLOW:

+            for (Subnet subnet : this) {

+                if (subnet.inSubnet(address)) {

+                    if (LOGGER.isDebugEnabled()) {

+                        LOGGER

+                                .debug(

+                                        "Allowing connection from {} because it matches with the whitelist subnet {}",

+                                        new Object[] { address, subnet });

+                    }

+                    return true;

+                }

+            }

+            if (LOGGER.isDebugEnabled()) {

+                LOGGER

+                        .debug(

+                                "Denying connection from {} because it does not match any of the whitelist subnets",

+                                new Object[] { address });

+            }

+            return false;

+        case DENY:

+            if (isEmpty()) {

+                if (LOGGER.isDebugEnabled()) {

+                    LOGGER

+                            .debug(

+                                    "Allowing connection from {} because blacklist is empty",

+                                    new Object[] { address });

+                }

+                return true;

+            }

+            for (Subnet subnet : this) {

+                if (subnet.inSubnet(address)) {

+                    if (LOGGER.isDebugEnabled()) {

+                        LOGGER

+                                .debug(

+                                        "Denying connection from {} because it matches with the blacklist subnet {}",

+                                        new Object[] { address, subnet });

+                    }

+                    return false;

+                }

+            }

+            if (LOGGER.isDebugEnabled()) {

+                LOGGER

+                        .debug(

+                                "Allowing connection from {} because it does not match any of the blacklist subnets",

+                                new Object[] { address });

+            }

+            return true;

+        default:

+            throw new RuntimeException("Unknown or unimplemented filter type: "

+                    + type);

+        }

+    }

+}

diff --git a/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java b/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
similarity index 67%
rename from core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java
rename to core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
index 53b2b53..ec2b8c5 100644
--- a/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java
+++ b/core/src/main/java/org/apache/ftpserver/ipfilter/SessionFilter.java
@@ -19,25 +19,25 @@
 

 package org.apache.ftpserver.ipfilter;

 

-import java.net.InetAddress;

+import org.apache.mina.core.session.IoSession;

 

 /**

- * The interface for filtering connections based on the client's IP address.

+ * The interface for filtering sessions based on various session attributes.

  * 

  * @author <a href="http://mina.apache.org">Apache MINA Project</a>

  * 

  */

 

-public interface IpFilter {

+public interface SessionFilter {

 

-	/**

-	 * Tells whether or not the given IP address is accepted by this filter.

-	 * 

-	 * @param address

-	 *            the IP address to check

-	 * @return <code>true</code>, if the given IP address is accepted by this

-	 *         filter; <code>false</code>, otherwise.

-	 */

-	public boolean accept(InetAddress address);

+    /**

+     * Tells whether or not the given session is accepted by this filter.

+     * 

+     * @param session

+     *            the session to check

+     * @return <code>true</code>, if the given session is accepted by this

+     *         filter; <code>false</code>, otherwise.

+     */

+    public boolean accept(IoSession session);

 

 }

diff --git a/core/src/main/java/org/apache/ftpserver/listener/Listener.java b/core/src/main/java/org/apache/ftpserver/listener/Listener.java
index ce9d90c..1ca1b8b 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/Listener.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/Listener.java
@@ -26,7 +26,7 @@
 import org.apache.ftpserver.DataConnectionConfiguration;
 import org.apache.ftpserver.impl.FtpIoSession;
 import org.apache.ftpserver.impl.FtpServerContext;
-import org.apache.ftpserver.ipfilter.IpFilter;
+import org.apache.ftpserver.ipfilter.SessionFilter;
 import org.apache.ftpserver.ssl.SslConfiguration;
 import org.apache.mina.filter.firewall.Subnet;
 
@@ -139,36 +139,36 @@
     int getIdleTimeout();
 
     /**
-	 * @deprecated Replaced by IpFilter. Retrieves the {@link InetAddress} for
-	 *             which this listener blocks connections.
-	 * 
-	 * @return The list of {@link InetAddress}es. This method returns a valid
-	 *         list if and only if there is an <code>IpFilter</code> set, and,
-	 *         if it is an instance of <code>DefaultIpFilter</code> and it is of
-	 *         type <code>IpFilterType.DENY</code>. This functionality is
-	 *         provided for backward compatibility purpose only.
-	 */
-	@Deprecated
-	List<InetAddress> getBlockedAddresses();
+     * @deprecated Replaced by IpFilter. Retrieves the {@link InetAddress} for
+     *             which this listener blocks connections.
+     * 
+     * @return The list of {@link InetAddress}es. This method returns a valid
+     *         list if and only if there is an <code>IpFilter</code> set, and,
+     *         if it is an instance of <code>DefaultIpFilter</code> and it is of
+     *         type <code>IpFilterType.DENY</code>. This functionality is
+     *         provided for backward compatibility purpose only.
+     */
+    @Deprecated
+    List<InetAddress> getBlockedAddresses();
 
     /**
-     * @deprecated Replaced by IpFilter. 
-     * Retrieves the {@link Subnet}s for this listener blocks connections. 
+     * @deprecated Replaced by IpFilter. Retrieves the {@link Subnet}s for this
+     *             listener blocks connections.
      * 
-     * @return The list of {@link Subnet}s. This method returns a valid
-	 *         list if and only if there is an <code>IpFilter</code> set, and,
-	 *         if it is an instance of <code>DefaultIpFilter</code> and it is of
-	 *         type <code>IpFilterType.DENY</code>. This functionality is
-	 *         provided for backward compatibility purpose only.
+     * @return The list of {@link Subnet}s. This method returns a valid list if
+     *         and only if there is an <code>IpFilter</code> set, and, if it is
+     *         an instance of <code>DefaultIpFilter</code> and it is of type
+     *         <code>IpFilterType.DENY</code>. This functionality is provided
+     *         for backward compatibility purpose only.
      */
     List<Subnet> getBlockedSubnets();
-    
+
     /**
-	 * Returns the IP filter associated with this listener. May return
-	 * <code>null</code>.
-	 * 
-	 * @return the IP filter associated with this listener. May return
-	 *         <code>null</code>.
-	 */
-	IpFilter getIpFilter();
+     * Returns the <code>SessionFilter</code> associated with this listener. May
+     * return <code>null</code>.
+     * 
+     * @return the <code>SessionFilter</code> associated with this listener. May
+     *         return <code>null</code>.
+     */
+    SessionFilter getSessionFilter();
 }
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java b/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
index 1a3532b..60a689b 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
@@ -26,7 +26,7 @@
 import org.apache.ftpserver.DataConnectionConfiguration;

 import org.apache.ftpserver.DataConnectionConfigurationFactory;

 import org.apache.ftpserver.FtpServerConfigurationException;

-import org.apache.ftpserver.ipfilter.IpFilter;

+import org.apache.ftpserver.ipfilter.SessionFilter;

 import org.apache.ftpserver.listener.nio.NioListener;

 import org.apache.ftpserver.ssl.SslConfiguration;

 import org.apache.mina.filter.firewall.Subnet;

@@ -57,9 +57,9 @@
     private List<Subnet> blockedSubnets;

     

     /**

-     * The IP filter

+     * The Session filter

      */

-    private IpFilter ipFilter = null;

+    private SessionFilter sessionFilter = null;

 

     /**

      * Default constructor

@@ -79,10 +79,11 @@
         implicitSsl = listener.isImplicitSsl();

         dataConnectionConfig = listener.getDataConnectionConfiguration();

         idleTimeout = listener.getIdleTimeout();

-        //TODO remove the next two lines if and when we remove the deprecated methods. 

+        // TODO remove the next two lines if and when we remove the deprecated

+        // methods.

         blockedAddresses = listener.getBlockedAddresses();

         blockedSubnets = listener.getBlockedSubnets();

-        this.ipFilter = listener.getIpFilter();

+        this.sessionFilter = listener.getSessionFilter();

     }

 

     /**

@@ -90,25 +91,26 @@
      * @return The created listener

      */

     public Listener createListener() {

-    	try{

-    		InetAddress.getByName(serverAddress);

-    	}catch(UnknownHostException e){

-    		throw new FtpServerConfigurationException("Unknown host",e);

-    	}

-    	//Deal with the old style black list and new IP Filter here. 

-    	if(ipFilter != null) {

-    		 if(blockedAddresses != null || blockedSubnets != null) {

-    			 throw new IllegalStateException("Usage of IPFilter in combination with blockedAddesses/subnets is not supported. ");

-    		 }

-    	}

-    	if(blockedAddresses != null || blockedSubnets != null) {

+        try {

+            InetAddress.getByName(serverAddress);

+        } catch (UnknownHostException e) {

+            throw new FtpServerConfigurationException("Unknown host", e);

+        }

+        // Deal with the old style black list and new session Filter here.

+        if (sessionFilter != null) {

+            if (blockedAddresses != null || blockedSubnets != null) {

+                throw new IllegalStateException(

+                        "Usage of SessionFilter in combination with blockedAddesses/subnets is not supported. ");

+            }

+        }

+        if (blockedAddresses != null || blockedSubnets != null) {

             return new NioListener(serverAddress, port, implicitSsl, ssl,

-                dataConnectionConfig, idleTimeout, blockedAddresses, blockedSubnets);

-    	}

-    	else {

-	        return new NioListener(serverAddress, port, implicitSsl, ssl,

-	        	dataConnectionConfig, idleTimeout, ipFilter);

-    	}

+                    dataConnectionConfig, idleTimeout, blockedAddresses,

+                    blockedSubnets);

+        } else {

+            return new NioListener(serverAddress, port, implicitSsl, ssl,

+                    dataConnectionConfig, idleTimeout, sessionFilter);

+        }

     }

 

     /**

@@ -280,22 +282,23 @@
     }

     

     /**

-	 * Returns the currently configured IP filter, if any.

-	 * 

-	 * @return the currently configured IP filter, if any. Returns

-	 *         <code>null</code>, if no IP filter is configured.

-	 */

-	public IpFilter getIpFilter() {

-		return ipFilter;

-	}

+     * Returns the currently configured <code>SessionFilter</code>, if any.

+     * 

+     * @return the currently configured <code>SessionFilter</code>, if any.

+     *         Returns <code>null</code>, if no <code>SessionFilter</code> is

+     *         configured.

+     */

+    public SessionFilter getSessionFilter() {

+        return sessionFilter;

+    }

 

-	/**

-	 * Sets the IP filter to the given filter.

-	 * 

-	 * @param ipFilter

-	 *            the IP filter.

-	 */

-	public void setIpFilter(IpFilter ipFilter) {

-		this.ipFilter = ipFilter;

-	}

+    /**

+     * Sets the session filter to the given filter.

+     * 

+     * @param sessionFilter

+     *            the session filter.

+     */

+    public void setSessionFilter(SessionFilter sessionFilter) {

+        this.sessionFilter = sessionFilter;

+    }

 }
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java b/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java
index f00d812..d09751c 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java
@@ -23,9 +23,9 @@
 import java.util.List;
 
 import org.apache.ftpserver.DataConnectionConfiguration;
-import org.apache.ftpserver.ipfilter.DefaultIpFilter;
-import org.apache.ftpserver.ipfilter.IpFilter;
 import org.apache.ftpserver.ipfilter.IpFilterType;
+import org.apache.ftpserver.ipfilter.RemoteIpFilter;
+import org.apache.ftpserver.ipfilter.SessionFilter;
 import org.apache.ftpserver.listener.Listener;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.ftpserver.ssl.SslConfiguration;
@@ -53,8 +53,8 @@
     private List<InetAddress> blockedAddresses;
 
     private List<Subnet> blockedSubnets;
-    
-    private IpFilter ipFilter = null;
+
+    private SessionFilter sessionFilter = null;
 
     private DataConnectionConfiguration dataConnectionConfig;
 
@@ -75,42 +75,48 @@
     /**
      * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
      */
-    public AbstractListener(String serverAddress, int port, boolean implicitSsl, 
-            SslConfiguration sslConfiguration, DataConnectionConfiguration dataConnectionConfig,
-            int idleTimeout, IpFilter ipFilter) {
+    public AbstractListener(String serverAddress, int port,
+            boolean implicitSsl, SslConfiguration sslConfiguration,
+            DataConnectionConfiguration dataConnectionConfig, int idleTimeout,
+            SessionFilter sessionFilter) {
         this.serverAddress = serverAddress;
         this.port = port;
         this.implicitSsl = implicitSsl;
         this.dataConnectionConfig = dataConnectionConfig;
         this.ssl = sslConfiguration;
         this.idleTimeout = idleTimeout;
-        this.ipFilter = ipFilter;
+        this.sessionFilter = sessionFilter;
     }
     
     /**
-     * Creates an IpFilter that blacklists the given IP addresses and/or Subnets. 
-     * @param blockedAddresses the addresses to block
-     * @param blockedSubnets the subnets to block
-     * @return an IpFilter that blacklists the given IP addresses and/or Subnets.
+     * Creates a SessionFilter that blacklists the given IP addresses and/or
+     * Subnets.
+     * 
+     * @param blockedAddresses
+     *            the addresses to block
+     * @param blockedSubnets
+     *            the subnets to block
+     * @return a SessionFilter that blacklists the given IP addresses and/or
+     *         Subnets.
      */
-    private static IpFilter createBlackListFilter(List<InetAddress> blockedAddresses, 
-    	List<Subnet> blockedSubnets) {
-    	if(blockedAddresses == null && blockedSubnets == null) {
-    		return null;
-    	}
-		//Initialize the IP filter with Deny type
-		DefaultIpFilter ipFilter = new DefaultIpFilter(IpFilterType.DENY);
-		if(blockedSubnets != null) {
-			ipFilter.addAll(blockedSubnets);
-		}
-		if(blockedAddresses != null) {
-			for(InetAddress address:blockedAddresses) {
-				ipFilter.add(new Subnet(address, 32));
-			}
-		}
-		return ipFilter;
+    private static SessionFilter createBlackListFilter(
+            List<InetAddress> blockedAddresses, List<Subnet> blockedSubnets) {
+        if (blockedAddresses == null && blockedSubnets == null) {
+            return null;
+        }
+        // Initialize the IP filter with Deny type
+        RemoteIpFilter ipFilter = new RemoteIpFilter(IpFilterType.DENY);
+        if (blockedSubnets != null) {
+            ipFilter.addAll(blockedSubnets);
+        }
+        if (blockedAddresses != null) {
+            for (InetAddress address : blockedAddresses) {
+                ipFilter.add(new Subnet(address, 32));
+            }
+        }
+        return ipFilter;
     }
-    
+
     /**
      * {@inheritDoc}
      */
@@ -181,8 +187,8 @@
     public List<Subnet> getBlockedSubnets() {
         return blockedSubnets;
     }
-    
-    public IpFilter getIpFilter() {
-    	return ipFilter;
+
+    public SessionFilter getSessionFilter() {
+        return sessionFilter;
     }
 }
diff --git a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
index ec0ee8e..69999f0 100644
--- a/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
+++ b/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
@@ -27,8 +27,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
 
 import org.apache.ftpserver.DataConnectionConfiguration;
 import org.apache.ftpserver.FtpServerConfigurationException;
@@ -36,8 +34,8 @@
 import org.apache.ftpserver.impl.FtpHandler;
 import org.apache.ftpserver.impl.FtpIoSession;
 import org.apache.ftpserver.impl.FtpServerContext;
-import org.apache.ftpserver.ipfilter.IpFilter;
-import org.apache.ftpserver.ipfilter.MinaIpFilter;
+import org.apache.ftpserver.ipfilter.MinaSessionFilter;
+import org.apache.ftpserver.ipfilter.SessionFilter;
 import org.apache.ftpserver.listener.Listener;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.ftpserver.ssl.ClientAuth;
@@ -46,7 +44,6 @@
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
 import org.apache.mina.filter.executor.ExecutorFilter;
-import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
 import org.apache.mina.filter.firewall.Subnet;
 import org.apache.mina.filter.logging.MdcInjectionFilter;
 import org.apache.mina.filter.ssl.SslFilter;
@@ -94,13 +91,12 @@
     /**
      * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
      */
-    public NioListener(String serverAddress, int port,
-            boolean implicitSsl,
+    public NioListener(String serverAddress, int port, boolean implicitSsl,
             SslConfiguration sslConfiguration,
-            DataConnectionConfiguration dataConnectionConfig, 
-            int idleTimeout, IpFilter ipFilter) {
-        super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, 
-                idleTimeout, ipFilter);   
+            DataConnectionConfiguration dataConnectionConfig, int idleTimeout,
+            SessionFilter sessionFilter) {
+        super(serverAddress, port, implicitSsl, sslConfiguration,
+                dataConnectionConfig, idleTimeout, sessionFilter);
     }
 
     /**
@@ -131,11 +127,12 @@
             MdcInjectionFilter mdcFilter = new MdcInjectionFilter();
     
             acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
-    
-            IpFilter ipFilter = getIpFilter();
-            if(ipFilter != null) {
-            // 	add and IP filter to the filter chain. 
-            	acceptor.getFilterChain().addLast("ipFilter", new MinaIpFilter(ipFilter));
+
+            SessionFilter sessionFilter = getSessionFilter();
+            if (sessionFilter != null) {
+                // add and IP filter to the filter chain.
+                acceptor.getFilterChain().addLast("sessionFilter",
+                        new MinaSessionFilter(sessionFilter));
             }
     
             acceptor.getFilterChain().addLast("threadPool",
diff --git a/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd b/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
index 4f7cf19..530916c 100644
--- a/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
+++ b/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
@@ -100,8 +100,8 @@
 		</xs:complexType>
 	</xs:element>
 
-	<!-- Element used to configure the IP Filtering -->
-	<xs:element name="ip-filter">
+	<!-- Element used to configure the remote IP Filtering -->
+	<xs:element name="remote-ip-filter">
 		<xs:complexType>
 			<xs:simpleContent>
 				<xs:extension base="xs:string">
@@ -149,7 +149,7 @@
 					</xs:complexType>
 				</xs:element>
 				<xs:element minOccurs="0" name="blacklist" type="xs:string" />
-				<xs:element ref="ip-filter" minOccurs="0" maxOccurs="1" />
+				<xs:element ref="remote-ip-filter" minOccurs="0" maxOccurs="1" />
 			</xs:sequence>
 			<xs:attribute name="name" use="required" type="xs:string" />
 			<xs:attribute name="local-address" />
diff --git a/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java b/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java
index 3f3c02c..d1f3fc9 100644
--- a/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java
+++ b/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java
@@ -23,11 +23,10 @@
 
 import org.apache.commons.net.ftp.FTPConnectionClosedException;
 import org.apache.ftpserver.FtpServerFactory;
-import org.apache.ftpserver.ipfilter.DefaultIpFilter;
 import org.apache.ftpserver.ipfilter.IpFilterType;
+import org.apache.ftpserver.ipfilter.RemoteIpFilter;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.mina.filter.firewall.Subnet;
-import org.springframework.context.annotation.FilterType;
 
 /**
 *
@@ -35,15 +34,15 @@
 *
 */
 public class IpFilterTest extends ClientTestTemplate {
-	
-	private DefaultIpFilter filter = new DefaultIpFilter(IpFilterType.DENY);
-	
+
+    private RemoteIpFilter filter = new RemoteIpFilter(IpFilterType.DENY);
+
     protected FtpServerFactory createServer() throws Exception {
         FtpServerFactory server = super.createServer();
 
         ListenerFactory factory = new ListenerFactory(server.getListener("default"));
 
-        factory.setIpFilter(filter);
+        factory.setSessionFilter(filter);
         server.addListener("default", factory.createListener());
         
         return server;
diff --git a/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java b/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java
index 20b7d21..f9e6d27 100644
--- a/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java
+++ b/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java
@@ -26,7 +26,7 @@
 import org.apache.ftpserver.DataConnectionConfiguration;
 import org.apache.ftpserver.impl.FtpIoSession;
 import org.apache.ftpserver.impl.FtpServerContext;
-import org.apache.ftpserver.ipfilter.IpFilter;
+import org.apache.ftpserver.ipfilter.SessionFilter;
 import org.apache.ftpserver.listener.Listener;
 import org.apache.ftpserver.ssl.SslConfiguration;
 import org.apache.mina.filter.firewall.Subnet;
@@ -105,8 +105,8 @@
         return null;
     }
 
-	public IpFilter getIpFilter() {
-		return null;
-	}
+    public SessionFilter getSessionFilter() {
+        return null;
+    }
 
 }
diff --git a/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java b/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java
index cda1597..5ef03ea 100644
--- a/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java
+++ b/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java
@@ -30,7 +30,7 @@
 import org.apache.ftpserver.command.impl.STAT;
 import org.apache.ftpserver.filesystem.nativefs.NativeFileSystemFactory;
 import org.apache.ftpserver.impl.DefaultFtpServer;
-import org.apache.ftpserver.ipfilter.DefaultIpFilter;
+import org.apache.ftpserver.ipfilter.RemoteIpFilter;
 import org.apache.ftpserver.listener.Listener;
 import org.apache.ftpserver.listener.nio.NioListener;
 import org.apache.mina.filter.firewall.Subnet;
@@ -81,7 +81,7 @@
         assertEquals(false, ((NioListener) listener)
                 .getDataConnectionConfiguration().isPassiveIpCheck());
         
-        DefaultIpFilter filter = (DefaultIpFilter) listener.getIpFilter();
+        RemoteIpFilter filter = (RemoteIpFilter) listener.getSessionFilter();
         assertEquals(3, filter.size());
         assertTrue(filter.contains(new Subnet(InetAddress.getByName("1.2.3.0"), 16)));
         assertTrue(filter.contains(new Subnet(InetAddress.getByName("1.2.4.0"), 16)));