Added plug-in capability for authentication mechanisms.
This commit is contained in:
		| @@ -0,0 +1,257 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  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; version 2.1 | ||||||
|  |  *  of the License. | ||||||
|  |  * | ||||||
|  |  *  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 | ||||||
|  |  *  Library 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, Novell, Inc. | ||||||
|  |  *  | ||||||
|  |  *  To contact Novell about this file by physical or electronic mail,  | ||||||
|  |  *  you may find current contact information at www.novell.com. | ||||||
|  |  *  | ||||||
|  |  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||||
|  |  *   | ||||||
|  |  ***********************************************************************/ | ||||||
|  |  | ||||||
|  | package com.novell.casa.authtoksvc; | ||||||
|  |  | ||||||
|  | import java.io.*; | ||||||
|  | import java.util.*; | ||||||
|  |  | ||||||
|  | import org.xml.sax.InputSource; | ||||||
|  | import org.xml.sax.SAXException; | ||||||
|  | import org.xml.sax.XMLReader; | ||||||
|  | import org.xml.sax.helpers.XMLReaderFactory; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * AuthMechConfig Class. | ||||||
|  |  *  | ||||||
|  |  * This class obtains and maintains authentication token configuration. | ||||||
|  |  *  | ||||||
|  |  */ | ||||||
|  | public class AuthMechConfig | ||||||
|  | { | ||||||
|  |    // Well known authentication token configuration settings | ||||||
|  |    public final static String ClassName = "ClassName"; | ||||||
|  |    public final static String RelativeClassPath = "RelativeClassPath"; | ||||||
|  |    public final static String ClassPath = "ClassPath"; | ||||||
|  |  | ||||||
|  |    private Map m_mechSettingsMap; | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Class for handling parsing events. | ||||||
|  |     */ | ||||||
|  |    private class SAXHandler extends org.xml.sax.helpers.DefaultHandler | ||||||
|  |    { | ||||||
|  |       private final static int AWAITING_ROOT_ELEMENT_START = 0; | ||||||
|  |       private final static int AWAITING_SETTING_ELEMENT_START = 1; | ||||||
|  |       private final static int AWAITING_SETTING_ELEMENT_DATA = 2; | ||||||
|  |       private final static int AWAITING_SETTING_ELEMENT_END = 3; | ||||||
|  |       private final static int DONE_PARSING = 4; | ||||||
|  |  | ||||||
|  |       private final static String m_rootElementName = "settings"; | ||||||
|  |  | ||||||
|  |       private Map    m_keyMap; | ||||||
|  |       private int    m_state; | ||||||
|  |       private String m_currentKey; | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * Constructor | ||||||
|  |        */ | ||||||
|  |       public SAXHandler(Map keyMap) | ||||||
|  |       { | ||||||
|  |          super(); | ||||||
|  |  | ||||||
|  |          // Initialize our members | ||||||
|  |          m_keyMap = keyMap; | ||||||
|  |          m_state = AWAITING_ROOT_ELEMENT_START; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * endDocument() implementation. | ||||||
|  |        */ | ||||||
|  |       public void endDocument () throws SAXException | ||||||
|  |       { | ||||||
|  |          // Verify that we are not in an invalid state | ||||||
|  |          if (m_state != DONE_PARSING) | ||||||
|  |          { | ||||||
|  |             System.err.println("AuthMechConfig SAXHandler.endDocument()- Invalid state" + m_state);  | ||||||
|  |             throw new SAXException("Invalid state at endDocument"); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * startElement() implementation. | ||||||
|  |        */ | ||||||
|  |       public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException | ||||||
|  |       { | ||||||
|  |          // Proceed based on our state | ||||||
|  |          switch (m_state) | ||||||
|  |          { | ||||||
|  |             case AWAITING_ROOT_ELEMENT_START: | ||||||
|  |                // Verify that we are processing the expected tag | ||||||
|  |                if (m_rootElementName.equals(qName)) | ||||||
|  |                { | ||||||
|  |                   // Advance to the next state | ||||||
|  |                   m_state = AWAITING_SETTING_ELEMENT_START; | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   System.err.println("AuthMechConfig SAXHandler.startElement()- Un-expected element");  | ||||||
|  |                   throw new SAXException("Un-expected element"); | ||||||
|  |                } | ||||||
|  |                break; | ||||||
|  |  | ||||||
|  |             case AWAITING_SETTING_ELEMENT_START: | ||||||
|  |                // Keep track of the key name | ||||||
|  |                m_currentKey = qName; | ||||||
|  |  | ||||||
|  |                // Advance to the next state | ||||||
|  |                m_state = AWAITING_SETTING_ELEMENT_DATA; | ||||||
|  |                break; | ||||||
|  |  | ||||||
|  |             default: | ||||||
|  |                System.err.println("AuthMechConfig SAXHandler.startElement()- Invalid state " + m_state);  | ||||||
|  |                throw new SAXException("Invalid state at startElement"); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * endElement() immplementation. | ||||||
|  |        */ | ||||||
|  |       public void endElement (String uri, String name, String qName) throws SAXException | ||||||
|  |       { | ||||||
|  |          // Proceed based on our state | ||||||
|  |          switch (m_state) | ||||||
|  |          { | ||||||
|  |             case AWAITING_SETTING_ELEMENT_END: | ||||||
|  |                // Advance to the next state | ||||||
|  |                m_state = AWAITING_SETTING_ELEMENT_START; | ||||||
|  |                break; | ||||||
|  |  | ||||||
|  |             case AWAITING_SETTING_ELEMENT_START: | ||||||
|  |                // Verify that we are processing the expected tag | ||||||
|  |                if (m_rootElementName.equals(qName)) | ||||||
|  |                { | ||||||
|  |                   // Advance to the next state | ||||||
|  |                   m_state = DONE_PARSING; | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   System.err.println("AuthMechConfig SAXHandler.endElement()- Un-expected element");  | ||||||
|  |                   throw new SAXException("Un-expected element"); | ||||||
|  |                } | ||||||
|  |                break; | ||||||
|  |  | ||||||
|  |             default: | ||||||
|  |                System.err.println("AuthMechConfig SAXHandler.endElement()- Invalid state " + m_state);  | ||||||
|  |                throw new SAXException("Invalid state at endElement"); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       /* | ||||||
|  |        * character() implementation. | ||||||
|  |        */ | ||||||
|  |       public void characters (char ch[], int start, int length) throws SAXException | ||||||
|  |       { | ||||||
|  |          // Consume the data if in the right state | ||||||
|  |          if (m_state == AWAITING_SETTING_ELEMENT_DATA) | ||||||
|  |          { | ||||||
|  |             // Consume the data and add the key to map | ||||||
|  |             m_keyMap.put(m_currentKey, new String(ch, start, length)); | ||||||
|  |  | ||||||
|  |             // Advance to the next state | ||||||
|  |             m_state = AWAITING_SETTING_ELEMENT_END; | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Constructor which sets default configuration values. | ||||||
|  |     */ | ||||||
|  |    public AuthMechConfig() throws Exception | ||||||
|  |    { | ||||||
|  |       System.err.println("AuthMechConfig()- Default"); | ||||||
|  |  | ||||||
|  |       // Create a map to keep track of the token settings | ||||||
|  |       m_mechSettingsMap = new HashMap(); | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Constructor. | ||||||
|  |     */ | ||||||
|  |    public AuthMechConfig(String mechSettingsFileName) throws Exception | ||||||
|  |    { | ||||||
|  |       System.err.println("AuthMechConfig()-"); | ||||||
|  |  | ||||||
|  |       // Create a map to keep track of the token settings | ||||||
|  |       m_mechSettingsMap = new HashMap(); | ||||||
|  |  | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          // Get an input stream to read from the token settings file | ||||||
|  |          File f = new File(mechSettingsFileName); | ||||||
|  |          FileInputStream inStream = new FileInputStream(f); | ||||||
|  |  | ||||||
|  |          // Parse the file | ||||||
|  |          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||||
|  |          SAXHandler handler = new SAXHandler(m_mechSettingsMap); | ||||||
|  |          xr.setContentHandler(handler); | ||||||
|  |          xr.setErrorHandler(handler); | ||||||
|  |           | ||||||
|  |          InputSource source = new InputSource(inStream); | ||||||
|  |          xr.parse(source); | ||||||
|  |  | ||||||
|  |          inStream.close(); | ||||||
|  |       } | ||||||
|  |       catch (SAXException e) | ||||||
|  |       { | ||||||
|  |         System.err.println("AuthMechConfig()- " + mechSettingsFileName + " format error, exception: " + e.toString());  | ||||||
|  |         throw new Exception("AuthMechConfig()- authtoken.settings format error"); | ||||||
|  |       } | ||||||
|  |       catch (SecurityException e) | ||||||
|  |       { | ||||||
|  |          System.err.println("AuthMechConfig()- SecurityException accessing " + mechSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |          throw new Exception("AuthMechConfig()- Not able to access file"); | ||||||
|  |       } | ||||||
|  |       catch (FileNotFoundException e) | ||||||
|  |       { | ||||||
|  |          System.err.println("AuthMechConfig()- File " + mechSettingsFileName + " not found"); | ||||||
|  |          throw new Exception("AuthMechConfig()- File not found"); | ||||||
|  |       } | ||||||
|  |       catch (IOException e) | ||||||
|  |       { | ||||||
|  |          System.err.println("AuthMechConfig()- IOException accessing " + mechSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |          throw new Exception("AuthMechConfig()- Read error"); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Returns the value associated with the specified setting. | ||||||
|  |     */ | ||||||
|  |    public String getSetting(String settingName) throws Exception | ||||||
|  |    { | ||||||
|  |       // Try to find the setting in our map | ||||||
|  |       String value = (String) m_mechSettingsMap.get(settingName); | ||||||
|  |       if (value == null) | ||||||
|  |       { | ||||||
|  |          System.err.println("AuthMechConfig.getSetting()- Did not find setting " + settingName); | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          System.err.println("AuthMechConfig.getSetting()- Found setting " + settingName); | ||||||
|  |          System.err.println("AuthMechConfig.getSetting()- Setting value = " + value); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       return value; | ||||||
|  |    } | ||||||
|  | } | ||||||
| @@ -28,13 +28,17 @@ package com.novell.casa.authtoksvc; | |||||||
|  * AuthMechanism Interface. |  * AuthMechanism Interface. | ||||||
|  *  |  *  | ||||||
|  * This is the interface implemented by Authentication Mechanisms. |  * This is the interface implemented by Authentication Mechanisms. | ||||||
|  |  * | ||||||
|  |  * Please note that Authentication Machanisms must also implement the | ||||||
|  |  * Serializable interface. | ||||||
|  |  * | ||||||
|  */ |  */ | ||||||
| public interface AuthMechanism | public interface AuthMechanism | ||||||
| { | { | ||||||
|    /* |    /* | ||||||
|     * Initialize the authentication mechanism. |     * Initialize the authentication mechanism. | ||||||
|     */ |     */ | ||||||
|    void init(SvcConfig svcConfig) throws Exception; |    void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception; | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|     * Process authenticate request. If successful, return the Id of the |     * Process authenticate request. If successful, return the Id of the | ||||||
|   | |||||||
| @@ -0,0 +1,351 @@ | |||||||
|  | /*********************************************************************** | ||||||
|  |  *  | ||||||
|  |  *  Copyright (C) 2006 Novell, Inc. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  *  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; version 2.1 | ||||||
|  |  *  of the License. | ||||||
|  |  * | ||||||
|  |  *  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 | ||||||
|  |  *  Library 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, Novell, Inc. | ||||||
|  |  *  | ||||||
|  |  *  To contact Novell about this file by physical or electronic mail,  | ||||||
|  |  *  you may find current contact information at www.novell.com. | ||||||
|  |  *  | ||||||
|  |  *  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||||
|  |  *   | ||||||
|  |  ***********************************************************************/ | ||||||
|  |  | ||||||
|  | package com.novell.casa.authtoksvc; | ||||||
|  |  | ||||||
|  | import java.util.*; | ||||||
|  | import java.io.*; | ||||||
|  |  | ||||||
|  | import java.io.ObjectOutputStream; | ||||||
|  | import java.io.ObjectInputStream; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.io.InputStream; | ||||||
|  | import java.io.PrintWriter; | ||||||
|  |  | ||||||
|  | import java.net.URL; | ||||||
|  | import java.net.MalformedURLException; | ||||||
|  | import java.net.URLClassLoader; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Authenticate Class. | ||||||
|  |  *  | ||||||
|  |  * This class processes authentication requests. | ||||||
|  |  *  | ||||||
|  |  */ | ||||||
|  | public class Authenticate implements RpcMethod | ||||||
|  | { | ||||||
|  |    private static final String   sessionTokenLifetime = "360"; // tbd - Obtain from configuration | ||||||
|  |  | ||||||
|  |    private static final String   m_mechanismSettingsFileName = "mechanism.settings"; | ||||||
|  |  | ||||||
|  |    private Map m_authMechanismMap; | ||||||
|  |  | ||||||
|  |    private SvcConfig          m_svcConfig; | ||||||
|  |    private EnabledSvcsConfig  m_enabledSvcsConfig; | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Constructor | ||||||
|  |     */ | ||||||
|  |    public Authenticate() throws Exception | ||||||
|  |    { | ||||||
|  |       // Create a map to keep track of the authentication mechanisms | ||||||
|  |       m_authMechanismMap = new HashMap(); | ||||||
|  |    }      | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Initialize the Rpc method. | ||||||
|  |     */ | ||||||
|  |    public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception | ||||||
|  |    { | ||||||
|  |       m_svcConfig = svcConfig; | ||||||
|  |       m_enabledSvcsConfig = enabledSvcsConfig; | ||||||
|  |  | ||||||
|  |       // Now go through the configured authentication mechanisms, as we do so, instantiate | ||||||
|  |       // the mechanisms and place them in our map. Note that the mechanisms config folder | ||||||
|  |       // contains folders for each installed authentication mechanism. The name of these | ||||||
|  |       // folders usually match the name of the Authentication mechanisms. | ||||||
|  |       String svcConfigPath = svcConfig.getSetting(SvcConfig.ConfigFolderPath); | ||||||
|  |       File mechanismsConfigFolder = new File(svcConfigPath + "/auth_mechanisms"); | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          String[] mechanismsConfigFolderObjs = mechanismsConfigFolder.list(); | ||||||
|  |          if (mechanismsConfigFolderObjs != null) | ||||||
|  |          { | ||||||
|  |             for (int i = 0; i < mechanismsConfigFolderObjs.length; i++) | ||||||
|  |             { | ||||||
|  |                // Check if we are dealing with a file or a folder | ||||||
|  |                File mechanismFolder = new File(mechanismsConfigFolder, mechanismsConfigFolderObjs[i]); | ||||||
|  |                try | ||||||
|  |                { | ||||||
|  |                   if (mechanismFolder.isDirectory() == true) | ||||||
|  |                   { | ||||||
|  |                      System.err.println("Authenticate.init()- Mechanism folder " + mechanismFolder + " is directory"); | ||||||
|  |  | ||||||
|  |                      // Try to obtain the mechanism settings | ||||||
|  |                      try | ||||||
|  |                      { | ||||||
|  |                         AuthMechConfig mechConfig = new AuthMechConfig(mechanismFolder + "/" + m_mechanismSettingsFileName); | ||||||
|  |  | ||||||
|  |                         // Mechanism settings obtained, now instantiate it and place it in our map. | ||||||
|  |                         // | ||||||
|  |                         String mechClassName = mechConfig.getSetting(AuthMechConfig.ClassName); | ||||||
|  |                         if (mechClassName != null) | ||||||
|  |                         { | ||||||
|  |                            // We now know the name of the class implementing the mechanism, now lets | ||||||
|  |                            // get the relative path to the class file. Note that the path is relative | ||||||
|  |                            // to the root folder of our application. | ||||||
|  |                            String relativePath = mechConfig.getSetting(AuthMechConfig.RelativeClassPath); | ||||||
|  |                            if (relativePath != null) | ||||||
|  |                            { | ||||||
|  |                               // Create a file object to the folder containing the class file. Note that we need to | ||||||
|  |                               // ultimately instantiate objects from a class loaded by the same class loader that | ||||||
|  |                               // loads the AuthMechanism class to avoid ClassCastExceptions. | ||||||
|  |                               File mechClassPathFile = new File(svcConfig.getSetting(SvcConfig.AppRootPath) + relativePath); | ||||||
|  |                               System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile); | ||||||
|  |                               try | ||||||
|  |                               { | ||||||
|  |                                  URL methClassPathUrl = mechClassPathFile.toURL(); | ||||||
|  |                                  URL[] urls = new URL[]{methClassPathUrl}; | ||||||
|  |  | ||||||
|  |                                  // Create a class loader for the folder | ||||||
|  |                                  ClassLoader customClassLoader = new URLClassLoader(urls); | ||||||
|  |  | ||||||
|  |                                  // Load the mech class using our custom loader | ||||||
|  |                                  Class mechClass = customClassLoader.loadClass(mechClassName); | ||||||
|  |                                  FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp"); | ||||||
|  |                                  ObjectOutputStream oos = new ObjectOutputStream(fos); | ||||||
|  |                                  oos.writeObject(mechClass); | ||||||
|  |                                  oos.close(); | ||||||
|  |                                  fos.close(); | ||||||
|  |                                  FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp"); | ||||||
|  |                                  ObjectInputStream ois = new ObjectInputStream(fis); | ||||||
|  |                                  mechClass = (Class) ois.readObject(); | ||||||
|  |                                  ois.close(); | ||||||
|  |                                  fis.close(); | ||||||
|  |                                   | ||||||
|  |                                  // Now reload the class using the class loader for our AuthMechanism class | ||||||
|  |                                  AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance(); | ||||||
|  |                                  mechanism.init(svcConfig, mechConfig); | ||||||
|  |                                  m_authMechanismMap.put(mechanism.getId(), mechanism); | ||||||
|  |                               } | ||||||
|  |                               catch (MalformedURLException e) | ||||||
|  |                               { | ||||||
|  |                                  System.err.println("Authenticate.init()- MalformedURLException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                               } | ||||||
|  |                               catch (ClassNotFoundException e) | ||||||
|  |                               { | ||||||
|  |                                  System.err.println("Authenticate.init()- ClassNotFoundException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                               } | ||||||
|  |                               catch (InstantiationException e) | ||||||
|  |                               { | ||||||
|  |                                  System.err.println("Authenticate.init()- InstantiationException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                               } | ||||||
|  |                               catch (IllegalAccessException e) | ||||||
|  |                               { | ||||||
|  |                                  System.err.println("Authenticate.init()- IllegalAccessException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                               } | ||||||
|  |                            } | ||||||
|  |                            else | ||||||
|  |                            { | ||||||
|  |                               // A relative path was not configured, check if instead a full path was configured. | ||||||
|  |                               String classPath = mechConfig.getSetting(AuthMechConfig.ClassPath); | ||||||
|  |                               if (classPath != null) | ||||||
|  |                               { | ||||||
|  |                                  // Create a file object to the folder containing the class file. Note that we need to | ||||||
|  |                                  // ultimately instantiate objects from a class loaded by the same class loader that | ||||||
|  |                                  // loads the AuthMechanism class to avoid ClassCastExceptions. | ||||||
|  |                                  File mechClassPathFile = new File(classPath); | ||||||
|  |                                  System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile); | ||||||
|  |                                  try | ||||||
|  |                                  { | ||||||
|  |                                     URL methClassPathUrl = mechClassPathFile.toURL(); | ||||||
|  |                                     URL[] urls = new URL[]{methClassPathUrl}; | ||||||
|  |  | ||||||
|  |                                     // Create a class loader for the folder | ||||||
|  |                                     ClassLoader customClassLoader = new URLClassLoader(urls); | ||||||
|  |  | ||||||
|  |                                     // Load the mech class using our custom loader | ||||||
|  |                                     Class mechClass = customClassLoader.loadClass(mechClassName); | ||||||
|  |                                     FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp"); | ||||||
|  |                                     ObjectOutputStream oos = new ObjectOutputStream(fos); | ||||||
|  |                                     oos.writeObject(mechClass); | ||||||
|  |                                     oos.close(); | ||||||
|  |                                     fos.close(); | ||||||
|  |                                     FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp"); | ||||||
|  |                                     ObjectInputStream ois = new ObjectInputStream(fis); | ||||||
|  |                                     mechClass = (Class) ois.readObject(); | ||||||
|  |                                     ois.close(); | ||||||
|  |                                     fis.close(); | ||||||
|  |  | ||||||
|  |                                     // Now reload the class using the class loader for our AuthMechanism class | ||||||
|  |                                     AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance(); | ||||||
|  |                                     mechanism.init(svcConfig, mechConfig); | ||||||
|  |                                     m_authMechanismMap.put(mechanism.getId(), mechanism); | ||||||
|  |                                  } | ||||||
|  |                                  catch (MalformedURLException e) | ||||||
|  |                                  { | ||||||
|  |                                     System.err.println("Authenticate.init()- MalformedURLException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                                  } | ||||||
|  |                                  catch (ClassNotFoundException e) | ||||||
|  |                                  { | ||||||
|  |                                     System.err.println("Authenticate.init()- ClassNotFoundException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                                  } | ||||||
|  |                                  catch (InstantiationException e) | ||||||
|  |                                  { | ||||||
|  |                                     System.err.println("Authenticate.init()- InstantiationException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                                  } | ||||||
|  |                                  catch (IllegalAccessException e) | ||||||
|  |                                  { | ||||||
|  |                                     System.err.println("Authenticate.init()- IllegalAccessException for "  + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                                  } | ||||||
|  |                               } | ||||||
|  |                               else | ||||||
|  |                               { | ||||||
|  |                                  System.err.println("Authenticate.init()- No configuration to find class path to load "  + mechanismFolder + "/" + m_mechanismSettingsFileName); | ||||||
|  |                               } | ||||||
|  |                            } | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                            System.err.println("Authenticate.init()- No configured mechanism class name for "  + mechanismFolder + "/" + m_mechanismSettingsFileName); | ||||||
|  |                         } | ||||||
|  |                      } | ||||||
|  |                      catch (SecurityException e) | ||||||
|  |                      { | ||||||
|  |                         System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                      } | ||||||
|  |                      catch (FileNotFoundException e) | ||||||
|  |                      { | ||||||
|  |                         System.err.println("Authenticate.init()- No authentication policy file for " + mechanismFolder); | ||||||
|  |                      } | ||||||
|  |                      catch (IOException e) | ||||||
|  |                      { | ||||||
|  |                         System.err.println("Authenticate.init()- IOException reading " + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                      } | ||||||
|  |                      catch (Exception e) | ||||||
|  |                      { | ||||||
|  |                         System.err.println("Authenticate.init()- Exception instantiating mechConfig or mechanism " + mechanismFolder + "/" + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||||
|  |                      } | ||||||
|  |                   } | ||||||
|  |                } | ||||||
|  |                catch (SecurityException e) | ||||||
|  |                { | ||||||
|  |                   System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + " Exception=" + e.toString()); | ||||||
|  |                } | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             System.err.println("Authenticate.init()- Unable to obtain mechanisms folder " + mechanismsConfigFolder + " objects"); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       catch (SecurityException e) | ||||||
|  |       { | ||||||
|  |          System.err.println("Authenticate.init()- SecurityException accessing " + mechanismsConfigFolder + " Exception=" + e.toString()); | ||||||
|  |       } | ||||||
|  |       /*// tbd - make pluggable. | ||||||
|  |       AuthMechanism krb5Mech = new Krb5Authenticate(); | ||||||
|  |       krb5Mech.init(svcConfig); | ||||||
|  |       m_authMechanismMap.put(krb5Mech.getId(), krb5Mech); | ||||||
|  |  | ||||||
|  |       AuthMechanism pwdMech = new PwdAuthenticate(); | ||||||
|  |       pwdMech.init(svcConfig); | ||||||
|  |       m_authMechanismMap.put(pwdMech.getId(), pwdMech);*/ | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Process Rpc. | ||||||
|  |     */ | ||||||
|  |    public void invoke(InputStream inStream, PrintWriter out) throws IOException | ||||||
|  |    { | ||||||
|  |       try | ||||||
|  |       { | ||||||
|  |          System.err.println("Authenticate.invoke()"); | ||||||
|  |  | ||||||
|  |          // Parse the AuthReqMsg sent from the client | ||||||
|  |          AuthReqMsg authReqMsg = new AuthReqMsg(inStream); | ||||||
|  |  | ||||||
|  |          // Get the necessary authentication mechanism | ||||||
|  |          AuthMechanism authMechanism = (AuthMechanism) m_authMechanismMap.get(authReqMsg.getMechanismId()); | ||||||
|  |          if (authMechanism != null) | ||||||
|  |          { | ||||||
|  |             // Invoke the mechanism to authenticate the entity | ||||||
|  |             String identId = authMechanism.invoke(authReqMsg); | ||||||
|  |  | ||||||
|  |             // Create response based on the identity resolution results | ||||||
|  |             if (identId != null && identId.length() != 0) | ||||||
|  |             { | ||||||
|  |                System.err.println("Authenticate.invoke()- identId resolved"); | ||||||
|  |  | ||||||
|  |                // An identity was resolved, get a SessionToken for it. | ||||||
|  |                SessionToken sessionToken = new SessionToken(identId, | ||||||
|  |                                                             authReqMsg.getRealm(), | ||||||
|  |                                                             m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime)); | ||||||
|  |  | ||||||
|  |                // Write out the response | ||||||
|  |                AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg, | ||||||
|  |                                                          ProtoDefs.httpOkStatusCode, | ||||||
|  |                                                          sessionToken.toString(), | ||||||
|  |                                                          m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime)); | ||||||
|  |                // tbd - Convert to ints, perform calculation, and then convert result to string | ||||||
|  |                //m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime) | ||||||
|  |                //- m_svcConfig.getSetting(SvcConfig.LifetimeShorter)); | ||||||
|  |                out.println(authRespMsg.toString()); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                System.err.println("Authenticate.invoke()- identId not resolved"); | ||||||
|  |  | ||||||
|  |                // Write out the response | ||||||
|  |                AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg, | ||||||
|  |                                                          ProtoDefs.httpUnauthorizedStatusCode); | ||||||
|  |                out.println(authRespMsg.toString()); | ||||||
|  |             } | ||||||
|  |          } | ||||||
|  |          else | ||||||
|  |          { | ||||||
|  |             System.err.println("Authenticate.invoke()- Unsupported mechanism " + authReqMsg.getMechanismId()); | ||||||
|  |  | ||||||
|  |             // Write out the response | ||||||
|  |             AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpNotFoundStatusMsg, | ||||||
|  |                                                       ProtoDefs.httpNotFoundStatusCode); | ||||||
|  |             out.println(authRespMsg.toString()); | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |       catch (Exception e) | ||||||
|  |       { | ||||||
|  |          System.err.println("Authenticate.invoke()- Exception: " + e.toString());  | ||||||
|  |  | ||||||
|  |          // Write out the response | ||||||
|  |          try | ||||||
|  |          { | ||||||
|  |             AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg, | ||||||
|  |                                                       ProtoDefs.httpServerErrorStatusCode); | ||||||
|  |             out.println(authRespMsg.toString()); | ||||||
|  |          } | ||||||
|  |          catch (Exception e2) | ||||||
|  |          { | ||||||
|  |             System.err.println("Authenticate.invoke()- Exception trying to construct response msg: " + e2.toString());  | ||||||
|  |          } | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    /* | ||||||
|  |     * Return the method id. | ||||||
|  |     */ | ||||||
|  |    public String getId() | ||||||
|  |    { | ||||||
|  |       return "Authenticate"; | ||||||
|  |    } | ||||||
|  | } | ||||||
| @@ -74,7 +74,6 @@ public class EnabledSvcsConfig | |||||||
|    public EnabledSvcsConfig(String svcConfigPath) throws Exception |    public EnabledSvcsConfig(String svcConfigPath) throws Exception | ||||||
|    { |    { | ||||||
|       System.err.println("EnabledSvcsConfig()-"); |       System.err.println("EnabledSvcsConfig()-"); | ||||||
|  |  | ||||||
|       System.err.println("EnabledSvcsConfig()- SvcConfigPath = " + svcConfigPath); |       System.err.println("EnabledSvcsConfig()- SvcConfigPath = " + svcConfigPath); | ||||||
|  |  | ||||||
|       // Initialize the default auth policy, authtoken, and identtoken configs. |       // Initialize the default auth policy, authtoken, and identtoken configs. | ||||||
| @@ -144,7 +143,7 @@ public class EnabledSvcsConfig | |||||||
|          // contains folders for each host for which there are enabled services. The folders |          // contains folders for each host for which there are enabled services. The folders | ||||||
|          // in the services config folder must match the DNS name of the hosts where |          // in the services config folder must match the DNS name of the hosts where | ||||||
|          // the enabled services reside. |          // the enabled services reside. | ||||||
|          File servicesConfigFolder = new File(svcConfigPath + "/services"); |          File servicesConfigFolder = new File(svcConfigPath + "/enabled_services"); | ||||||
|          try |          try | ||||||
|          { |          { | ||||||
|             String[] servicesConfigFolderObjs = servicesConfigFolder.list(); |             String[] servicesConfigFolderObjs = servicesConfigFolder.list(); | ||||||
| @@ -277,9 +276,6 @@ public class EnabledSvcsConfig | |||||||
|          { |          { | ||||||
|             System.err.println("EnabledSvcsConfig()- SecurityException accessing " + servicesConfigFolder + " Exception=" + e.toString()); |             System.err.println("EnabledSvcsConfig()- SecurityException accessing " + servicesConfigFolder + " Exception=" + e.toString()); | ||||||
|          } |          } | ||||||
|  |  | ||||||
|          // Now go through the services configured as enabled. Note that a service is configured as enabled by |  | ||||||
|          // placing a folder in our conf directory with a name that matches the service's name. |  | ||||||
|       } |       } | ||||||
|       catch (SecurityException e) |       catch (SecurityException e) | ||||||
|       { |       { | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ | |||||||
|  |  | ||||||
| package com.novell.casa.authtoksvc; | package com.novell.casa.authtoksvc; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||||
| @@ -56,9 +57,12 @@ import org.bandit.ia.IAContext; | |||||||
|  * Kerberos5 token. |  * Kerberos5 token. | ||||||
|  *  |  *  | ||||||
|  */ |  */ | ||||||
| public class Krb5Authenticate implements AuthMechanism | public class Krb5Authenticate implements AuthMechanism, Serializable | ||||||
| { | { | ||||||
|    private SvcConfig          m_svcConfig; |    private static final String ServicePrincipalNameSetting = "ServicePrincipalName"; | ||||||
|  |  | ||||||
|  |    private SvcConfig       m_svcConfig; | ||||||
|  |    private AuthMechConfig  m_mechConfig; | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|     * GSS Long Lived variables |     * GSS Long Lived variables | ||||||
| @@ -128,37 +132,45 @@ public class Krb5Authenticate implements AuthMechanism | |||||||
|    /* |    /* | ||||||
|     * Initialize the mechanism. |     * Initialize the mechanism. | ||||||
|     */ |     */ | ||||||
|    public void init(SvcConfig svcConfig) throws Exception |    public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception | ||||||
|    { |    { | ||||||
|       m_svcConfig = svcConfig; |       m_svcConfig = svcConfig; | ||||||
|  |       m_mechConfig = mechConfig; | ||||||
|  |  | ||||||
|       try |       String servicePrincipal = mechConfig.getSetting(ServicePrincipalNameSetting); | ||||||
|  |       if (servicePrincipal != null) | ||||||
|       { |       { | ||||||
|          // Initalize our GSS variables |          try | ||||||
|          // |          { | ||||||
|          // Get an instance of the default GSSManager |             // Initalize our GSS variables | ||||||
|          m_manager = GSSManager.getInstance(); |             // | ||||||
|  |             // Get an instance of the default GSSManager | ||||||
|  |             m_manager = GSSManager.getInstance(); | ||||||
|  |  | ||||||
|          // Create an OID specifying the Krb5 mechanism |             // Create an OID specifying the Krb5 mechanism | ||||||
|          m_krb5 = new Oid("1.2.840.113554.1.2.2"); |             m_krb5 = new Oid("1.2.840.113554.1.2.2"); | ||||||
|  |  | ||||||
|          // Create our host based service name |             // Create our host based service name | ||||||
|          // tbd - obtain the service name from configuration |             m_svcName = m_manager.createName(servicePrincipal, | ||||||
|          //GSSName svcName = manager.createName(ourServiceName, GSSName.NT_HOSTBASED_SERVICE, krb5); |                                              GSSName.NT_HOSTBASED_SERVICE,  | ||||||
|          m_svcName = m_manager.createName("host@jcstation.dnsdhcp.provo.novell.com", |                                              m_krb5); | ||||||
|                                           GSSName.NT_HOSTBASED_SERVICE,  |  | ||||||
|                                           m_krb5); |  | ||||||
|  |  | ||||||
|          // Now acquire our credentials |             // Now acquire our credentials | ||||||
|          m_credential = m_manager.createCredential(m_svcName,  |             m_credential = m_manager.createCredential(m_svcName,  | ||||||
|                                                    GSSCredential.INDEFINITE_LIFETIME,  |                                                       GSSCredential.INDEFINITE_LIFETIME,  | ||||||
|                                                    m_krb5,  |                                                       m_krb5,  | ||||||
|                                                    GSSCredential.ACCEPT_ONLY); |                                                       GSSCredential.ACCEPT_ONLY); | ||||||
|  |          } | ||||||
|  |          catch (GSSException e) | ||||||
|  |          { | ||||||
|  |             System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage()); | ||||||
|  |             throw new Exception("Failed to instantiate needed GSS objects"); | ||||||
|  |          } | ||||||
|       } |       } | ||||||
|       catch (GSSException e) |       else | ||||||
|       { |       { | ||||||
|          System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage()); |          System.err.println("Krb5Authenticate()- Service Principal Name not configured"); | ||||||
|          throw new Exception("Failed to instantiate needed GSS objects"); |          throw new Exception("Service Principal Name not configured"); | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ | |||||||
|  |  | ||||||
| package com.novell.casa.authtoksvc; | package com.novell.casa.authtoksvc; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStream; | import java.io.InputStream; | ||||||
| @@ -52,9 +53,10 @@ import org.bandit.ia.IAContext; | |||||||
|  * username/password token. |  * username/password token. | ||||||
|  *  |  *  | ||||||
|  */ |  */ | ||||||
| public class PwdAuthenticate implements AuthMechanism | public class PwdAuthenticate implements AuthMechanism, Serializable | ||||||
| { | { | ||||||
|    private SvcConfig          m_svcConfig; |    private SvcConfig       m_svcConfig; | ||||||
|  |    private AuthMechConfig  m_mechConfig; | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|     * Password Token Class. |     * Password Token Class. | ||||||
| @@ -111,9 +113,10 @@ public class PwdAuthenticate implements AuthMechanism | |||||||
|    /* |    /* | ||||||
|     * Initialize the mechanism. |     * Initialize the mechanism. | ||||||
|     */ |     */ | ||||||
|    public void init(SvcConfig svcConfig) throws Exception |    public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception | ||||||
|    { |    { | ||||||
|       m_svcConfig = svcConfig; |       m_svcConfig = svcConfig; | ||||||
|  |       m_mechConfig = mechConfig; | ||||||
|    } |    } | ||||||
|  |  | ||||||
|    /* |    /* | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ public class Rpc extends javax.servlet.http.HttpServlet implements javax.servlet | |||||||
|          ServletContext context = config.getServletContext(); |          ServletContext context = config.getServletContext(); | ||||||
|  |  | ||||||
|          // Read service configuration |          // Read service configuration | ||||||
|          SvcConfig svcConfig = new SvcConfig(context.getRealPath("/") + "WEB-INF/conf"); |          SvcConfig svcConfig = new SvcConfig(context.getRealPath("/"), context.getRealPath("/") + "WEB-INF/conf"); | ||||||
|  |  | ||||||
|          // Read enabled services configuration |          // Read enabled services configuration | ||||||
|          EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(context.getRealPath("/") + "WEB-INF/conf"); |          EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(context.getRealPath("/") + "WEB-INF/conf"); | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ public class SvcConfig | |||||||
|    public final static String IdentityAbstractionConfigFile = "IAConfigFile"; |    public final static String IdentityAbstractionConfigFile = "IAConfigFile"; | ||||||
|    public final static String StartSearchContext = "startSearchContext"; |    public final static String StartSearchContext = "startSearchContext"; | ||||||
|    public final static String ConfigFolderPath = "ConfigFolderPath"; |    public final static String ConfigFolderPath = "ConfigFolderPath"; | ||||||
|  |    public final static String AppRootPath = "AppRootPath"; | ||||||
|  |  | ||||||
|    // Default configuration values |    // Default configuration values | ||||||
|    private String m_defaultSessionTokenLifetimeValue = "360";  // Seconds |    private String m_defaultSessionTokenLifetimeValue = "360";  // Seconds | ||||||
| @@ -190,7 +191,7 @@ public class SvcConfig | |||||||
|    /* |    /* | ||||||
|     * Constructor. |     * Constructor. | ||||||
|     */ |     */ | ||||||
|    public SvcConfig(String svcConfigPath) throws Exception |    public SvcConfig(String appRootPath, String svcConfigPath) throws Exception | ||||||
|    { |    { | ||||||
|       System.err.println("SvcConfig()-"); |       System.err.println("SvcConfig()-"); | ||||||
|  |  | ||||||
| @@ -215,7 +216,8 @@ public class SvcConfig | |||||||
|          xr.parse(source); |          xr.parse(source); | ||||||
|          inStream.close(); |          inStream.close(); | ||||||
|  |  | ||||||
|          // Add the config folder path setting to our map |          // Add the application and config folder path settings to our map | ||||||
|  |          m_svcSettingsMap.put(AppRootPath, appRootPath); | ||||||
|          m_svcSettingsMap.put(ConfigFolderPath, svcConfigPath); |          m_svcSettingsMap.put(ConfigFolderPath, svcConfigPath); | ||||||
|       } |       } | ||||||
|       catch (SAXException e) |       catch (SAXException e) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user