All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jradius.server.config.Configuration Maven / Gradle / Ivy

The newest version!
/**
 * JRadius - A RADIUS Server Java Adapter
 * Copyright (C) 2004-2005 PicoPoint, B.V.
 * Copyright (c) 2006 David Bird 
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

package net.jradius.server.config;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.net.URL;

import net.jradius.handler.chain.JRCommand;
import net.jradius.handler.chain.JRConfigParser;
import net.jradius.log.RadiusLog;
import net.jradius.log.RadiusLogger;
import net.jradius.realm.JRadiusRealmManager;
import net.jradius.realm.RealmFactory;
import net.jradius.session.JRadiusSessionManager;
import net.jradius.session.SessionFactory;
import net.jradius.session.SessionKeyProvider;

import org.apache.commons.chain.Catalog;
import org.apache.commons.chain.CatalogFactory;
import org.apache.commons.chain.Command;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.BeanFactoryAware;

/**
 * Reads JRadius configuration options and provides methods to access them
 * 
 * @author Gert Jan Verhoog
 * @author David Bird
 */
public class Configuration
{
    private static XMLConfiguration xmlCfg;
    private static HierarchicalConfiguration.Node root;

    private static boolean debug;
    private static int timeoutSeconds;
    private static File configFile;
    private static Map listeners = new LinkedHashMap();
    private static Map packetHandlers = new LinkedHashMap();
    private static Map eventHandlers = new LinkedHashMap();
    private static Map dictionaries = new LinkedHashMap();

    private static BeanFactory beanFactory;
    private static JRConfigParser parser = new JRConfigParser();
    private static CatalogFactory factory = CatalogFactory.getInstance();
    private static LogConfigurationItem logConfig;
    
    public static void initialize(File file) throws FileNotFoundException, ConfigurationException
    {        
        configFile = file;
        initialize(new FileInputStream(file), null);
    }
 
    public static void initialize(InputStream input, BeanFactory factory) throws FileNotFoundException, ConfigurationException
    {
        //let new initalization configure it's own logger
        logConfig = null;

        beanFactory = factory;
        xmlCfg = new XMLConfiguration(new InputStreamReader(input));
        root = xmlCfg.getRoot();
        
        RadiusLog.info("Configuring JRadius Server....");

        setLogConfig();
        setGeneralOptions();
        setRealmManagerConfig();
        setSessionManagerConfig();
        setDictionaryConfigs();
        setPacketHandlersConfigs();   
        setEventHandlersConfigs();   
        setListenerConfigs();
    }
 
    /**
     * Corresponds to the <debug>true/false</debug> configuration
     * option. If set to true, generate log messages for debugging.
     * @return true if debugging messages should be generated.
     */
    public static boolean isDebug()
    {
        return debug;
    }
    
    /**
     * @return configuration file directory
     */
    public static String getConfigFileDir()
    {
        if (configFile == null) return ".";
        String configFileDir = configFile.getParent();
        if (configFileDir == null) return ".";
        return configFileDir;
    }

    /**
     * A collection of PacketHandlerConfigurationItems, corresponding
     * to the <packet-handler> elements in the configuration file.
     * @return A collection of PacketHandlerConfigurationItems
     */
    public static Collection getPacketHandlers()
    {
        return packetHandlers.values();
    }

    /**
     * A collection of HandlerConfigurationItems, corresponding
     * to the <event-handler> elements in the configuration file.
     * @return A collection of HandlerConfigurationItems
     */
    public static Collection getEventHandlers()
    {
        return eventHandlers.values();
    }

    public static PacketHandlerConfigurationItem packetHandlerConfigurationForName(String name)
    {
        return (PacketHandlerConfigurationItem) packetHandlers.get(name);
    }
    
    public static HandlerConfigurationItem eventHandlerConfigurationForName(String name)
    {
        return (HandlerConfigurationItem) eventHandlers.get(name);
    }
    
    public static JRCommand packetHandlerForName(String name)
    {
        // XXX: our getCommand() will be replaced with factory.getCommand()
        return (JRCommand)getCommand(name);
    }
    
    public static JRCommand eventHandlerForName(String name)
    {
        // XXX: our getCommand() will be replaced with factory.getCommand()
        return (JRCommand)getCommand(name);
    }
    
    public static Command getCommand(String commandID) throws IllegalArgumentException 
    {
        // XXX: This function taken from CVS version of CatalogFactory
        String DELIMITER = ":";
        String commandName = commandID;
        String catalogName = null;
        Catalog catalog = null;

        if (commandID != null) 
        {
            int splitPos = commandID.indexOf(DELIMITER);
            if (splitPos != -1) 
            {
                catalogName = commandID.substring(0, splitPos);
                commandName = commandID.substring(splitPos + DELIMITER.length());
                if (commandName.indexOf(DELIMITER) != -1) 
                {
                    throw new IllegalArgumentException("commandID [" + commandID + "] has too many delimiters (reserved for future use)");
                }
            }
        }

        if (catalogName != null) 
        {
            catalog = factory.getCatalog(catalogName);
            if (catalog == null) 
            {
                RadiusLog.warn("No catalog found for name: " + catalogName + ".");
                return null;
            }
        } 
        else 
        {
            catalog = factory.getCatalog();
            if (catalog == null) 
            {
                RadiusLog.warn("No default catalog found.");
                return null;
            }
        }

        return catalog.getCommand(commandName);                    
    }

    /**
     * A collection of ListenerConfigurationItems, corresponding
     * to the <listener> elements in the configuration file.
     * @return A collection of ListenerConfigurationItems
     */
    public static Collection getListenerConfigs()
    {
        return listeners.values();
    }
    
    public static ListenerConfigurationItem listenerConfigurationForName(String name)
    {
        return (ListenerConfigurationItem) listeners.get(name);
    }

    /**
     * A collection of DictionaryConfigurationItems, corresponding
     * to the <load-dictionaries> elements in the configuration file.
     * @return A collection of DictionaryConfigurationItems
     */
    public static Collection getDictionaryConfigs()
    {
        return dictionaries.values();
    }
    
    public static DictionaryConfigurationItem dictionaryConfigurationForName(String name)
    {
        return (DictionaryConfigurationItem) dictionaries.get(name);
    }

    /**
     * The number of seconds to wait for packets, corresponding to
     * the <timeout> option in the configuration file. If
     * this is 0 (zero), wait indefinately (i.e. waiting will
     * never time out).
     * @return The number of seconds to wait for packets
     */
    public static int getTimeoutSeconds()
    {
        return timeoutSeconds;
    }
    
    private static void setGeneralOptions()
    {
        debug = xmlCfg.getConfigBoolean("debug");
        timeoutSeconds = xmlCfg.getConfigInt("timeout");

        List children = root.getChildren("chain-catalog");
        
        HierarchicalConfiguration.Node node;
        for (Iterator i = children.iterator(); i.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)i.next();
            xmlCfg.setRoot(node);
            
            String catalogURL = xmlCfg.getConfigString("name");
            
            if (catalogURL != null)
            {
                try
                {
                    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                    RadiusLog.debug("Loading Chains URL: " + catalogURL);

                    URL url = classLoader.getResource(catalogURL);

                    if (url == null)
                    {
                        RadiusLog.error("File " + catalogURL + " not found.");
                    }
                    else
                    {
                        boolean failure;

                        try
                        {
                            url.openStream().close();
                            failure = false;
                        }
                        catch(Exception e)
                        {
                            failure = true;
                        }

                        if(failure)
                        {
                            RadiusLog.error("file " + url + " not found.");
                        }
                        else
                        {
                            parser.parse(url);
                        }
                    }
                }
                catch (Exception e)
                {
                	RadiusLog.error("Error loading catalog chain.", e);
                }
            }
            
            xmlCfg.setRoot(root);
        }
    }

    private static void setDictionaryConfigs()
    {
        List children = root.getChildren(DictionaryConfigurationItem.XML_KEY);
        HierarchicalConfiguration.Node node;
        for (Iterator i = children.iterator(); i.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)i.next();
            xmlCfg.setRoot(node);
            DictionaryConfigurationItem item = new DictionaryConfigurationItem(node, xmlCfg);
            dictionaries.put(item.getName(), item);
            xmlCfg.setRoot(root);
        }
    }

    private static void setLogConfig()
    {
        List children = root.getChildren(LogConfigurationItem.XML_KEY);
        HierarchicalConfiguration.Node node;
        for (Iterator i = children.iterator(); i.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)i.next();
            xmlCfg.setRoot(node);
            if (logConfig != null)
            {
                RadiusLog.warn("A RadiusLogger is already configured, skipping configuration");
                return;
            }
            
            logConfig = new LogConfigurationItem(node, xmlCfg);
            
            // Setup the new logger now so that the rest of the configuration
            // takes use of the new logger.
            try
            {
                RadiusLogger logger = (RadiusLogger)Configuration.getBean(logConfig.getClassName());
                RadiusLog.setRadiusLogger(logger);
                RadiusLog.debug("Configuring RadiusLogger " + logConfig.getName() + ": " + logger.getClass().getName());
            }
            catch (Exception e)
            {
                RadiusLog.error(e.getMessage(), e);
                logConfig = null;
            }

            xmlCfg.setRoot(root);
        }
    }

    private static void setPacketHandlersConfigs()
    {
        List list = root.getChildren(PacketHandlerConfigurationItem.XML_LIST_KEY);
        HierarchicalConfiguration.Node node;
        for (Iterator l = list.iterator(); l.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)l.next();
            List children = node.getChildren(PacketHandlerConfigurationItem.XML_KEY);
            for (Iterator i = children.iterator(); i.hasNext();)
            {
                node = (HierarchicalConfiguration.Node)i.next();
                xmlCfg.setRoot(node);
                PacketHandlerConfigurationItem item = new PacketHandlerConfigurationItem(node, xmlCfg);
                packetHandlers.put(item.getName(),item);
                xmlCfg.setRoot(root);
            }
        }
    }

    private static void setEventHandlersConfigs()
    {
        List list = root.getChildren(HandlerConfigurationItem.XML_LIST_KEY);
        HierarchicalConfiguration.Node node;
        for (Iterator l = list.iterator(); l.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)l.next();
            List children = node.getChildren(HandlerConfigurationItem.XML_KEY);
            for (Iterator i = children.iterator(); i.hasNext();)
            {
                node = (HierarchicalConfiguration.Node)i.next();
                xmlCfg.setRoot(node);
                HandlerConfigurationItem item = new HandlerConfigurationItem(node, xmlCfg);
                eventHandlers.put(item.getName(),item);
                xmlCfg.setRoot(root);
            }
        }
    }

    private static void setListenerConfigs()
    {
        List list = root.getChildren(ListenerConfigurationItem.XML_LIST_KEY);
        HierarchicalConfiguration.Node node;
        for (Iterator l = list.iterator(); l.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)l.next();
            List children = node.getChildren(ListenerConfigurationItem.XML_KEY);
            for (Iterator i = children.iterator(); i.hasNext();)
            {
                node = (HierarchicalConfiguration.Node)i.next();
                xmlCfg.setRoot(node);
                ListenerConfigurationItem item = new ListenerConfigurationItem(node, xmlCfg);
                listeners.put(item.getName(),item);
                xmlCfg.setRoot(root);
            }
        }
    }
    
    private static final String SESSION_MANAGER_KEY 	= "session-manager";
    private static final String REALM_MANAGER_KEY 		= "realm-manager";
    private static final String REQUESTER_KEY 			= "requester";
    private static final String KEY_PROVIDER_KEY 		= "key-provider";
    private static final String SESSION_FACTORY_KEY 	= "session-factory";
    private static final String REALM_FACTORY_KEY 		= "realm-factory";
    
    private static void setSessionManagerConfig()
    {
        List list = root.getChildren(SESSION_MANAGER_KEY);
        
        RadiusLog.info("Initializing session manager");

        HierarchicalConfiguration.Node node;
        for (Iterator l = list.iterator(); l.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)l.next();
            xmlCfg.setRoot(node);
            
            String clazz = xmlCfg.getConfigString("class");
            String requester = xmlCfg.getConfigString(REQUESTER_KEY);
            String keyProvider = xmlCfg.getConfigString(KEY_PROVIDER_KEY);
            String sessionFactory = xmlCfg.getConfigString(SESSION_FACTORY_KEY);
            
            if (clazz != null)
            {
                try
                {
                    RadiusLog.debug("Session Manager (" + requester + "): " + clazz);
                    JRadiusSessionManager manager = (JRadiusSessionManager) getBean(clazz);
                    JRadiusSessionManager.setManager(requester, manager);
                }
                catch (Exception e)
                {
                    RadiusLog.error(e.getMessage(), e);
                }
            }
            
            if (keyProvider != null)
            {
                try
                {
                    RadiusLog.debug("Session Key Provider (" + requester + "): " + keyProvider);
                    SessionKeyProvider provider = (SessionKeyProvider) getBean(keyProvider);
                    JRadiusSessionManager.getManager(requester).setSessionKeyProvider(requester, provider);
                }
                catch (Exception e)
                {
                    RadiusLog.error(e.getMessage(), e);
                }
            }
            
            if (sessionFactory != null)
            {
                try
                {
                    RadiusLog.debug("Session Factory (" + requester + "): " + sessionFactory);
                    SessionFactory factory = (SessionFactory) getBean(sessionFactory);
                    factory.setConfig(xmlCfg, node);
                    JRadiusSessionManager.getManager(requester).setSessionFactory(requester, factory);
                }
                catch (Exception e)
                {
                    RadiusLog.error(e.getMessage(), e);
                }
            }
        }
    }

    public static Object getBean(String name) throws IllegalAccessException, ClassNotFoundException, InstantiationException
    {
        Object o = null;
        if (name == null) return null;
        if (name.startsWith("bean:")) 
        {
            String s[] = name.split(":");
            o = beanFactory.getBean(s[1]);    
        }
        else
        {
            Class clazz = Class.forName(name);
            if (clazz == null) return null;
            o = clazz.newInstance();
            if (o instanceof BeanFactoryAware)
            {
                try
                {
                    ((BeanFactoryAware)o).setBeanFactory(Configuration.beanFactory);
                }
                catch(Exception e)
                {
                    RadiusLog.warn("Error during bean initialization [BeanFactoryAware]", e);
                }
            }
            if (o instanceof InitializingBean)
            {
                try
                {
                    ((InitializingBean)o).afterPropertiesSet();
                }
                catch (Exception e)
                {
                    RadiusLog.warn("Error during bean initialization [InitializingBean]", e);
                }
            }
        }
        return o;
    }
    
    private static void setRealmManagerConfig()
    {
        List list = root.getChildren(REALM_MANAGER_KEY);
        
        RadiusLog.info("Initializing realm manager");

        HierarchicalConfiguration.Node node;
        for (Iterator l = list.iterator(); l.hasNext();)
        {
            node = (HierarchicalConfiguration.Node)l.next();
            xmlCfg.setRoot(node);
            
            String requester = xmlCfg.getConfigString(REQUESTER_KEY);
            String realmFactory = xmlCfg.getConfigString(REALM_FACTORY_KEY);
            
            if (realmFactory != null)
            {
                try
                {
                    RadiusLog.debug("Realm Factory (" + requester + "): " + realmFactory);
                    RealmFactory factory = (RealmFactory) getBean(realmFactory);
                    factory.setConfig(xmlCfg, node);
                    JRadiusRealmManager.getManager().setRealmFactory(requester, factory);
                }
                catch (Exception e)
                {
                    RadiusLog.error(e.getMessage(), e);
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy