You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by sa...@apache.org on 2010/03/29 15:31:56 UTC

svn commit: r928769 - in /mina/ftpserver/trunk/core/src: main/java/org/apache/ftpserver/config/spring/ main/java/org/apache/ftpserver/ipfilter/ main/java/org/apache/ftpserver/listener/ main/java/org/apache/ftpserver/listener/nio/ main/resources/org/apa...

Author: sai
Date: Mon Mar 29 13:31:55 2010
New Revision: 928769

URL: http://svn.apache.org/viewvc?rev=928769&view=rev
Log:
Implemented FTPSERVER-357

Added:
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java   (with props)
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java   (with props)
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java   (with props)
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java   (with props)
    mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java   (with props)
Modified:
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/Listener.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java
    mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
    mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
    mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java
    mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/config/spring/ListenerBeanDefinitionParser.java Mon Mar 29 13:31:55 2010
@@ -1,318 +1,294 @@
-/*
- * 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.config.spring;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.ftpserver.DataConnectionConfiguration;
-import org.apache.ftpserver.DataConnectionConfigurationFactory;
-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;
-import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-/**
- * Parses the FtpServer "nio-listener" element into a Spring bean graph
- *
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class ListenerBeanDefinitionParser extends
-        AbstractSingleBeanDefinitionParser {
-
-    private final Logger LOG = LoggerFactory
-            .getLogger(ListenerBeanDefinitionParser.class);
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected Class<?> getBeanClass(final Element element) {
-        return null;
-    }
-
-    /**
-     * Parse CIDR notations into MINA {@link Subnet}s. TODO: move to Mina
-     */
-    private Subnet parseSubnet(final String subnet) {
-        if (subnet == null) {
-            throw new NullPointerException("subnet can not be null");
-        }
-
-        String[] tokens = subnet.split("/");
-
-        String ipString;
-        String maskString;
-        if (tokens.length == 2) {
-            ipString = tokens[0];
-            maskString = tokens[1];
-        } else if (tokens.length == 1) {
-            ipString = tokens[0];
-            maskString = "32";
-        } else {
-            throw new IllegalArgumentException("Illegal subnet format: "
-                    + subnet);
-        }
-
-        InetAddress address;
-        try {
-            address = InetAddress.getByName(ipString);
-        } catch (UnknownHostException e) {
-            throw new IllegalArgumentException("Illegal IP address in subnet: "
-                    + subnet);
-        }
-
-        int mask = Integer.parseInt(maskString);
-        if (mask < 0 || mask > 32) {
-            throw new IllegalArgumentException("Mask must be in the range 0-32");
-        }
-
-        return new Subnet(address, mask);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void doParse(final Element element,
-            final ParserContext parserContext,
-            final BeanDefinitionBuilder builder) {
-
-        BeanDefinitionBuilder factoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(ListenerFactory.class);
-
-        if (StringUtils.hasText(element.getAttribute("port"))) {
-            factoryBuilder.addPropertyValue("port", Integer.parseInt(element
-                    .getAttribute("port")));
-        }
-
-        SslConfiguration ssl = parseSsl(element);
-        if (ssl != null) {
-            factoryBuilder.addPropertyValue("sslConfiguration", ssl);
-        }
-
-        Element dataConElm = SpringUtil.getChildElement(element,
-                FtpServerNamespaceHandler.FTPSERVER_NS, "data-connection");
-        DataConnectionConfiguration dc = parseDataConnection(dataConElm, ssl);
-        factoryBuilder.addPropertyValue("dataConnectionConfiguration", dc);
-
-        if (StringUtils.hasText(element.getAttribute("idle-timeout"))) {
-            factoryBuilder.addPropertyValue("idleTimeout", SpringUtil.parseInt(
-                    element, "idle-timeout", 300));
-        }
-
-        String localAddress = SpringUtil.parseStringFromInetAddress(element,
-                "local-address");
-        if (localAddress != null) {
-            factoryBuilder.addPropertyValue("serverAddress", localAddress);
-        }
-        factoryBuilder.addPropertyValue("implicitSsl", SpringUtil.parseBoolean(
-                element, "implicit-ssl", false));
-
-        Element blacklistElm = SpringUtil.getChildElement(element,
-                FtpServerNamespaceHandler.FTPSERVER_NS, "blacklist");
-        if (blacklistElm != null
-                && StringUtils.hasText(blacklistElm.getTextContent())) {
-            String[] blocks = blacklistElm.getTextContent().split("[\\s,]+");
-            List<Subnet> subnets = new ArrayList<Subnet>();
-
-            for (String block : blocks) {
-                subnets.add(parseSubnet(block));
-            }
-
-            factoryBuilder.addPropertyValue("blockedSubnets", subnets);
-        }
-        
-        BeanDefinition factoryDefinition = factoryBuilder.getBeanDefinition();
-
-        String listenerFactoryName = parserContext.getReaderContext().generateBeanName(factoryDefinition);
-        
-        BeanDefinitionHolder factoryHolder = new BeanDefinitionHolder(factoryDefinition, listenerFactoryName);
-        registerBeanDefinition(factoryHolder, parserContext.getRegistry());
-
-        // set the factory on the listener bean
-        builder.getRawBeanDefinition().setFactoryBeanName(listenerFactoryName);
-        builder.getRawBeanDefinition().setFactoryMethodName("createListener");
-    }
-
-    private SslConfiguration parseSsl(final Element parent) {
-        Element sslElm = SpringUtil.getChildElement(parent,
-                FtpServerNamespaceHandler.FTPSERVER_NS, "ssl");
-
-        if (sslElm != null) {
-            SslConfigurationFactory ssl = new SslConfigurationFactory();
-
-            Element keyStoreElm = SpringUtil.getChildElement(sslElm,
-                    FtpServerNamespaceHandler.FTPSERVER_NS, "keystore");
-            if (keyStoreElm != null) {
-                ssl.setKeystoreFile(SpringUtil.parseFile(keyStoreElm, "file"));
-                ssl.setKeystorePassword(SpringUtil.parseString(keyStoreElm,
-                        "password"));
-
-                String type = SpringUtil.parseString(keyStoreElm, "type");
-                if (type != null) {
-                    ssl.setKeystoreType(type);
-                }
-
-                String keyAlias = SpringUtil.parseString(keyStoreElm,
-                        "key-alias");
-                if (keyAlias != null) {
-                    ssl.setKeyAlias(keyAlias);
-                }
-
-                String keyPassword = SpringUtil.parseString(keyStoreElm,
-                        "key-password");
-                if (keyPassword != null) {
-                    ssl.setKeyPassword(keyPassword);
-                }
-
-                String algorithm = SpringUtil.parseString(keyStoreElm,
-                        "algorithm");
-                if (algorithm != null) {
-                    ssl.setKeystoreAlgorithm(algorithm);
-                }
-            }
-
-            Element trustStoreElm = SpringUtil.getChildElement(sslElm,
-                    FtpServerNamespaceHandler.FTPSERVER_NS, "truststore");
-            if (trustStoreElm != null) {
-                ssl.setTruststoreFile(SpringUtil.parseFile(trustStoreElm,
-                        "file"));
-                ssl.setTruststorePassword(SpringUtil.parseString(trustStoreElm,
-                        "password"));
-
-                String type = SpringUtil.parseString(trustStoreElm, "type");
-                if (type != null) {
-                    ssl.setTruststoreType(type);
-                }
-
-                String algorithm = SpringUtil.parseString(trustStoreElm,
-                        "algorithm");
-                if (algorithm != null) {
-                    ssl.setTruststoreAlgorithm(algorithm);
-                }
-            }
-
-            String clientAuthStr = SpringUtil.parseString(sslElm,
-                    "client-authentication");
-            if (clientAuthStr != null) {
-                ssl.setClientAuthentication(clientAuthStr);
-            }
-
-            String enabledCiphersuites = SpringUtil.parseString(sslElm,
-                    "enabled-ciphersuites");
-            if (enabledCiphersuites != null) {
-                ssl.setEnabledCipherSuites(enabledCiphersuites.split(" "));
-            }
-
-            String protocol = SpringUtil.parseString(sslElm, "protocol");
-            if (protocol != null) {
-                ssl.setSslProtocol(protocol);
-            }
-
-            return ssl.createSslConfiguration();
-        } else {
-            return null;
-        }
-
-    }
-
-    private DataConnectionConfiguration parseDataConnection(
-            final Element element,
-            final SslConfiguration listenerSslConfiguration) {
-        DataConnectionConfigurationFactory dc = new DataConnectionConfigurationFactory();
-
-        if (element != null) {
-            
-            dc.setImplicitSsl(SpringUtil.parseBoolean(element, "implicit-ssl", false));
-            
-            // data con config element available
-            SslConfiguration ssl = parseSsl(element);
-
-            if (ssl != null) {
-                LOG.debug("SSL configuration found for the data connection");
-                dc.setSslConfiguration(ssl);
-            }
-
-            dc.setIdleTime(SpringUtil.parseInt(element, "idle-timeout", dc.getIdleTime()));
-
-            Element activeElm = SpringUtil.getChildElement(element,
-                    FtpServerNamespaceHandler.FTPSERVER_NS, "active");
-            if (activeElm != null) {
-                dc.setActiveEnabled(SpringUtil.parseBoolean(activeElm, "enabled",
-                        true));
-                dc.setActiveIpCheck(SpringUtil.parseBoolean(activeElm,
-                        "ip-check", false));
-                dc.setActiveLocalPort(SpringUtil.parseInt(activeElm,
-                        "local-port", 0));
-                
-                String localAddress = SpringUtil.parseStringFromInetAddress(
-                        activeElm, "local-address");
-                if (localAddress != null) {
-                	dc.setActiveLocalAddress(localAddress);
-                }
-            }
-
-            Element passiveElm = SpringUtil.getChildElement(element,
-                    FtpServerNamespaceHandler.FTPSERVER_NS, "passive");
-            if (passiveElm != null) {
-                String address = SpringUtil.parseStringFromInetAddress(passiveElm,
-                        "address");
-                if (address != null) {
-                	dc.setPassiveAddress(address);
-                }
-
-                String externalAddress = SpringUtil.parseStringFromInetAddress(
-                        passiveElm, "external-address");
-                if (externalAddress != null) {
-                    dc.setPassiveExternalAddress(externalAddress);
-                }
-
-                String ports = SpringUtil.parseString(passiveElm, "ports");
-                if (ports != null) {
-                    dc.setPassivePorts(ports);
-                }
-                dc.setPassiveIpCheck(SpringUtil.parseBoolean(passiveElm,
-                    "ip-check", false));
-            }
-        } else {
-            // no data conn config element, do we still have SSL config from the
-            // parent?
-            if (listenerSslConfiguration != null) {
-                LOG
-                        .debug("SSL configuration found for the listener, falling back for that for the data connection");
-                dc.setSslConfiguration(listenerSslConfiguration);
-            }
-        }
-
-        return dc.createDataConnectionConfiguration();
-    }
-
-}
+/*
+ * 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.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.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;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * Parses the FtpServer "nio-listener" element into a Spring bean graph
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class ListenerBeanDefinitionParser extends
+        AbstractSingleBeanDefinitionParser {
+
+    private final Logger LOG = LoggerFactory
+            .getLogger(ListenerBeanDefinitionParser.class);
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Class<?> getBeanClass(final Element element) {
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void doParse(final Element element,
+            final ParserContext parserContext,
+            final BeanDefinitionBuilder builder) {
+
+        BeanDefinitionBuilder factoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(ListenerFactory.class);
+
+        if (StringUtils.hasText(element.getAttribute("port"))) {
+            factoryBuilder.addPropertyValue("port", Integer.parseInt(element
+                    .getAttribute("port")));
+        }
+
+        SslConfiguration ssl = parseSsl(element);
+        if (ssl != null) {
+            factoryBuilder.addPropertyValue("sslConfiguration", ssl);
+        }
+
+        Element dataConElm = SpringUtil.getChildElement(element,
+                FtpServerNamespaceHandler.FTPSERVER_NS, "data-connection");
+        DataConnectionConfiguration dc = parseDataConnection(dataConElm, ssl);
+        factoryBuilder.addPropertyValue("dataConnectionConfiguration", dc);
+
+        if (StringUtils.hasText(element.getAttribute("idle-timeout"))) {
+            factoryBuilder.addPropertyValue("idleTimeout", SpringUtil.parseInt(
+                    element, "idle-timeout", 300));
+        }
+
+        String localAddress = SpringUtil.parseStringFromInetAddress(element,
+                "local-address");
+        if (localAddress != null) {
+            factoryBuilder.addPropertyValue("serverAddress", localAddress);
+        }
+        factoryBuilder.addPropertyValue("implicitSsl", SpringUtil.parseBoolean(
+                element, "implicit-ssl", false));
+
+        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);
+			}
+        }
+        
+        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");
+			}
+        }
+        
+        BeanDefinition factoryDefinition = factoryBuilder.getBeanDefinition();
+
+        String listenerFactoryName = parserContext.getReaderContext().generateBeanName(factoryDefinition);
+        
+        BeanDefinitionHolder factoryHolder = new BeanDefinitionHolder(factoryDefinition, listenerFactoryName);
+        registerBeanDefinition(factoryHolder, parserContext.getRegistry());
+
+        // set the factory on the listener bean
+        builder.getRawBeanDefinition().setFactoryBeanName(listenerFactoryName);
+        builder.getRawBeanDefinition().setFactoryMethodName("createListener");
+    }
+
+    private SslConfiguration parseSsl(final Element parent) {
+        Element sslElm = SpringUtil.getChildElement(parent,
+                FtpServerNamespaceHandler.FTPSERVER_NS, "ssl");
+
+        if (sslElm != null) {
+            SslConfigurationFactory ssl = new SslConfigurationFactory();
+
+            Element keyStoreElm = SpringUtil.getChildElement(sslElm,
+                    FtpServerNamespaceHandler.FTPSERVER_NS, "keystore");
+            if (keyStoreElm != null) {
+                ssl.setKeystoreFile(SpringUtil.parseFile(keyStoreElm, "file"));
+                ssl.setKeystorePassword(SpringUtil.parseString(keyStoreElm,
+                        "password"));
+
+                String type = SpringUtil.parseString(keyStoreElm, "type");
+                if (type != null) {
+                    ssl.setKeystoreType(type);
+                }
+
+                String keyAlias = SpringUtil.parseString(keyStoreElm,
+                        "key-alias");
+                if (keyAlias != null) {
+                    ssl.setKeyAlias(keyAlias);
+                }
+
+                String keyPassword = SpringUtil.parseString(keyStoreElm,
+                        "key-password");
+                if (keyPassword != null) {
+                    ssl.setKeyPassword(keyPassword);
+                }
+
+                String algorithm = SpringUtil.parseString(keyStoreElm,
+                        "algorithm");
+                if (algorithm != null) {
+                    ssl.setKeystoreAlgorithm(algorithm);
+                }
+            }
+
+            Element trustStoreElm = SpringUtil.getChildElement(sslElm,
+                    FtpServerNamespaceHandler.FTPSERVER_NS, "truststore");
+            if (trustStoreElm != null) {
+                ssl.setTruststoreFile(SpringUtil.parseFile(trustStoreElm,
+                        "file"));
+                ssl.setTruststorePassword(SpringUtil.parseString(trustStoreElm,
+                        "password"));
+
+                String type = SpringUtil.parseString(trustStoreElm, "type");
+                if (type != null) {
+                    ssl.setTruststoreType(type);
+                }
+
+                String algorithm = SpringUtil.parseString(trustStoreElm,
+                        "algorithm");
+                if (algorithm != null) {
+                    ssl.setTruststoreAlgorithm(algorithm);
+                }
+            }
+
+            String clientAuthStr = SpringUtil.parseString(sslElm,
+                    "client-authentication");
+            if (clientAuthStr != null) {
+                ssl.setClientAuthentication(clientAuthStr);
+            }
+
+            String enabledCiphersuites = SpringUtil.parseString(sslElm,
+                    "enabled-ciphersuites");
+            if (enabledCiphersuites != null) {
+                ssl.setEnabledCipherSuites(enabledCiphersuites.split(" "));
+            }
+
+            String protocol = SpringUtil.parseString(sslElm, "protocol");
+            if (protocol != null) {
+                ssl.setSslProtocol(protocol);
+            }
+
+            return ssl.createSslConfiguration();
+        } else {
+            return null;
+        }
+
+    }
+
+    private DataConnectionConfiguration parseDataConnection(
+            final Element element,
+            final SslConfiguration listenerSslConfiguration) {
+        DataConnectionConfigurationFactory dc = new DataConnectionConfigurationFactory();
+
+        if (element != null) {
+            
+            dc.setImplicitSsl(SpringUtil.parseBoolean(element, "implicit-ssl", false));
+            
+            // data con config element available
+            SslConfiguration ssl = parseSsl(element);
+
+            if (ssl != null) {
+                LOG.debug("SSL configuration found for the data connection");
+                dc.setSslConfiguration(ssl);
+            }
+
+            dc.setIdleTime(SpringUtil.parseInt(element, "idle-timeout", dc.getIdleTime()));
+
+            Element activeElm = SpringUtil.getChildElement(element,
+                    FtpServerNamespaceHandler.FTPSERVER_NS, "active");
+            if (activeElm != null) {
+                dc.setActiveEnabled(SpringUtil.parseBoolean(activeElm, "enabled",
+                        true));
+                dc.setActiveIpCheck(SpringUtil.parseBoolean(activeElm,
+                        "ip-check", false));
+                dc.setActiveLocalPort(SpringUtil.parseInt(activeElm,
+                        "local-port", 0));
+                
+                String localAddress = SpringUtil.parseStringFromInetAddress(
+                        activeElm, "local-address");
+                if (localAddress != null) {
+                	dc.setActiveLocalAddress(localAddress);
+                }
+            }
+
+            Element passiveElm = SpringUtil.getChildElement(element,
+                    FtpServerNamespaceHandler.FTPSERVER_NS, "passive");
+            if (passiveElm != null) {
+                String address = SpringUtil.parseStringFromInetAddress(passiveElm,
+                        "address");
+                if (address != null) {
+                	dc.setPassiveAddress(address);
+                }
+
+                String externalAddress = SpringUtil.parseStringFromInetAddress(
+                        passiveElm, "external-address");
+                if (externalAddress != null) {
+                    dc.setPassiveExternalAddress(externalAddress);
+                }
+
+                String ports = SpringUtil.parseString(passiveElm, "ports");
+                if (ports != null) {
+                    dc.setPassivePorts(ports);
+                }
+                dc.setPassiveIpCheck(SpringUtil.parseBoolean(passiveElm,
+                    "ip-check", false));
+            }
+        } else {
+            // no data conn config element, do we still have SSL config from the
+            // parent?
+            if (listenerSslConfiguration != null) {
+                LOG
+                        .debug("SSL configuration found for the listener, falling back for that for the data connection");
+                dc.setSslConfiguration(listenerSslConfiguration);
+            }
+        }
+
+        return dc.createDataConnectionConfiguration();
+    }
+
+}

Added: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java?rev=928769&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java (added)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java Mon Mar 29 13:31:55 2010
@@ -0,0 +1,217 @@
+/*
+ * 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);
+		}
+	}
+}

Propchange: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/DefaultIpFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java?rev=928769&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java (added)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java Mon Mar 29 13:31:55 2010
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+/**
+ * The interface for filtering connections based on the client's IP address.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+
+public interface IpFilter {
+
+	/**
+	 * 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);
+
+}

Propchange: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java?rev=928769&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java (added)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java Mon Mar 29 13:31:55 2010
@@ -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;
+
+/**
+ * Defines various types of IP Filters.
+ * 
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ * 
+ */
+public enum IpFilterType {
+
+	/**
+	 * filter type that allows a set of predefined IP addresses, also known as a
+	 * white list.
+	 */
+	ALLOW,
+
+	/**
+	 * filter type that blocks a set of predefined IP addresses, also known as a
+	 * black list.
+	 */
+	DENY;
+
+	/**
+	 * Parses the given string into its equivalent enum.
+	 * 
+	 * @param value
+	 *            the string value to parse.
+	 * @return the equivalent enum
+	 */
+	public static IpFilterType parse(String value) {
+		for (IpFilterType type : values()) {
+			if (type.name().equalsIgnoreCase(value)) {
+				return type;
+			}
+		}
+		throw new IllegalArgumentException("Invalid IpFilterType: " + value);
+	}
+
+}

Propchange: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/IpFilterType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java?rev=928769&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java (added)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java Mon Mar 29 13:31:55 2010
@@ -0,0 +1,69 @@
+/*
+ * 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);
+			}
+		}
+	}
+}

Propchange: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/ipfilter/MinaIpFilter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/Listener.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/Listener.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/Listener.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/Listener.java Mon Mar 29 13:31:55 2010
@@ -26,6 +26,7 @@ import java.util.Set;
 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.ssl.SslConfiguration;
 import org.apache.mina.filter.firewall.Subnet;
 
@@ -138,17 +139,36 @@ public interface Listener {
     int getIdleTimeout();
 
     /**
-     * Retrieves the {@link InetAddress} for which this listener blocks
-     * connections
-     * 
-     * @return The list of {@link InetAddress}es
-     */
-    List<InetAddress> getBlockedAddresses();
-
-    /**
-     * Retrieves the {@link Subnet}s for this listener blocks connections
-     * 
-     * @return The list of {@link Subnet}s
+	 * @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. 
+     * 
+     * @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();
 }
\ No newline at end of file

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/ListenerFactory.java Mon Mar 29 13:31:55 2010
@@ -1,255 +1,301 @@
-/*
- * 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.listener;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.List;
-
-import org.apache.ftpserver.DataConnectionConfiguration;
-import org.apache.ftpserver.DataConnectionConfigurationFactory;
-import org.apache.ftpserver.FtpServerConfigurationException;
-import org.apache.ftpserver.listener.nio.NioListener;
-import org.apache.ftpserver.ssl.SslConfiguration;
-import org.apache.mina.filter.firewall.Subnet;
-
-/**
- * Factory for listeners. Listeners themselves are immutable and must be 
- * created using this factory.
- *
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class ListenerFactory {
-
-    private String serverAddress;
-
-    private int port = 21;
-
-    private SslConfiguration ssl;
-
-    private boolean implicitSsl = false;
-
-    private DataConnectionConfiguration dataConnectionConfig = new DataConnectionConfigurationFactory()
-            .createDataConnectionConfiguration();
-
-    private int idleTimeout = 300;
-
-    private List<InetAddress> blockedAddresses;
-
-    private List<Subnet> blockedSubnets;
-
-    /**
-     * Default constructor
-     */
-    public ListenerFactory() {
-        // do nothing
-    }
-
-    /**
-     * Copy constructor, will copy properties from the provided listener.
-     * @param listener The listener which properties will be used for this factory
-     */
-    public ListenerFactory(Listener listener) {
-        serverAddress = listener.getServerAddress();
-        port = listener.getPort();
-        ssl = listener.getSslConfiguration();
-        implicitSsl = listener.isImplicitSsl();
-        dataConnectionConfig = listener.getDataConnectionConfiguration();
-        idleTimeout = listener.getIdleTimeout();
-        blockedAddresses = listener.getBlockedAddresses();
-        blockedSubnets = listener.getBlockedSubnets();
-    }
-
-    /**
-     * Create a listener based on the settings of this factory. The listener is immutable.
-     * @return The created listener
-     */
-    public Listener createListener() {
-    	try{
-    		InetAddress.getByName(serverAddress);
-    	}catch(UnknownHostException e){
-    		throw new FtpServerConfigurationException("Unknown host",e);
-    	}
-        return new NioListener(serverAddress, port, implicitSsl, ssl,
-                dataConnectionConfig, idleTimeout, blockedAddresses,
-                blockedSubnets);
-    }
-
-    /**
-     * Is listeners created by this factory in SSL mode automatically or must the client explicitly
-     * request to use SSL
-     * 
-     * @return true is listeners created by this factory is automatically in SSL mode, false
-     *         otherwise
-     */
-    public boolean isImplicitSsl() {
-        return implicitSsl;
-    }
-
-    /**
-     * Should listeners created by this factory be in SSL mode automatically or must the client
-     * explicitly request to use SSL
-     * 
-     * @param implicitSsl
-     *            true is listeners created by this factory should automatically be in SSL mode,
-     *            false otherwise
-     */
-    public void setImplicitSsl(boolean implicitSsl) {
-        this.implicitSsl = implicitSsl;
-    }
-
-    /**
-     * Get the port on which listeners created by this factory is waiting for requests. 
-     * 
-     * @return The port
-     */
-    public int getPort() {
-        return port;
-    }
-
-    /**
-     * Set the port on which listeners created by this factory will accept requests. Or set to 0
-     * (zero) is the port should be automatically assigned
-     * 
-     * @param port
-     *            The port to use.
-     */
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    /**
-     * Get the {@link InetAddress} used for binding the local socket. Defaults
-     * to null, that is, the server binds to all available network interfaces
-     * 
-     * @return The local socket {@link InetAddress}, if set
-     */
-    public String getServerAddress()  {
-        return serverAddress;
-    }
-
-    /**
-     * Set the {@link InetAddress} used for binding the local socket. Defaults
-     * to null, that is, the server binds to all available network interfaces
-     * 
-     * @param serverAddress
-     *            The local socket {@link InetAddress}
-     */
-    public void setServerAddress(String serverAddress) {
-        this.serverAddress = serverAddress;
-    }
-
-    /**
-     * Get the {@link SslConfiguration} used for listeners created by this factory
-     * 
-     * @return The {@link SslConfiguration}
-     */
-    public SslConfiguration getSslConfiguration() {
-        return ssl;
-    }
-
-    /**
-     * Set the {@link SslConfiguration} to use by listeners created by this factory
-     * @param ssl The {@link SslConfiguration}
-     */
-    public void setSslConfiguration(SslConfiguration ssl) {
-        this.ssl = ssl;
-    }
-
-    /**
-     * Get configuration for data connections made within listeners created by this factory
-     * 
-     * @return The data connection configuration
-     */
-    public DataConnectionConfiguration getDataConnectionConfiguration() {
-        return dataConnectionConfig;
-    }
-
-    /**
-     * Set configuration for data connections made within listeners created by this factory
-     * 
-     * @param dataConnectionConfig
-     *            The data connection configuration
-     */
-    public void setDataConnectionConfiguration(
-            DataConnectionConfiguration dataConnectionConfig) {
-        this.dataConnectionConfig = dataConnectionConfig;
-    }
-
-    /**
-     * Get the number of seconds during which no network activity 
-     * is allowed before a session is closed due to inactivity.  
-     * @return The idle time out
-     */
-    public int getIdleTimeout() {
-        return idleTimeout;
-    }
-
-    /**
-     * Set the number of seconds during which no network activity 
-     * is allowed before a session is closed due to inactivity.  
-     *
-     * @param idleTimeout The idle timeout in seconds
-     */
-    public void setIdleTimeout(int idleTimeout) {
-        this.idleTimeout = idleTimeout;
-    }
-
-    /**
-     * Retrives the {@link InetAddress} for which listeners created by this factory blocks
-     * connections
-     * 
-     * @return The list of {@link InetAddress}es
-     */
-    public List<InetAddress> getBlockedAddresses() {
-        return blockedAddresses;
-    }
-
-    /**
-     * Sets the {@link InetAddress} that listeners created by this factory will block from
-     * connecting
-     * 
-     * @param blockedAddresses
-     *            The list of {@link InetAddress}es
-     */
-    public void setBlockedAddresses(List<InetAddress> blockedAddresses) {
-        this.blockedAddresses = blockedAddresses;
-    }
-
-    /**
-     * Retrives the {@link Subnet}s for which listeners created by this factory blocks connections
-     * 
-     * @return The list of {@link Subnet}s
-     */
-    public List<Subnet> getBlockedSubnets() {
-        return blockedSubnets;
-    }
-
-    /**
-     * Sets the {@link Subnet}s that listeners created by this factory will block from connecting
-     * @param blockedSubnets 
-     *  The list of {@link Subnet}s
-     * @param blockedAddresses
-     */
-    public void setBlockedSubnets(List<Subnet> blockedSubnets) {
-        this.blockedSubnets = blockedSubnets;
-    }
-
+/*
+ * 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.listener;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+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.listener.nio.NioListener;
+import org.apache.ftpserver.ssl.SslConfiguration;
+import org.apache.mina.filter.firewall.Subnet;
+
+/**
+ * Factory for listeners. Listeners themselves are immutable and must be 
+ * created using this factory.
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+public class ListenerFactory {
+
+    private String serverAddress;
+
+    private int port = 21;
+
+    private SslConfiguration ssl;
+
+    private boolean implicitSsl = false;
+
+    private DataConnectionConfiguration dataConnectionConfig = new DataConnectionConfigurationFactory()
+            .createDataConnectionConfiguration();
+
+    private int idleTimeout = 300;
+
+    private List<InetAddress> blockedAddresses;
+
+    private List<Subnet> blockedSubnets;
+    
+    /**
+     * The IP filter
+     */
+    private IpFilter ipFilter = null;
+
+    /**
+     * Default constructor
+     */
+    public ListenerFactory() {
+        // do nothing
+    }
+
+    /**
+     * Copy constructor, will copy properties from the provided listener.
+     * @param listener The listener which properties will be used for this factory
+     */
+    public ListenerFactory(Listener listener) {
+        serverAddress = listener.getServerAddress();
+        port = listener.getPort();
+        ssl = listener.getSslConfiguration();
+        implicitSsl = listener.isImplicitSsl();
+        dataConnectionConfig = listener.getDataConnectionConfiguration();
+        idleTimeout = listener.getIdleTimeout();
+        //TODO remove the next two lines if and when we remove the deprecated methods. 
+        blockedAddresses = listener.getBlockedAddresses();
+        blockedSubnets = listener.getBlockedSubnets();
+        this.ipFilter = listener.getIpFilter();
+    }
+
+    /**
+     * Create a listener based on the settings of this factory. The listener is immutable.
+     * @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) {
+            return new NioListener(serverAddress, port, implicitSsl, ssl,
+                dataConnectionConfig, idleTimeout, blockedAddresses, blockedSubnets);
+    	}
+    	else {
+	        return new NioListener(serverAddress, port, implicitSsl, ssl,
+	        	dataConnectionConfig, idleTimeout, ipFilter);
+    	}
+    }
+
+    /**
+     * Is listeners created by this factory in SSL mode automatically or must the client explicitly
+     * request to use SSL
+     * 
+     * @return true is listeners created by this factory is automatically in SSL mode, false
+     *         otherwise
+     */
+    public boolean isImplicitSsl() {
+        return implicitSsl;
+    }
+
+    /**
+     * Should listeners created by this factory be in SSL mode automatically or must the client
+     * explicitly request to use SSL
+     * 
+     * @param implicitSsl
+     *            true is listeners created by this factory should automatically be in SSL mode,
+     *            false otherwise
+     */
+    public void setImplicitSsl(boolean implicitSsl) {
+        this.implicitSsl = implicitSsl;
+    }
+
+    /**
+     * Get the port on which listeners created by this factory is waiting for requests. 
+     * 
+     * @return The port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Set the port on which listeners created by this factory will accept requests. Or set to 0
+     * (zero) is the port should be automatically assigned
+     * 
+     * @param port
+     *            The port to use.
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    /**
+     * Get the {@link InetAddress} used for binding the local socket. Defaults
+     * to null, that is, the server binds to all available network interfaces
+     * 
+     * @return The local socket {@link InetAddress}, if set
+     */
+    public String getServerAddress()  {
+        return serverAddress;
+    }
+
+    /**
+     * Set the {@link InetAddress} used for binding the local socket. Defaults
+     * to null, that is, the server binds to all available network interfaces
+     * 
+     * @param serverAddress
+     *            The local socket {@link InetAddress}
+     */
+    public void setServerAddress(String serverAddress) {
+        this.serverAddress = serverAddress;
+    }
+
+    /**
+     * Get the {@link SslConfiguration} used for listeners created by this factory
+     * 
+     * @return The {@link SslConfiguration}
+     */
+    public SslConfiguration getSslConfiguration() {
+        return ssl;
+    }
+
+    /**
+     * Set the {@link SslConfiguration} to use by listeners created by this factory
+     * @param ssl The {@link SslConfiguration}
+     */
+    public void setSslConfiguration(SslConfiguration ssl) {
+        this.ssl = ssl;
+    }
+
+    /**
+     * Get configuration for data connections made within listeners created by this factory
+     * 
+     * @return The data connection configuration
+     */
+    public DataConnectionConfiguration getDataConnectionConfiguration() {
+        return dataConnectionConfig;
+    }
+
+    /**
+     * Set configuration for data connections made within listeners created by this factory
+     * 
+     * @param dataConnectionConfig
+     *            The data connection configuration
+     */
+    public void setDataConnectionConfiguration(
+            DataConnectionConfiguration dataConnectionConfig) {
+        this.dataConnectionConfig = dataConnectionConfig;
+    }
+
+    /**
+     * Get the number of seconds during which no network activity 
+     * is allowed before a session is closed due to inactivity.  
+     * @return The idle time out
+     */
+    public int getIdleTimeout() {
+        return idleTimeout;
+    }
+
+    /**
+     * Set the number of seconds during which no network activity 
+     * is allowed before a session is closed due to inactivity.  
+     *
+     * @param idleTimeout The idle timeout in seconds
+     */
+    public void setIdleTimeout(int idleTimeout) {
+        this.idleTimeout = idleTimeout;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Retrieves the {@link InetAddress} for which listeners created by this factory blocks
+     * connections
+     * 
+     * @return The list of {@link InetAddress}es
+     */
+    @Deprecated
+    public List<InetAddress> getBlockedAddresses() {
+        return blockedAddresses;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Sets the {@link InetAddress} that listeners created by this factory will block from
+     * connecting
+     * 
+     * @param blockedAddresses
+     *            The list of {@link InetAddress}es
+     */
+    @Deprecated
+    public void setBlockedAddresses(List<InetAddress> blockedAddresses) {
+        this.blockedAddresses = blockedAddresses;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Retrives the {@link Subnet}s for which listeners created by this factory blocks connections
+     * 
+     * @return The list of {@link Subnet}s
+     */
+    @Deprecated
+    public List<Subnet> getBlockedSubnets() {
+        return blockedSubnets;
+    }
+
+    /**
+     * @deprecated Replaced by the IpFilter.    
+     * Sets the {@link Subnet}s that listeners created by this factory will block from connecting
+     * @param blockedSubnets 
+     *  The list of {@link Subnet}s
+     * @param blockedAddresses
+     */
+    @Deprecated
+    public void setBlockedSubnets(List<Subnet> blockedSubnets) {
+        this.blockedSubnets = blockedSubnets;
+    }
+    
+    /**
+	 * 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;
+	}
+
+	/**
+	 * Sets the IP filter to the given filter.
+	 * 
+	 * @param ipFilter
+	 *            the IP filter.
+	 */
+	public void setIpFilter(IpFilter ipFilter) {
+		this.ipFilter = ipFilter;
+	}
 }
\ No newline at end of file

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/AbstractListener.java Mon Mar 29 13:31:55 2010
@@ -20,10 +20,12 @@
 package org.apache.ftpserver.listener.nio;
 
 import java.net.InetAddress;
-import java.util.Collections;
 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.listener.Listener;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.ftpserver.ssl.SslConfiguration;
@@ -51,29 +53,62 @@ public abstract class AbstractListener i
     private List<InetAddress> blockedAddresses;
 
     private List<Subnet> blockedSubnets;
+    
+    private IpFilter ipFilter = null;
 
     private DataConnectionConfiguration dataConnectionConfig;
 
     /**
+     * @deprecated Use the constructor with IpFilter instead. 
      * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
      */
+    @Deprecated
     public AbstractListener(String serverAddress, int port, boolean implicitSsl, 
             SslConfiguration sslConfiguration, DataConnectionConfiguration dataConnectionConfig,
             int idleTimeout, List<InetAddress> blockedAddresses, List<Subnet> blockedSubnets) {
+    	this(serverAddress, port, implicitSsl, sslConfiguration, 
+    		dataConnectionConfig, idleTimeout, createBlackListFilter(blockedAddresses, blockedSubnets));
+    	this.blockedAddresses = blockedAddresses;
+    	this.blockedSubnets = blockedSubnets;
+    }
+    
+    /**
+     * 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) {
         this.serverAddress = serverAddress;
         this.port = port;
         this.implicitSsl = implicitSsl;
         this.dataConnectionConfig = dataConnectionConfig;
         this.ssl = sslConfiguration;
         this.idleTimeout = idleTimeout;
-        
-        if(blockedAddresses != null) {
-            this.blockedAddresses = Collections.unmodifiableList(blockedAddresses);
-        }
-        if(blockedSubnets != null) {
-            this.blockedSubnets = Collections.unmodifiableList(blockedSubnets);
-        }
-        
+        this.ipFilter = ipFilter;
+    }
+    
+    /**
+     * 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.
+     */
+    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;
     }
     
     /**
@@ -146,4 +181,8 @@ public abstract class AbstractListener i
     public List<Subnet> getBlockedSubnets() {
         return blockedSubnets;
     }
+    
+    public IpFilter getIpFilter() {
+    	return ipFilter;
+    }
 }

Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/listener/nio/NioListener.java Mon Mar 29 13:31:55 2010
@@ -37,6 +37,8 @@ import org.apache.ftpserver.impl.Default
 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.listener.Listener;
 import org.apache.ftpserver.listener.ListenerFactory;
 import org.apache.ftpserver.ssl.ClientAuth;
@@ -80,8 +82,10 @@ public class NioListener extends Abstrac
     private FtpServerContext context;
 
     /**
+     * @deprecated Use the constructor with IpFilter instead. 
      * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
      */
+    @Deprecated
     public NioListener(String serverAddress, int port,
             boolean implicitSsl,
             SslConfiguration sslConfiguration,
@@ -89,27 +93,18 @@ public class NioListener extends Abstrac
             int idleTimeout, List<InetAddress> blockedAddresses, List<Subnet> blockedSubnets) {
         super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, 
                 idleTimeout, blockedAddresses, blockedSubnets);   
-        
-        updateBlacklistFilter();
     }
 
-    private void updateBlacklistFilter() {
-        if (acceptor != null) {
-            BlacklistFilter filter = (BlacklistFilter) acceptor
-                    .getFilterChain().get("ipFilter");
-
-            if (filter != null) {
-                if (getBlockedAddresses() != null) {
-                    filter.setBlacklist(getBlockedAddresses());
-                } else if (getBlockedSubnets() != null) {
-                    filter.setSubnetBlacklist(getBlockedSubnets());
-                } else {
-                    // an empty list clears the blocked addresses
-                    filter.setSubnetBlacklist(new ArrayList<Subnet>());
-                }
-
-            }
-        }
+    /**
+     * Constructor for internal use, do not use directly. Instead use {@link ListenerFactory}
+     */
+    public NioListener(String serverAddress, int port,
+            boolean implicitSsl,
+            SslConfiguration sslConfiguration,
+            DataConnectionConfiguration dataConnectionConfig, 
+            int idleTimeout, IpFilter ipFilter) {
+        super(serverAddress, port, implicitSsl, sslConfiguration, dataConnectionConfig, 
+                idleTimeout, ipFilter);   
     }
 
     /**
@@ -141,9 +136,11 @@ public class NioListener extends Abstrac
     
             acceptor.getFilterChain().addLast("mdcFilter", mdcFilter);
     
-            // add and update the blacklist filter
-            acceptor.getFilterChain().addLast("ipFilter", new BlacklistFilter());
-            updateBlacklistFilter();
+            IpFilter ipFilter = getIpFilter();
+            if(ipFilter != null) {
+            // 	add and IP filter to the filter chain. 
+            	acceptor.getFilterChain().addLast("ipFilter", new MinaIpFilter(ipFilter));
+            }
     
             acceptor.getFilterChain().addLast("threadPool",
                     new ExecutorFilter(filterExecutor));

Modified: mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd (original)
+++ mina/ftpserver/trunk/core/src/main/resources/org/apache/ftpserver/config/spring/ftpserver-1.0.xsd Mon Mar 29 13:31:55 2010
@@ -99,6 +99,24 @@
 		</xs:complexType>
 	</xs:element>
 
+	<!-- Element used to configure the IP Filtering -->
+	<xs:element name="ip-filter">
+		<xs:complexType>
+			<xs:simpleContent>
+				<xs:extension base="xs:string">
+					<xs:attribute name="type">
+						<xs:simpleType>
+							<xs:restriction base="xs:string">
+								<xs:enumeration value="allow" />
+								<xs:enumeration value="deny" />
+							</xs:restriction>
+						</xs:simpleType>
+					</xs:attribute>
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+
 	<!-- Element used to define the default, NIO based listener -->
 	<xs:element name="nio-listener">
 		<xs:complexType>
@@ -130,6 +148,7 @@
 					</xs:complexType>
 				</xs:element>
 				<xs:element minOccurs="0" name="blacklist" type="xs:string" />
+				<xs:element ref="ip-filter" minOccurs="0" maxOccurs="1" />
 			</xs:sequence>
 			<xs:attribute name="name" use="required" type="xs:string" />
 			<xs:attribute name="local-address" />

Added: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java?rev=928769&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java (added)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java Mon Mar 29 13:31:55 2010
@@ -0,0 +1,85 @@
+/*
+ * 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.clienttests;
+
+import java.net.InetAddress;
+
+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.listener.ListenerFactory;
+import org.apache.mina.filter.firewall.Subnet;
+import org.springframework.context.annotation.FilterType;
+
+/**
+*
+* @author <a href="http://mina.apache.org">Apache MINA Project</a>
+*
+*/
+public class IpFilterTest extends ClientTestTemplate {
+	
+	private DefaultIpFilter filter = new DefaultIpFilter(IpFilterType.DENY);
+	
+    protected FtpServerFactory createServer() throws Exception {
+        FtpServerFactory server = super.createServer();
+
+        ListenerFactory factory = new ListenerFactory(server.getListener("default"));
+
+        factory.setIpFilter(filter);
+        server.addListener("default", factory.createListener());
+        
+        return server;
+    }
+
+    protected boolean isConnectClient() {
+        return false;
+    }
+
+    public void testDenyBlackList() throws Exception {
+    	filter.clear();
+    	filter.setType(IpFilterType.DENY);
+        filter.add(new Subnet(InetAddress.getByName("localhost"), 32));
+        try {
+            client.connect("localhost", getListenerPort());
+            fail("Must throw");
+        } catch (FTPConnectionClosedException e) {
+            // OK
+        }
+    }
+
+    public void testDenyEmptyWhiteList() throws Exception {
+    	filter.clear();
+    	filter.setType(IpFilterType.ALLOW);
+        try {
+            client.connect("localhost", getListenerPort());
+            fail("Must throw");
+        } catch (FTPConnectionClosedException e) {
+            // OK
+        }
+    }
+
+    public void testWhiteList() throws Exception {
+    	filter.clear();
+    	filter.setType(IpFilterType.ALLOW);
+        filter.add(new Subnet(InetAddress.getByName("localhost"), 32));
+        client.connect("localhost", getListenerPort());
+    }
+}

Propchange: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/IpFilterTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java (original)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/MyCustomListener.java Mon Mar 29 13:31:55 2010
@@ -26,6 +26,7 @@ import java.util.Set;
 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.listener.Listener;
 import org.apache.ftpserver.ssl.SslConfiguration;
 import org.apache.mina.filter.firewall.Subnet;
@@ -104,4 +105,8 @@ public class MyCustomListener implements
         return null;
     }
 
+	public IpFilter getIpFilter() {
+		return null;
+	}
+
 }

Modified: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java?rev=928769&r1=928768&r2=928769&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java (original)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/config/spring/SpringConfigTest.java Mon Mar 29 13:31:55 2010
@@ -30,6 +30,7 @@ import org.apache.ftpserver.command.impl
 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.listener.Listener;
 import org.apache.ftpserver.listener.nio.NioListener;
 import org.apache.mina.filter.firewall.Subnet;
@@ -79,16 +80,12 @@ public class SpringConfigTest extends Te
                 .getDataConnectionConfiguration().getPassivePorts());
         assertEquals(false, ((NioListener) listener)
                 .getDataConnectionConfiguration().isPassiveIpCheck());
-
-        List<Subnet> subnets = ((NioListener) listener).getBlockedSubnets();
-        assertEquals(3, subnets.size());
-        assertEquals(new Subnet(InetAddress.getByName("1.2.3.0"), 16), subnets
-                .get(0));
-        assertEquals(new Subnet(InetAddress.getByName("1.2.4.0"), 16), subnets
-                .get(1));
-        assertEquals(new Subnet(InetAddress.getByName("1.2.3.4"), 32), subnets
-                .get(2));
-
+        
+        DefaultIpFilter filter = (DefaultIpFilter) listener.getIpFilter();
+        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)));
+        assertTrue(filter.contains(new Subnet(InetAddress.getByName("1.2.3.4"), 32)));
         listener = listeners.get("listener1");
         assertNotNull(listener);
         assertTrue(listener instanceof MyCustomListener);