Package cu.ftpd

Source Code of cu.ftpd.FtpdSettings

/**
* Copyright (c) 2007, Markus Jevring <markus@jevring.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
* 3. The names of the contributors may not be used to endorse or promote
*    products derived from this software without specific prior written
*    permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/

package cu.ftpd;

import cu.settings.XMLSettings;
import cu.settings.ConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;

/**
* @author Markus Jevring
* @since 2007-maj-11 : 11:29:10
* @version $Id: FtpdSettings.java 308 2011-02-27 21:58:19Z jevring $
*/
public class FtpdSettings extends XMLSettings {
    protected File dataDirectory;
    protected int pasvHighPort;
    protected int pasvLowPort;
    protected final Random random = new Random();
    protected HashSet<InetAddress> bouncers;
    protected final String settingsNamespace;
    protected final Map<String, Document> moduleSettings = new HashMap<String, Document>();

    /**
     * Creates the settings object.
     * The settings namespace is as follows:
     * cuftpd: "/ftpd"
     * cubnc:  "/bnc"
     * Anything else depends on when and where it is used.
     * @param settingsNamespace the settings namespace. defines the name of the toplevel settings object. This helps us reuse the same classes for a lot of projects.
     * @param xmlPath the path of the file containing the settings.
     * @param schemaPath the path of the xsd schema. Often something like "/cuftpd.xsd"
     * @throws cu.settings.ConfigurationException if something goes wrong when reading or checking the configuration
     * @throws java.io.IOException if something goes wrong when reading the settings from file.
     */
    public FtpdSettings(String settingsNamespace, String xmlPath, String schemaPath) throws IOException, ConfigurationException {
        super(xmlPath, schemaPath);
        this.settingsNamespace = settingsNamespace;
        loadBouncers(get("/main/bouncers"));
        loadPasvPorts(get("/main/pasv_port_range"));
        loadDataDir(get("/main/data_directory"));
        checkSanity();
    }
/*
    public void load(String xmlPath, String xsdPath) throws IOException, ConfigurationException {
        super.load(xmlPath, xsdPath);

    }
*/
    private void loadBouncers(String listOfBouncers) throws ConfigurationException {
        bouncers = new HashSet<InetAddress>();
        try {
            // if there are no bouncers, then we'll just have an empty set which will return quickly
            String[] bouncerIps = listOfBouncers.split("\\s+|,");
            for (int i = 0; i < bouncerIps.length; i++) {
                String bouncerIp = bouncerIps[i];
                if (bouncerIp != null && bouncerIp.length() > 0) {
                    bouncers.add(InetAddress.getByName(bouncerIp));
                }
            }
        } catch (UnknownHostException e) {
            throw new ConfigurationException("Failed to resolve bouncer address: " + e.getMessage(), e);
        }
    }

    public boolean isBouncer(Socket connection) {
        // no need to check for null, since we know that it'll never be null when we get it in here
        return bouncers.contains(connection.getInetAddress());
    }

    private void checkSanity() throws ConfigurationException {
        // check that the pasv_address resolves
        // note: the values returned by get() are already trim():ed
        try {
            final String s = get("/main/pasv_address");
            if (!"".equals(s)) {
                InetAddress.getByName(s);
            }
        } catch (UnknownHostException e) {
            throw new ConfigurationException("The supplied pasv_address did not resolve properly.", e);
        }
        try {
            final String s = get("/main/bind_address");
            if (!"".equals(s)) {
                InetAddress.getByName(s);
            }
        } catch (UnknownHostException e) {
            throw new ConfigurationException("The supplied bind_address did not resolve properly.", e);
        }

        try {
            final String s = get("/epsv/ipv4_bind_address");
            if (!"".equals(s)) {
                InetAddress.getByName(s);
            }
        } catch (UnknownHostException e) {
            throw new ConfigurationException("The supplied ipv4_bind_address did not resolve properly.", e);
        }
        try {
            final String s = get("/epsv/ipv6_bind_address");
            if (!"".equals(s)) {
                InetAddress.getByName(s);
            }
        } catch (UnknownHostException e) {
            throw new ConfigurationException("The supplied ipv6_bind_address did not resolve properly.", e);
        }
        // Note: moved section check to loadSections(), as it is now called externally

        if (!dataDirectory.exists() || !dataDirectory.isDirectory()) {
            throw new ConfigurationException("Could not find data_directory: " + dataDirectory.getAbsolutePath());
        }
        if (getInt("/user/authentication/type") == 2) {
            if (get("/user/authentication/remote/host") == null || get("/user/authentication/remote/port") == null || get("/user/authentication/remote/retry_interval") == null) {
                throw new ConfigurationException("must specify {host, port, retry_interval} when using remote authentication");
            }
        }
    }

    private void loadPasvPorts(String pasvPortsString) throws ConfigurationException {
        if (pasvPortsString != null) {
            String[] ports = pasvPortsString.split("-");
            try {
                if (ports.length == 2) {
                    pasvHighPort = Integer.parseInt(ports[1]);
                    pasvLowPort = Integer.parseInt(ports[0]);
                }
            } catch (Exception e) {
                throw new ConfigurationException("pasv_port_range is not defined properly, make sure it contains two numbers between 0 and 65536, connected by a dash '-'. For example: 1024-2048", e);
            }
        }
    }

    public int getNextPassivePort() {
        // read the ports, and when asked, just step then one at a time.
        // if no ports are specified, always return 0
        if (pasvHighPort > 0 && pasvHighPort > pasvLowPort && pasvLowPort > 0) {
            int i = random.nextInt(pasvHighPort-pasvLowPort) + pasvLowPort;
            //System.out.println("returning " + i + " as next passive port");
            return i;
        } else {
            return 0;
        }
    }

    private void loadDataDir(String dataDirectory) {
        this.dataDirectory = new File(dataDirectory);
    }

    public File getDataDirectory() {
        return dataDirectory;
    }

    @Override
    public String get(String attributePath) {
        return super.get(settingsNamespace + attributePath);
    }

    @Override
    public Node getNode(String attributePath) {
        return super.getNode(settingsNamespace + attributePath);
    }
}
TOP

Related Classes of cu.ftpd.FtpdSettings

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.