Modifications to get us closer to submit this part of the project to
autobuild.
This commit is contained in:
		
							
								
								
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2006 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program 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 | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS = com | ||||
|  | ||||
| DIST_SUBDIRS = com | ||||
|  | ||||
| CFILES = | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| .PHONY: package package-clean package-install package-uninstall | ||||
| package package-clean package-install package-uninstall: | ||||
| 	$(MAKE) -C $(TARGET_OS) $@ | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
							
								
								
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/com/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/com/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2006 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program 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 | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS = novell | ||||
|  | ||||
| DIST_SUBDIRS = novell | ||||
|  | ||||
| CFILES = | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| .PHONY: package package-clean package-install package-uninstall | ||||
| package package-clean package-install package-uninstall: | ||||
| 	$(MAKE) -C $(TARGET_OS) $@ | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
							
								
								
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/com/novell/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								CASA-auth-token/java/server/Svc/src/com/novell/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2006 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program 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 | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS = casa | ||||
|  | ||||
| DIST_SUBDIRS = casa | ||||
|  | ||||
| CFILES = | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| .PHONY: package package-clean package-install package-uninstall | ||||
| package package-clean package-install package-uninstall: | ||||
| 	$(MAKE) -C $(TARGET_OS) $@ | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
| @@ -0,0 +1,37 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2006 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program 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 | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS = authtoksvc | ||||
|  | ||||
| DIST_SUBDIRS = authtoksvc | ||||
|  | ||||
| CFILES = | ||||
|  | ||||
| EXTRA_DIST = $(CFILES) | ||||
|  | ||||
| .PHONY: package package-clean package-install package-uninstall | ||||
| package package-clean package-install package-uninstall: | ||||
| 	$(MAKE) -C $(TARGET_OS) $@ | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
| @@ -0,0 +1,258 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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_DATA: | ||||
|             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; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,53 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /* | ||||
|  * AuthMechanism Interface. | ||||
|  *  | ||||
|  * This is the interface implemented by Authentication Mechanisms. | ||||
|  * | ||||
|  * Please note that Authentication Machanisms must also implement the | ||||
|  * Serializable interface. | ||||
|  * | ||||
|  */ | ||||
| public interface AuthMechanism | ||||
| { | ||||
|    /* | ||||
|     * Initialize the authentication mechanism. | ||||
|     */ | ||||
|    void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Process authenticate request. If successful, return the Id of the | ||||
|     * authenticated identity. | ||||
|     */ | ||||
|    String invoke(AuthReqMsg authReqMsg) throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Return the mechanism id. | ||||
|     */ | ||||
|    String getId(); | ||||
| } | ||||
| @@ -0,0 +1,328 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.InputStream; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * AuthReqMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent by Casa Client when requesting | ||||
|  * that an entity be authenticated. The format of the message is as | ||||
|  * follows: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <auth_req> | ||||
|  * <realm>realm value</realm> | ||||
|  * <mechanism>mechanism id</mechanism> | ||||
|  * <auth_mech_token>mechanism token data</auth_mech_token> | ||||
|  * </auth_req> | ||||
|  *  | ||||
|  */ | ||||
| public class AuthReqMsg | ||||
| { | ||||
|  | ||||
|    protected String  m_realm = null; | ||||
|    protected String  m_authMechToken = null; | ||||
|    protected String  m_authMechanism = null; | ||||
|  | ||||
|    /* | ||||
|     * Class for handling Authentication Request 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_REALM_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_REALM_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_REALM_DATA = 4; | ||||
|       private final static int AWAITING_MECH_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_MECH_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_MECH_DATA = 7; | ||||
|       private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_START = 8; | ||||
|       private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_END = 9; | ||||
|       private final static int AWAITING_AUTH_MECH_TOKEN_DATA = 10; | ||||
|       private final static int DONE_PARSING = 11; | ||||
|  | ||||
|       private AuthReqMsg   m_authReqMsg; | ||||
|       private int          m_state; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (AuthReqMsg authReqMsg) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_authReqMsg = authReqMsg; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("AuthReqMsg SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * 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 (ProtoDefs.authRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_REALM_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_REALM_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.realmElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_REALM_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_MECH_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.mechanismElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_MECH_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_AUTH_MECH_TOKEN_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.authMechTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_AUTH_MECH_TOKEN_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("AuthReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.authRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_REALM_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.realmElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_MECH_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_MECH_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.mechanismElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_AUTH_MECH_TOKEN_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.authMechTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("AuthReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|             case AWAITING_REALM_DATA: | ||||
|                // Consume the data | ||||
|                m_authReqMsg.m_realm = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_REALM_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_MECH_DATA: | ||||
|                // Consume the data | ||||
|                m_authReqMsg.m_authMechanism = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_MECH_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_AUTH_MECH_TOKEN_DATA: | ||||
|                // Consume the data | ||||
|                m_authReqMsg.m_authMechToken = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_AUTH_MECH_TOKEN_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public AuthReqMsg (InputStream inStream) throws Exception | ||||
|    { | ||||
|       try | ||||
|       { | ||||
|          // Parse the AuthReqMsg | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          System.err.println("AuthReqMsg()- Parse exception: " + e.toString());  | ||||
|          throw new Exception("Protocol error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the authentication realm.  | ||||
|     */ | ||||
|    public String getRealm() throws Exception | ||||
|    { | ||||
|       return m_realm; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the authentication mechanism token.  | ||||
|     */ | ||||
|    public String getAuthMechToken() throws Exception | ||||
|    { | ||||
|       return m_authMechToken; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the authentication mechanism id.  | ||||
|     */ | ||||
|    public String getMechanismId() throws Exception | ||||
|    { | ||||
|       return m_authMechanism; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,113 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * AuthRespMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent to the CASA Client as a | ||||
|  * response to an authentication request. The format of the message is | ||||
|  * as follows when the response includes a session token: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <auth_resp> | ||||
|  * <status><description>OK</description>200</status> | ||||
|  * <session_token><lifetime>lifetime value</lifetime>session token data</session_token> | ||||
|  * </auth_resp> | ||||
|  *  | ||||
|  * The format of the message is as follows when the response does not | ||||
|  * include a session token. | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <auth_resp> | ||||
|  * <status><description>status description</description>status code</status> | ||||
|  * </auth_resp> | ||||
|  *  | ||||
|  * Plase note that the protocol utilizes the status codes defined | ||||
|  * in the HTTP 1.1 Specification. | ||||
|  * | ||||
|  */ | ||||
| public class AuthRespMsg | ||||
| { | ||||
|  | ||||
|    String   m_msg; | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that does not include the session token. | ||||
|     */ | ||||
|    public AuthRespMsg ( | ||||
|                       String statusDescription, | ||||
|                       String statusCode) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that includes the session token. | ||||
|     */ | ||||
|    public AuthRespMsg ( | ||||
|                       String statusDescription, | ||||
|                       String statusCode, | ||||
|                       String sessionToken, | ||||
|                       String sessionTokenLifetime) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.sessionTokenElementName + ">" | ||||
|                 + "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">" | ||||
|                 + sessionToken + "</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the AuthRespMsg. | ||||
|     */ | ||||
|    public String toString() | ||||
|    { | ||||
|       return m_msg; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,466 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.ByteArrayInputStream; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * AuthToken Class. | ||||
|  *  | ||||
|  * This class constructs authentication tokens that clients can present | ||||
|  * to services for authentication. The format of the authentication token | ||||
|  * is as follows: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <auth_token> | ||||
|  * <signature>signature value</signature> | ||||
|  * <lifetime>lifetime value</lifetime> | ||||
|  * <ident_token><type>Identity Token type</type>identity token data</ident_token> | ||||
|  * </auth_token> | ||||
|  * | ||||
|  */ | ||||
| public class AuthToken | ||||
| { | ||||
|  | ||||
|    private String       m_token; | ||||
|    private String       m_lifetime; | ||||
|    private String       m_lifetimeShorter; | ||||
|    private String       m_identityTokenType; | ||||
|    private StringBuffer m_identityToken; | ||||
|    private String       m_signature; | ||||
|  | ||||
|    /* | ||||
|     * 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_SIGNATURE_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_SIGNATURE_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_SIGNATURE_DATA = 4; | ||||
|       private final static int AWAITING_LIFETIME_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_LIFETIME_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_LIFETIME_DATA = 7; | ||||
|       private final static int AWAITING_IDENT_TOKEN_ELEMENT_START = 8; | ||||
|       private final static int AWAITING_IDENT_TOKEN_ELEMENT_END = 9; | ||||
|       private final static int AWAITING_IDENT_TOKEN_DATA = 10; | ||||
|       private final static int AWAITING_TYPE_ELEMENT_START = 11; | ||||
|       private final static int AWAITING_TYPE_ELEMENT_END = 12; | ||||
|       private final static int AWAITING_TYPE_DATA = 13; | ||||
|       private final static int DONE_PARSING = 14; | ||||
|  | ||||
|       private AuthToken m_AuthToken; | ||||
|       private int    m_state; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (AuthToken AuthToken) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_AuthToken = AuthToken; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("AuthToken SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * 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 (ProtoDefs.authTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SIGNATURE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SIGNATURE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.signatureElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SIGNATURE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.lifetimeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_LIFETIME_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|  | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_TOKEN_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.identTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TYPE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TYPE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.typeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TYPE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("AuthToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.authTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SIGNATURE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.signatureElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_LIFETIME_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.lifetimeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_IDENT_TOKEN_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TYPE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.typeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_IDENT_TOKEN_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_TOKEN_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.identTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("AuthToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("AuthToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_SIGNATURE_DATA: | ||||
|                // Consume the data | ||||
|                m_AuthToken.m_signature = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SIGNATURE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_DATA: | ||||
|                // Consume the data | ||||
|                m_AuthToken.m_lifetime = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_LIFETIME_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TYPE_DATA: | ||||
|                // Consume the data | ||||
|                m_AuthToken.m_identityTokenType = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_TYPE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_TOKEN_DATA: | ||||
|             case AWAITING_IDENT_TOKEN_ELEMENT_END: | ||||
|                // Consume the data | ||||
|                m_AuthToken.m_identityToken.append(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_IDENT_TOKEN_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public AuthToken(String identityId, | ||||
|                     String realm, | ||||
|                     String targetService, | ||||
|                     String targetHost, | ||||
|                     SvcConfig svcConfig, | ||||
|                     EnabledSvcsConfig enabledSvcsConfig) throws Exception | ||||
|    { | ||||
|       // Get access to the authentication token configuration for this service | ||||
|       AuthTokenConfig authTokenConfig = enabledSvcsConfig.getAuthTokenConfig(targetHost, targetService); | ||||
|       if (authTokenConfig != null) | ||||
|       { | ||||
|          try | ||||
|          { | ||||
|             // For now lets use the services of the only IdentityToken provider | ||||
|             // that we have. | ||||
|             // | ||||
|             // tbd - Add code to allow for the consumption of tokens | ||||
|             // from different providers. | ||||
|             CasaIdentityToken identityToken = new CasaIdentityToken(enabledSvcsConfig.getIdenTokenConfig(targetHost, targetService)); | ||||
|             identityToken.initialize(identityId, | ||||
|                                      realm, | ||||
|                                      targetService, | ||||
|                                      targetHost, | ||||
|                                      svcConfig); | ||||
|  | ||||
|             m_identityToken = new StringBuffer(); | ||||
|             m_identityToken.append(identityToken.getEncodedToken()); | ||||
|             m_identityTokenType = identityToken.getProviderType(); | ||||
|  | ||||
|             m_lifetime = authTokenConfig.getSetting(AuthTokenConfig.TokenLifetime); | ||||
|             m_lifetimeShorter = authTokenConfig.getSetting(AuthTokenConfig.LifetimeShorter); | ||||
|  | ||||
|             // Generate a signature | ||||
|             // tbd - Over identToken, identToken type, and lifetime data. | ||||
|             m_signature = "tbd"; | ||||
|  | ||||
|             // Get a StringBuffer to help us with the construction of the token | ||||
|             StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|             // Start building the message | ||||
|             sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|             sb.append("<" + ProtoDefs.authTokenElementName + ">" + "\r\n"); | ||||
|             sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "</" + ProtoDefs.signatureElementName + ">" + "\r\n"); | ||||
|             sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "</" + ProtoDefs.lifetimeElementName + ">" + "\r\n"); | ||||
|             sb.append("<" + ProtoDefs.identTokenElementName + ">" | ||||
|                       + "<" + ProtoDefs.typeElementName + ">" + m_identityTokenType + "</" + ProtoDefs.typeElementName + ">" | ||||
|                       + m_identityToken + "</" + ProtoDefs.identTokenElementName + ">" + "\r\n"); | ||||
|             sb.append("</" + ProtoDefs.authTokenElementName + ">" + "\r\n"); | ||||
|  | ||||
|             // Save the token | ||||
|             m_token = sb.toString(); | ||||
|          } | ||||
|          catch (Exception e) | ||||
|          { | ||||
|             // tbd | ||||
|             System.err.println("AuthToken()- Exception: " + e.toString());  | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          throw new Exception("Error: Missing authentication token config for " + targetService); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor given an authentication token string. The constructor | ||||
|     * validates the token as part of its processing. | ||||
|     */ | ||||
|    public AuthToken(String token) throws Exception | ||||
|    { | ||||
|       // Decode the token string | ||||
|       m_token = Base64Coder.decode(token); | ||||
|  | ||||
|       // Instantiate string buffer for the identity token | ||||
|       m_identityToken = new StringBuffer(); | ||||
|  | ||||
|       // Now parse the token into its elements | ||||
|       try | ||||
|       { | ||||
|          // Parse the AuthToken | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|          ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes()); | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|  | ||||
|          // Verify the signature | ||||
|          // tbd | ||||
|  | ||||
|          // Verify that the token has not expired | ||||
|          // tbd | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          System.err.println("AuthToken()- Parse exception: " + e.toString());  | ||||
|          throw new Exception("Protocol error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the Base64 encode token. | ||||
|     */ | ||||
|    public String toString() | ||||
|    { | ||||
|       return Base64Coder.encode(m_token); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the lifetime of the token. | ||||
|     */ | ||||
|    public String getLifetime() | ||||
|    { | ||||
|       // tbd - Convert to tokenLifetime and lifetimeShorter to ints, substractand then convert result to string | ||||
|       return "60"; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the identity token. | ||||
|     */ | ||||
|    public String getIdentityToken() | ||||
|    { | ||||
|       return m_identityToken.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the identity token type. | ||||
|     */ | ||||
|    public String getIdentityTokenType() | ||||
|    { | ||||
|       return m_identityTokenType; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,298 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * AuthTokenConfig Class. | ||||
|  *  | ||||
|  * This class obtains and maintains authentication token configuration. | ||||
|  *  | ||||
|  */ | ||||
| public class AuthTokenConfig | ||||
| { | ||||
|    // Well known authentication token configuration settings | ||||
|    public final static String TokenLifetime = "TokenLifetime"; | ||||
|    public final static String LifetimeShorter = "LifetimeShorter"; | ||||
|    public final static String IdentityTokenType = "IdentityTokenType"; | ||||
|  | ||||
|    // Default configuration values | ||||
|    private String m_defaultTokenLifetimeValue = "3600";  // Seconds | ||||
|    private String m_defaultLifetimeShorterValue = "5";   // Seconds | ||||
|    private String m_defaultIdentityTokenTypeValue = "CasaIdentityToken"; | ||||
|  | ||||
|    private Map m_tokenSettingsMap; | ||||
|  | ||||
|    /* | ||||
|     * 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("AuthTokenConfig 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("AuthTokenConfig 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("AuthTokenConfig 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_DATA: | ||||
|             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("AuthTokenConfig SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("AuthTokenConfig 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 AuthTokenConfig() throws Exception | ||||
|    { | ||||
|       System.err.println("AuthTokenConfig()- Default"); | ||||
|  | ||||
|       // Create a map to keep track of the token settings | ||||
|       m_tokenSettingsMap = new HashMap(); | ||||
|  | ||||
|       // Set the default settings in our map | ||||
|       m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue); | ||||
|       m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue); | ||||
|       m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public AuthTokenConfig(String authTokenSettingsFileName) throws Exception | ||||
|    { | ||||
|       System.err.println("AuthTokenConfig()-"); | ||||
|  | ||||
|       // Create a map to keep track of the token settings | ||||
|       m_tokenSettingsMap = new HashMap(); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Get an input stream to read from the token settings file | ||||
|          File f = new File(authTokenSettingsFileName); | ||||
|          FileInputStream inStream = new FileInputStream(f); | ||||
|  | ||||
|          // Parse the file | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(m_tokenSettingsMap); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|           | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|  | ||||
|          inStream.close(); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|         System.err.println("AuthTokenConfig()- " + authTokenSettingsFileName + " format error, exception: " + e.toString());  | ||||
|         throw new Exception("AuthTokenConfig()- authtoken.settings format error"); | ||||
|       } | ||||
|       catch (SecurityException e) | ||||
|       { | ||||
|          System.err.println("AuthTokenConfig()- SecurityException accessing " + authTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|          throw new Exception("AuthTokenConfig()- Not able to access file"); | ||||
|       } | ||||
|       catch (FileNotFoundException e) | ||||
|       { | ||||
|          System.err.println("AuthTokenConfig()- File " + authTokenSettingsFileName + " not found"); | ||||
|          throw new Exception("AuthTokenConfig()- File not found"); | ||||
|       } | ||||
|       catch (IOException e) | ||||
|       { | ||||
|          System.err.println("AuthTokenConfig()- IOException accessing " + authTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|          throw new Exception("AuthTokenConfig()- 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_tokenSettingsMap.get(settingName); | ||||
|       if (value == null) | ||||
|       { | ||||
|          System.err.println("AuthTokenConfig.getSetting()- Did not find setting " + settingName); | ||||
|  | ||||
|          // The setting is not in our map, check if it is one to | ||||
|          // which we have defaults. | ||||
|          if (settingName.equals(TokenLifetime) == true) | ||||
|          { | ||||
|             value = m_defaultTokenLifetimeValue; | ||||
|             System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue); | ||||
|          } | ||||
|          else if (settingName.equals(LifetimeShorter) == true) | ||||
|          { | ||||
|             value = m_defaultLifetimeShorterValue; | ||||
|             System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue); | ||||
|          } | ||||
|          else if (settingName.equals(IdentityTokenType) == true) | ||||
|          { | ||||
|             value = m_defaultLifetimeShorterValue; | ||||
|             System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          System.err.println("AuthTokenConfig.getSetting()- Found setting " + settingName); | ||||
|          System.err.println("AuthTokenConfig.getSetting()- Setting value = " + value); | ||||
|  | ||||
|          // Do some sanity checking | ||||
|          // tbd - Make sure that the token lifetime values are greater than the LifetimeShorter | ||||
|       } | ||||
|  | ||||
|       return value; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,341 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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   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 + File.separator + 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 + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                               } | ||||
|                               catch (ClassNotFoundException e) | ||||
|                               { | ||||
|                                  System.err.println("Authenticate.init()- ClassNotFoundException for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                               } | ||||
|                               catch (InstantiationException e) | ||||
|                               { | ||||
|                                  System.err.println("Authenticate.init()- InstantiationException for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                               } | ||||
|                               catch (IllegalAccessException e) | ||||
|                               { | ||||
|                                  System.err.println("Authenticate.init()- IllegalAccessException for "  + mechanismFolder + File.separator + 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 + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                                  } | ||||
|                                  catch (ClassNotFoundException e) | ||||
|                                  { | ||||
|                                     System.err.println("Authenticate.init()- ClassNotFoundException for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                                  } | ||||
|                                  catch (InstantiationException e) | ||||
|                                  { | ||||
|                                     System.err.println("Authenticate.init()- InstantiationException for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                                  } | ||||
|                                  catch (IllegalAccessException e) | ||||
|                                  { | ||||
|                                     System.err.println("Authenticate.init()- IllegalAccessException for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                                  } | ||||
|                               } | ||||
|                               else | ||||
|                               { | ||||
|                                  System.err.println("Authenticate.init()- No configuration to find class path to load "  + mechanismFolder + File.separator + m_mechanismSettingsFileName); | ||||
|                               } | ||||
|                            } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            System.err.println("Authenticate.init()- No configured mechanism class name for "  + mechanismFolder + File.separator + m_mechanismSettingsFileName); | ||||
|                         } | ||||
|                      } | ||||
|                      catch (SecurityException e) | ||||
|                      { | ||||
|                         System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + File.separator + 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 + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString()); | ||||
|                      } | ||||
|                      catch (Exception e) | ||||
|                      { | ||||
|                         System.err.println("Authenticate.init()- Exception instantiating mechConfig or mechanism " + mechanismFolder + File.separator + 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()); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * 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, " + identId); | ||||
|  | ||||
|                // 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"; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,121 @@ | ||||
| /************************************************************************** | ||||
| * | ||||
| * A Base64 Encoder/Decoder. | ||||
| * | ||||
| * This class is used to encode and decode data in Base64 format | ||||
| * as described in RFC 1521. | ||||
| * | ||||
| * <p> | ||||
| * Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br> | ||||
| * License: This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license. | ||||
| * It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.<br> | ||||
| * Home page: <a href="http://www.source-code.biz" target="_top">www.source-code.biz</a><br> | ||||
| * | ||||
| * <p> | ||||
| * Version history:<br> | ||||
| * 2003-07-22 Christian d'Heureuse (chdh): Module created.<br> | ||||
| * 2005-08-11 chdh: Lincense changed from GPL to LGPL. | ||||
| * | ||||
| **************************************************************************/ | ||||
|  | ||||
| package com.novell.casa.authtoksvc; | ||||
|  | ||||
| public class Base64Coder { | ||||
|  | ||||
| // Mapping table from 6-bit nibbles to Base64 characters. | ||||
| private static char[]    map1 = new char[64]; | ||||
|    static { | ||||
|       int i=0; | ||||
|       for (char c='A'; c<='Z'; c++) map1[i++] = c; | ||||
|       for (char c='a'; c<='z'; c++) map1[i++] = c; | ||||
|       for (char c='0'; c<='9'; c++) map1[i++] = c; | ||||
|       map1[i++] = '+'; map1[i++] = '/'; } | ||||
|  | ||||
| // Mapping table from Base64 characters to 6-bit nibbles. | ||||
| private static byte[]    map2 = new byte[128]; | ||||
|    static { | ||||
|       for (int i=0; i<map2.length; i++) map2[i] = -1; | ||||
|       for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; } | ||||
|  | ||||
| /** | ||||
| * Encodes a string into Base64 format. | ||||
| * No blanks or line breaks are inserted. | ||||
| * @param s  a String to be encoded. | ||||
| * @return   A String with the Base64 encoded data. | ||||
| */ | ||||
| public static String encode (String s) { | ||||
|    return new String(encode(s.getBytes())); } | ||||
|  | ||||
| /** | ||||
| * Encodes a byte array into Base64 format. | ||||
| * No blanks or line breaks are inserted. | ||||
| * @param in  an array containing the data bytes to be encoded. | ||||
| * @return    A character array with the Base64 encoded data. | ||||
| */ | ||||
| public static char[] encode (byte[] in) { | ||||
|    int iLen = in.length; | ||||
|    int oDataLen = (iLen*4+2)/3;       // output length without padding | ||||
|    int oLen = ((iLen+2)/3)*4;         // output length including padding | ||||
|    char[] out = new char[oLen]; | ||||
|    int ip = 0; | ||||
|    int op = 0; | ||||
|    while (ip < iLen) { | ||||
|       int i0 = in[ip++] & 0xff; | ||||
|       int i1 = ip < iLen ? in[ip++] & 0xff : 0; | ||||
|       int i2 = ip < iLen ? in[ip++] & 0xff : 0; | ||||
|       int o0 = i0 >>> 2; | ||||
|       int o1 = ((i0 &   3) << 4) | (i1 >>> 4); | ||||
|       int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); | ||||
|       int o3 = i2 & 0x3F; | ||||
|       out[op++] = map1[o0]; | ||||
|       out[op++] = map1[o1]; | ||||
|       out[op] = op < oDataLen ? map1[o2] : '='; op++; | ||||
|       out[op] = op < oDataLen ? map1[o3] : '='; op++; } | ||||
|    return out; } | ||||
|  | ||||
| /** | ||||
| * Decodes a Base64 string. | ||||
| * @param s  a Base64 String to be decoded. | ||||
| * @return   A String containing the decoded data. | ||||
| * @throws   IllegalArgumentException if the input is not valid Base64 encoded data. | ||||
| */ | ||||
| public static String decode (String s) { | ||||
|    return new String(decode(s.toCharArray())); } | ||||
|  | ||||
| /** | ||||
| * Decodes Base64 data. | ||||
| * No blanks or line breaks are allowed within the Base64 encoded data. | ||||
| * @param in  a character array containing the Base64 encoded data. | ||||
| * @return    An array containing the decoded data bytes. | ||||
| * @throws    IllegalArgumentException if the input is not valid Base64 encoded data. | ||||
| */ | ||||
| public static byte[] decode (char[] in) { | ||||
|    int iLen = in.length; | ||||
|    if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4."); | ||||
|    while (iLen > 0 && in[iLen-1] == '=') iLen--; | ||||
|    int oLen = (iLen*3) / 4; | ||||
|    byte[] out = new byte[oLen]; | ||||
|    int ip = 0; | ||||
|    int op = 0; | ||||
|    while (ip < iLen) { | ||||
|       int i0 = in[ip++]; | ||||
|       int i1 = in[ip++]; | ||||
|       int i2 = ip < iLen ? in[ip++] : 'A'; | ||||
|       int i3 = ip < iLen ? in[ip++] : 'A'; | ||||
|       if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) | ||||
|          throw new IllegalArgumentException ("Illegal character in Base64 encoded data."); | ||||
|       int b0 = map2[i0]; | ||||
|       int b1 = map2[i1]; | ||||
|       int b2 = map2[i2]; | ||||
|       int b3 = map2[i3]; | ||||
|       if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) | ||||
|          throw new IllegalArgumentException ("Illegal character in Base64 encoded data."); | ||||
|       int o0 = ( b0       <<2) | (b1>>>4); | ||||
|       int o1 = ((b1 & 0xf)<<4) | (b2>>>2); | ||||
|       int o2 = ((b2 &   3)<<6) |  b3; | ||||
|       out[op++] = (byte)o0; | ||||
|       if (op<oLen) out[op++] = (byte)o1; | ||||
|       if (op<oLen) out[op++] = (byte)o2; } | ||||
|    return out; } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,774 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.ByteArrayInputStream; | ||||
| import java.util.HashSet; | ||||
| import java.util.Hashtable; | ||||
| import java.util.Set; | ||||
|  | ||||
| import javax.naming.Context; | ||||
| import javax.naming.NamingEnumeration; | ||||
| import javax.naming.NamingException; | ||||
| import javax.naming.directory.Attributes; | ||||
| import javax.naming.directory.DirContext; | ||||
| import javax.naming.directory.InitialDirContext; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
| import org.bandit.ia.IAContext; | ||||
|  | ||||
| /* | ||||
|  * CasaIdentityToken Class. | ||||
|  *  | ||||
|  * This class constructs Casa Identity tokens. | ||||
|  *  | ||||
|  * A Casa Identity Token is a simple XML Document | ||||
|  * with information about an identity in the form | ||||
|  * of: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <casa_ident_tok> | ||||
|  * <id>identity id</id> | ||||
|  * <source_name>identity data source name</source_name> | ||||
|  * <source_url>identity data source url</source_url> | ||||
|  * <target_service>target service name</target_service> | ||||
|  * <target_host>target host name</target_host> | ||||
|  * <attributes> | ||||
|  * <attribute name>attribute value</attribute name> | ||||
|  * <attribute2 name>attribute2 value</attribute name> | ||||
|  * ...  | ||||
|  * </attributes> | ||||
|  * </casa_ident_tok> | ||||
|  *   | ||||
|  *   | ||||
|  *  attribute/values pairs. The attribute names | ||||
|  * being the XML elements of the documents. | ||||
|  *  | ||||
|  */ | ||||
| public class CasaIdentityToken implements IdentityToken | ||||
| { | ||||
|    /* | ||||
|     * XML Element Name Constants for the documents exchanged between the | ||||
|     * Casa Client and the Casa Server. | ||||
|     */ | ||||
|    private final static String casaIdentTokElementName = "casa_ident_tok"; | ||||
|    private final static String idElementName = "id"; | ||||
|    private final static String sourceNameElementName = "source_name"; | ||||
|    private final static String sourceUrlElementName = "source_url"; | ||||
|    private final static String targetServiceElementName = "target_service"; | ||||
|    private final static String targetHostElementName = "target_host"; | ||||
|    private final static String attributesElementName = "attributes"; | ||||
|  | ||||
|    private IdenTokenConfig m_idenTokenConfig; | ||||
|  | ||||
|    private String m_identityId = null; | ||||
|    private String m_sourceName = null; | ||||
|    private String m_sourceUrl = null; | ||||
|    private String m_service = null; | ||||
|    private String m_host = null; | ||||
|    private String m_token = null; | ||||
|    private javax.naming.directory.Attributes m_attributes = null; | ||||
|  | ||||
|    /* | ||||
|     * Class for handling Authentication Request 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_ID_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_ID_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_ID_DATA = 4; | ||||
|       private final static int AWAITING_SOURCE_NAME_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_SOURCE_NAME_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_SOURCE_NAME_DATA = 7; | ||||
|       private final static int AWAITING_SOURCE_URL_ELEMENT_START = 8; | ||||
|       private final static int AWAITING_SOURCE_URL_ELEMENT_END = 9; | ||||
|       private final static int AWAITING_SOURCE_URL_DATA = 10; | ||||
|       private final static int AWAITING_TARGET_SERVICE_ELEMENT_START = 11; | ||||
|       private final static int AWAITING_TARGET_SERVICE_ELEMENT_END = 12; | ||||
|       private final static int AWAITING_TARGET_SERVICE_DATA = 13; | ||||
|       private final static int AWAITING_TARGET_HOST_ELEMENT_START = 14; | ||||
|       private final static int AWAITING_TARGET_HOST_ELEMENT_END = 15; | ||||
|       private final static int AWAITING_TARGET_HOST_DATA = 16; | ||||
|       private final static int AWAITING_ATTRIBUTES_ELEMENT_START = 17; | ||||
|       private final static int AWAITING_ATTRIBUTE_START = 18; | ||||
|       private final static int AWAITING_ATTRIBUTE_END = 19; | ||||
|       private final static int AWAITING_ATTRIBUTE_DATA = 20; | ||||
|       private final static int AWAITING_BINARY_ATTRIBUTE_DATA = 21; | ||||
|       private final static int DONE_PARSING = 22; | ||||
|  | ||||
|       private CasaIdentityToken  m_casaIdentToken; | ||||
|       private int          m_state; | ||||
|       private String          m_currAttribute; | ||||
|       private boolean         m_encryptedAttrs; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (CasaIdentityToken casaIdentityToken) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_casaIdentToken = casaIdentityToken; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("CasaIdentityToken SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        *  | ||||
|        * 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 (casaIdentTokElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ID_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ID_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (idElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ID_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_NAME_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (sourceNameElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SOURCE_NAME_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|  | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_URL_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (sourceUrlElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SOURCE_URL_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_SERVICE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (targetServiceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TARGET_SERVICE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_HOST_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (targetHostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TARGET_HOST_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ATTRIBUTES_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (attributesElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ATTRIBUTE_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ATTRIBUTE_START: | ||||
|                // Save the element name as the current attribute | ||||
|                m_currAttribute = qName; | ||||
|  | ||||
|                // Advance to the next state based on the attribute type | ||||
|                String attrType = atts.getValue("type"); | ||||
|                if (attrType != null && attrType.equals("binary")) | ||||
|                { | ||||
|                   // We are dealing with a binary attribute. We are going to | ||||
|                   // assume that binary attributes are always base64 encoded. | ||||
|                   m_state = AWAITING_BINARY_ATTRIBUTE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   // Assume we are dealing with an attribute of type string | ||||
|                   m_state = AWAITING_ATTRIBUTE_DATA; | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (casaIdentTokElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ID_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (idElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SOURCE_NAME_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_NAME_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (sourceNameElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SOURCE_URL_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_URL_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (sourceUrlElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TARGET_SERVICE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_SERVICE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (targetServiceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_TARGET_HOST_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_HOST_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (targetHostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ATTRIBUTES_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ATTRIBUTE_END: | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_ATTRIBUTE_START; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ATTRIBUTE_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (attributesElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ID_DATA: | ||||
|                // Consume the data | ||||
|                m_casaIdentToken.m_identityId = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_ID_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_NAME_DATA: | ||||
|                // Consume the data | ||||
|                m_casaIdentToken.m_sourceName = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SOURCE_NAME_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SOURCE_URL_DATA: | ||||
|                // Consume the data | ||||
|                m_casaIdentToken.m_sourceUrl = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SOURCE_URL_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_SERVICE_DATA: | ||||
|                // Consume the data | ||||
|                m_casaIdentToken.m_service = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_TARGET_SERVICE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_TARGET_HOST_DATA: | ||||
|                // Consume the data | ||||
|                m_casaIdentToken.m_host = new String(ch, start, length); | ||||
|  | ||||
|                // At this point we now have the target service and host names, | ||||
|                // check if our configuration says that the attributes have been | ||||
|                // encrypted. | ||||
|                // tbd - Need to come up with a solution for obtaining configuration | ||||
|                // information when instanstiated using a stream. May be the token should | ||||
|                // carry an indication that the attributes are encrypted. | ||||
|                m_encryptedAttrs = false; | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_TARGET_HOST_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_ATTRIBUTE_DATA: | ||||
|                // Consume the data | ||||
|                // | ||||
|                // Decrypt the attribute data if necessary | ||||
|                if (m_encryptedAttrs) | ||||
|                { | ||||
|                   // tbd - Decrypt the attribute key and value with the private key of the service | ||||
|                   // using the configured mechanism. | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length)); | ||||
|                } | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_ATTRIBUTE_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_BINARY_ATTRIBUTE_DATA: | ||||
|                // Consume the data | ||||
|                // | ||||
|                // Decrypt the attribute data if necessary | ||||
|                if (m_encryptedAttrs) | ||||
|                { | ||||
|                   // tbd - Decrypt the attribute key and value with the private key of the service | ||||
|                   // using the configured mechanism. | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   // The data is base64 encoded | ||||
|                   char[] encodedChars = new char[length]; | ||||
|                   System.arraycopy(ch, start, encodedChars, 0, length); | ||||
|                   m_casaIdentToken.m_attributes.put(m_currAttribute, Base64Coder.decode(encodedChars)); | ||||
|                } | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_ATTRIBUTE_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public CasaIdentityToken (IdenTokenConfig idenTokenConfig) | ||||
|    { | ||||
|       // Initialize our members | ||||
|       m_token = null; | ||||
|       m_attributes = new javax.naming.directory.BasicAttributes(); | ||||
|       m_idenTokenConfig = idenTokenConfig; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public CasaIdentityToken () | ||||
|    { | ||||
|       // Initialize our members | ||||
|       m_token = null; | ||||
|       m_attributes = new javax.naming.directory.BasicAttributes(); | ||||
|       m_idenTokenConfig = null; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Initialize with parameters. | ||||
|     */ | ||||
|    public void initialize (String identityId, | ||||
|                            String sourceName, | ||||
|                            String targetService, | ||||
|                            String targetHost, | ||||
|                            SvcConfig svcConfig) throws Exception | ||||
|    { | ||||
|       // Save input parameters | ||||
|       m_identityId = identityId; | ||||
|       m_sourceName = sourceName; | ||||
|       m_sourceUrl = "ldap://myldaphost.novell.com:389"; // tbd - Obtain from Identity Abstraction layer | ||||
|       m_service = targetService; | ||||
|       m_host = targetHost; | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Open a directory context and use it to read the identity attributes. | ||||
|          Hashtable env = new Hashtable(); | ||||
|          env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); | ||||
|          env.put(IAContext.IA_REALM_CONFIG_LOCATION, svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); | ||||
|          env.put(IAContext.IA_REALM_SELECTOR, sourceName); | ||||
|  | ||||
|          DirContext ctx = new InitialDirContext(env); | ||||
|  | ||||
|          // Setup a string buffer for building the IdentityToken, notice for now | ||||
|          // we are not going to wrap the identity token. | ||||
|          StringBuffer sb = new StringBuffer(); | ||||
|          sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|          sb.append("<" + casaIdentTokElementName + ">" + "\r\n"); | ||||
|          sb.append("<" + idElementName + ">" + identityId + "</" + idElementName + ">\r\n"); | ||||
|          sb.append("<" + sourceNameElementName + ">" + sourceName + "</" + sourceNameElementName + ">\r\n"); | ||||
|          sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "</" + sourceUrlElementName + ">\r\n"); | ||||
|          sb.append("<" + targetServiceElementName + ">" + m_service + "</" + targetServiceElementName + ">\r\n"); | ||||
|          sb.append("<" + targetHostElementName + ">" + m_host + "</" + targetHostElementName + ">\r\n"); | ||||
|          sb.append("<" + attributesElementName + ">" + "\r\n"); | ||||
|  | ||||
|          // Get the necessary attributes of the specified services in the identity token | ||||
|          String[] attributesNeeded  = m_idenTokenConfig.getAttributes(); | ||||
|          boolean encryptAttributes = "true".equals(m_idenTokenConfig.getSetting(IdenTokenConfig.EncryptAttributes)); | ||||
|          Attributes attrs = ctx.getAttributes(identityId, attributesNeeded); | ||||
|  | ||||
|          // Now append the attributes to the token | ||||
|          for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();) | ||||
|          { | ||||
|             javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next(); | ||||
|  | ||||
|             NamingEnumeration enumeration = attr.getAll(); | ||||
|             while (enumeration.hasMore()) | ||||
|             { | ||||
|                Object attrValue = enumeration.next(); | ||||
|                m_attributes.put(attr.getID(), attrValue); | ||||
|                System.err.println("CasaIdentityToken.initialize()- Including attribute " + attr.getID()); | ||||
|  | ||||
|                // Encrypt the attribute if necessary | ||||
|                if (encryptAttributes == true) | ||||
|                { | ||||
|                   // tbd - Encrypt the attributes using the services public key, let the mechanism | ||||
|                   // be configurable. The service's certificate should be Base64 encoded as a setting | ||||
|                   // of the identoken.settings file. | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   // Proceed based on the attribute value type | ||||
|                   if (attrValue instanceof byte[]) | ||||
|                   { | ||||
|                      // The attribute value is of type byte[], we need to encode it. | ||||
|                      sb.append("<" + attr.getID() + " type=\"binary\" encoding=\"base64\">" + new String(Base64Coder.encode((byte[]) attrValue)) + "</" + attr.getID() + ">" + "\r\n"); | ||||
|                      System.err.println("Attribute " + attr.getID() + "included as " + new String(Base64Coder.encode((byte[]) attrValue))); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      // Assume the attribute value is of type String | ||||
|                      sb.append("<" + attr.getID() + ">" + (String) attrValue + "</" + attr.getID() + ">" + "\r\n"); | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|          } | ||||
|          sb.append("</" + attributesElementName + ">" + "\r\n"); | ||||
|          sb.append("</" + casaIdentTokElementName + ">" + "\r\n"); | ||||
|  | ||||
|          m_token = sb.toString(); | ||||
|       } | ||||
|       catch (NamingException e) | ||||
|       { | ||||
|          // tbd - Log the event??? | ||||
|          System.err.println("CasaIdentityToken.initialize()- Exception: " + e.getExplanation()); | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          // tbd | ||||
|          System.err.println("CasaIdentityToken.initialize()- Exception: " + e.toString());  | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Initialize the token object with an ecoded token string. | ||||
|     */ | ||||
|    public void initialize (String encodedToken) throws Exception | ||||
|    { | ||||
|       // Save copy of the token | ||||
|       m_token = Base64Coder.decode(encodedToken); | ||||
|  | ||||
|       // Now parse the token into its elements | ||||
|       try | ||||
|       { | ||||
|          // Parse the AuthReqMsg | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|  | ||||
|          ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes()); | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          // tbd - Log this. | ||||
|          System.err.println("CasaIdentityToken()- Parse exception: " + e.toString()); | ||||
|          throw new Exception("Token error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns encoded token string. | ||||
|     *  | ||||
|     * IMPORTANT: The token string can not contain the substring "]]>" | ||||
|     * within it. | ||||
|     */ | ||||
|    public String getEncodedToken () throws Exception | ||||
|    { | ||||
|       if (m_token != null) | ||||
|       { | ||||
|          return Base64Coder.encode(m_token); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.toString()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing our type of identity token provider. | ||||
|     */ | ||||
|    public String getProviderType () throws Exception | ||||
|    { | ||||
|       // tbd - Change to a GUID | ||||
|       return "CasaIdentityToken"; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the identity id. | ||||
|     */ | ||||
|    public String getIdentityId () throws Exception | ||||
|    { | ||||
|       if (m_identityId != null) | ||||
|          return m_identityId; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getIdentityId()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the name associated with the | ||||
|     * identity source. | ||||
|     */ | ||||
|    public String getSourceName () throws Exception | ||||
|    { | ||||
|       if (m_sourceName != null) | ||||
|          return m_sourceName; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getSourceName()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the url associated with the | ||||
|     * identity source. | ||||
|     */ | ||||
|    public String getSourceUrl () throws Exception | ||||
|    { | ||||
|       if (m_sourceUrl != null) | ||||
|          return m_sourceUrl; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getSourceUrl()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the name of the targeted service. | ||||
|     */ | ||||
|    public String getTargetService () throws Exception | ||||
|    { | ||||
|       if (m_service != null) | ||||
|          return m_service; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getTargetService()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containig the name of the host where the | ||||
|     * targeted service resides. | ||||
|     */ | ||||
|    public String getTargetHost () throws Exception | ||||
|    { | ||||
|       if (m_host != null) | ||||
|          return m_host; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getTargetHost()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the attributes of the identity. | ||||
|     */ | ||||
|    public javax.naming.directory.Attributes getAttributes () throws Exception | ||||
|    { | ||||
|       if (m_attributes != null) | ||||
|          return m_attributes; | ||||
|       else | ||||
|       { | ||||
|          System.err.println("CasaIdentityToken.getIdentityAttributes()- Not initialized"); | ||||
|          throw new Exception("Not initialized"); | ||||
|       } | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,388 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.*; | ||||
|  | ||||
| /** | ||||
|  * EnabledSvcsConfig Class. | ||||
|  *  | ||||
|  * This class obtains and maintains configuration and policy information about | ||||
|  * the services enabled to use Authentication Tokens. | ||||
|  *  | ||||
|  */ | ||||
| public class EnabledSvcsConfig | ||||
| { | ||||
|    private static final String m_authPolicyFileName = "auth.policy"; | ||||
|    private static final String m_authTokenSettingsFileName = "authtoken.settings"; | ||||
|    private static final String m_idenTokenSettingsFileName = "identoken.settings"; | ||||
|  | ||||
|    private Map m_hostsMap; | ||||
|  | ||||
|    /** | ||||
|     * SvcConfigEntry Class. | ||||
|     *  | ||||
|     * This class is used to maintain the configuration and policy associated with an | ||||
|     * enabled service. | ||||
|     *  | ||||
|     */ | ||||
|    private class SvcConfigEntry | ||||
|    { | ||||
|       protected byte[]           m_authPolicyFileData; | ||||
|       protected AuthTokenConfig  m_authTokenConfig; | ||||
|       protected IdenTokenConfig  m_idenTokenConfig; | ||||
|  | ||||
|       /* | ||||
|        * Constructor. | ||||
|        */ | ||||
|       public SvcConfigEntry(byte[] authPolicyFileData, | ||||
|                             AuthTokenConfig authTokenConfig, | ||||
|                             IdenTokenConfig idenTokenConfig) | ||||
|       { | ||||
|          m_authPolicyFileData = authPolicyFileData; | ||||
|          m_authTokenConfig = authTokenConfig; | ||||
|          m_idenTokenConfig = idenTokenConfig; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public EnabledSvcsConfig(String svcConfigPath) throws Exception | ||||
|    { | ||||
|       System.err.println("EnabledSvcsConfig()-"); | ||||
|       System.err.println("EnabledSvcsConfig()- SvcConfigPath = " + svcConfigPath); | ||||
|  | ||||
|       // Initialize the default auth policy, authtoken, and identtoken configs. | ||||
|       byte[] defaultAuthPolicyData = null; | ||||
|       AuthTokenConfig defaultAuthTokenConfig = null; | ||||
|       IdenTokenConfig defaultIdenTokenConfig = null; | ||||
|  | ||||
|       // Create a map to keep track of the enabled services and their configuration | ||||
|       // for each configured host. | ||||
|       m_hostsMap = new HashMap(); | ||||
|  | ||||
|       // Get access to the configuration folder for the service | ||||
|       File configFolder = new File(svcConfigPath); | ||||
|       try | ||||
|       { | ||||
|          // Try to obtain the default authentication policy | ||||
|          try | ||||
|          { | ||||
|             File f = new File(configFolder, m_authPolicyFileName); | ||||
|             defaultAuthPolicyData = new byte[(int) f.length()]; | ||||
|             FileInputStream inStream = new FileInputStream(f); | ||||
|             int bytesRead = inStream.read(defaultAuthPolicyData); | ||||
|             inStream.close(); | ||||
|             if (bytesRead != defaultAuthPolicyData.length) | ||||
|             { | ||||
|                System.err.println("EnabledSvcsConfig()- Error reading default policy file"); | ||||
|             } | ||||
|          } | ||||
|          catch (SecurityException e) | ||||
|          { | ||||
|             System.err.println("EnabledSvcsConfig()- SecurityException accessing " + configFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString()); | ||||
|          } | ||||
|          catch (FileNotFoundException e) | ||||
|          { | ||||
|             System.err.println("EnabledSvcsConfig()- File " + configFolder + File.separator + m_authPolicyFileName + " not found"); | ||||
|          } | ||||
|          catch (IOException e) | ||||
|          { | ||||
|             System.err.println("EnabledSvcsConfig()- IOException reading " + configFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString()); | ||||
|          } | ||||
|  | ||||
|          // Try to obtain the default authentication token settings | ||||
|          try | ||||
|          { | ||||
|             defaultAuthTokenConfig = new AuthTokenConfig(configFolder + File.separator + m_authTokenSettingsFileName); | ||||
|          } | ||||
|          catch (Exception e) | ||||
|          { | ||||
|             // Not able to create authentication token configuration using the default | ||||
|             // file. Create one using default parameters. | ||||
|             defaultAuthTokenConfig = new AuthTokenConfig(); | ||||
|          } | ||||
|  | ||||
|          // Try to obtain the default identity token settings | ||||
|          try | ||||
|          { | ||||
|             defaultIdenTokenConfig = new IdenTokenConfig(configFolder + File.separator + m_idenTokenSettingsFileName); | ||||
|          } | ||||
|          catch (Exception e) | ||||
|          { | ||||
|             // Not able to create identity token configuration using the default | ||||
|             // file. Create one using default parameters. | ||||
|             defaultIdenTokenConfig = new IdenTokenConfig(); | ||||
|          } | ||||
|  | ||||
|          // Now go through the configured hosts. Note that the services config folder | ||||
|          // 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 | ||||
|          // the enabled services reside. | ||||
|          File servicesConfigFolder = new File(svcConfigPath, "enabled_services"); | ||||
|          try | ||||
|          { | ||||
|             String[] servicesConfigFolderObjs = servicesConfigFolder.list(); | ||||
|             if (servicesConfigFolderObjs != null) | ||||
|             { | ||||
|                for (int i = 0; i < servicesConfigFolderObjs.length; i++) | ||||
|                { | ||||
|                   // Check if we are dealing with a file or a folder | ||||
|                   File hostFolder = new File(servicesConfigFolder, servicesConfigFolderObjs[i]); | ||||
|                   try | ||||
|                   { | ||||
|                      if (hostFolder.isDirectory() == true) | ||||
|                      { | ||||
|                         System.err.println("EnabledSvcsConfig()- Host folder " + hostFolder + " is directory"); | ||||
|  | ||||
|                         // Now go through the services configured for this host | ||||
|                         String[] hostFolderObjs = hostFolder.list(); | ||||
|                         if (hostFolderObjs != null) | ||||
|                         { | ||||
|                            // Create a Map object to hold the service configurations for this host | ||||
|                            Map enabledSvcsConfigMap = new HashMap(); | ||||
|  | ||||
|                            for (int ii = 0; ii < hostFolderObjs.length; ii++) | ||||
|                            { | ||||
|                               // Check if we are dealing with a file or a folder | ||||
|                               File serviceFolder = new File(hostFolder, hostFolderObjs[ii]); | ||||
|                               System.err.println("EnabledSvcsConfig()- Service folder " + serviceFolder); | ||||
|                               try | ||||
|                               { | ||||
|                                  if (serviceFolder.isDirectory() == true) | ||||
|                                  { | ||||
|                                     System.err.println("EnabledSvcsConfig()- Service folder " + serviceFolder + " is directory"); | ||||
|  | ||||
|                                     // We are dealing with a folder, remember that the folder name matches the name | ||||
|                                     // of the enabled service. Check and see if there are authentication policy and | ||||
|                                     // authtoken and identoken setting files configured for it. | ||||
|                                     byte[] authPolicyData = null; | ||||
|                                     AuthTokenConfig authTokenConfig = null; | ||||
|                                     IdenTokenConfig idenTokenConfig = null; | ||||
|  | ||||
|                                     try | ||||
|                                     { | ||||
|                                        File policyFile = new File(serviceFolder, m_authPolicyFileName); | ||||
|                                        authPolicyData = new byte[(int) policyFile.length()]; | ||||
|                                        FileInputStream inStream = new FileInputStream(policyFile); | ||||
|                                        int bytesRead = inStream.read(authPolicyData); | ||||
|                                        inStream.close(); | ||||
|                                        if (bytesRead != authPolicyData.length) | ||||
|                                        { | ||||
|                                           System.err.println("EnabledSvcsConfig()- Error reading policy file for " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii]); | ||||
|                                        } | ||||
|                                     } | ||||
|                                     catch (SecurityException e) | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- SecurityException accessing " + serviceFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString()); | ||||
|                                     } | ||||
|                                     catch (FileNotFoundException e) | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- No authentication policy file for " + serviceFolder); | ||||
|                                     } | ||||
|                                     catch (IOException e) | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- IOException reading " + serviceFolder + File.separator + m_authPolicyFileName + " Exception=" + e.toString()); | ||||
|                                     } | ||||
|  | ||||
|                                     try | ||||
|                                     { | ||||
|                                        authTokenConfig = new AuthTokenConfig(serviceFolder + File.separator + m_authTokenSettingsFileName); | ||||
|                                     } | ||||
|                                     catch (Exception e) | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + File.separator + m_authTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|                                     } | ||||
|  | ||||
|                                     try | ||||
|                                     { | ||||
|                                        idenTokenConfig = new IdenTokenConfig(serviceFolder + File.separator + m_idenTokenSettingsFileName); | ||||
|                                     } | ||||
|                                     catch (Exception e) | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + File.separator + m_idenTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|                                     } | ||||
|  | ||||
|                                     // Make sure that we have a policy file | ||||
|                                     if ((authPolicyData != null && authPolicyData.length != 0) | ||||
|                                         || (defaultAuthPolicyData != null && defaultAuthPolicyData.length != 0)) | ||||
|                                     { | ||||
|                                        // Instantiate SvcConfigEntry for this service and place it in our map | ||||
|                                        SvcConfigEntry svcConfigEntry = new SvcConfigEntry((authPolicyData != null && authPolicyData.length != 0) ? authPolicyData : defaultAuthPolicyData, | ||||
|                                                                                           (authTokenConfig != null) ? authTokenConfig : defaultAuthTokenConfig, | ||||
|                                                                                           (idenTokenConfig != null) ? idenTokenConfig : defaultIdenTokenConfig); | ||||
|  | ||||
|                                        // Add this entry to our map | ||||
|                                        System.err.println("EnabledSvcsConfig()- Adding entry in map for " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii]); | ||||
|                                        enabledSvcsConfigMap.put(hostFolderObjs[ii], svcConfigEntry); | ||||
|                                     } | ||||
|                                     else | ||||
|                                     { | ||||
|                                        System.err.println("EnabledSvcsConfig()- Unable to enable " + servicesConfigFolderObjs[i] + " " + hostFolderObjs[ii] + " due to no configured authentication policy"); | ||||
|                                     } | ||||
|                                  } | ||||
|                               } | ||||
|                               catch (SecurityException e) | ||||
|                               { | ||||
|                                  System.err.println("EnabledSvcsConfig()- SecurityException accessing " + serviceFolder + " Exception=" + e.toString()); | ||||
|                               } | ||||
|  | ||||
|                               // Add this hosts enabled services configuration map to the hosts map | ||||
|                               m_hostsMap.put(servicesConfigFolderObjs[i], enabledSvcsConfigMap); | ||||
|                            } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                            System.err.println("EnabledSvcsConfig()- No services configured for " + hostFolder); | ||||
|                         } | ||||
|                      } | ||||
|                   } | ||||
|                   catch (SecurityException e) | ||||
|                   { | ||||
|                      System.err.println("EnabledSvcsConfig()- SecurityException accessing " + hostFolder + " Exception=" + e.toString()); | ||||
|                   } | ||||
|                } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                System.err.println("EnabledSvcsConfig()- Unable to obtain services folder " + servicesConfigFolder + " objects"); | ||||
|             } | ||||
|          } | ||||
|          catch (SecurityException e) | ||||
|          { | ||||
|             System.err.println("EnabledSvcsConfig()- SecurityException accessing " + servicesConfigFolder + " Exception=" + e.toString()); | ||||
|          } | ||||
|       } | ||||
|       catch (SecurityException e) | ||||
|       { | ||||
|          System.err.println("EnabledSvcsConfig()- SecurityException accessing " + configFolder + " Exception=" + e.toString()); | ||||
|       } | ||||
|    }      | ||||
|  | ||||
|    /* | ||||
|     * Returns true if the specified service has been enabled to use authentication | ||||
|     * tokens. | ||||
|     */ | ||||
|    public boolean svcEnabled(String hostName, String serviceName) | ||||
|    { | ||||
|       // First try to obtain the Map of enabled services for the host | ||||
|       // tbd - Should we make this case insensitive? | ||||
|       Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName); | ||||
|       if (enabledSvcsConfigMap != null) | ||||
|       { | ||||
|          return enabledSvcsConfigMap.containsKey(serviceName); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          return false; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the data associated with the authentication policy file | ||||
|     * associated with the specified service. | ||||
|     */ | ||||
|    public byte[] getAuthPolicyFileDataForSvc(String hostName, String serviceName) | ||||
|    { | ||||
|       // First try to obtain the Map of enabled services for the host | ||||
|       // tbd - Should we make this case insensitive? | ||||
|       Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName); | ||||
|       if (enabledSvcsConfigMap != null) | ||||
|       { | ||||
|          // Retrieve SvcConfigEntry for the service from the map for the host | ||||
|          SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName); | ||||
|          if (svcConfigEntry != null) | ||||
|          { | ||||
|             return svcConfigEntry.m_authPolicyFileData; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             return null; | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          return null; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the authentication token configuration associated with the | ||||
|     * specified service. | ||||
|     */ | ||||
|    public AuthTokenConfig getAuthTokenConfig(String hostName, String serviceName) | ||||
|    { | ||||
|       // First try to obtain the Map of enabled services for the host | ||||
|       // tbd - Should we make this case insensitive? | ||||
|       Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName); | ||||
|       if (enabledSvcsConfigMap != null) | ||||
|       { | ||||
|          // Retrieve SvcConfigEntry for the service from the map for the host | ||||
|          SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName); | ||||
|          if (svcConfigEntry != null) | ||||
|          { | ||||
|             return svcConfigEntry.m_authTokenConfig; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             return null; | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          return null; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the identity token configuration associated with the | ||||
|     * specified service. | ||||
|     */ | ||||
|    public IdenTokenConfig getIdenTokenConfig(String hostName, String serviceName) | ||||
|    { | ||||
|       // First try to obtain the Map of enabled services for the host | ||||
|       // tbd - Should we make this case insensitive? | ||||
|       Map enabledSvcsConfigMap = (Map) m_hostsMap.get(hostName); | ||||
|       if (enabledSvcsConfigMap != null) | ||||
|       { | ||||
|          // Retrieve SvcConfigEntry for the service from the map for the host | ||||
|          SvcConfigEntry svcConfigEntry = (SvcConfigEntry) enabledSvcsConfigMap.get(serviceName); | ||||
|          if (svcConfigEntry != null) | ||||
|          { | ||||
|             return svcConfigEntry.m_idenTokenConfig; | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             return null; | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          return null; | ||||
|       } | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,127 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.io.PrintWriter; | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
|  * GetAuthPolicy Class. | ||||
|  *  | ||||
|  * This class processes get authentication policy requests for a particular | ||||
|  * service. | ||||
|  *  | ||||
|  */ | ||||
| public class GetAuthPolicy implements RpcMethod | ||||
| { | ||||
|    private SvcConfig          m_svcConfig; | ||||
|    private EnabledSvcsConfig  m_enabledSvcsConfig; | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public GetAuthPolicy() throws Exception | ||||
|    { | ||||
|       // Nothing to do at this time | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Initialize the Rpc method. | ||||
|     */ | ||||
|    public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception | ||||
|    { | ||||
|       m_svcConfig = svcConfig; | ||||
|       m_enabledSvcsConfig = enabledSvcsConfig; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Process Rpc. | ||||
|     */ | ||||
|    public void invoke(InputStream inStream, PrintWriter out) throws IOException | ||||
|    { | ||||
|       try | ||||
|       { | ||||
|          System.err.println("GetAuthPolicy.invoke()"); | ||||
|  | ||||
|          // Read and parse the GetAuthPolicyReqMsg sent from the client | ||||
|          GetAuthPolicyReqMsg getAuthPolicyReqMsg = new GetAuthPolicyReqMsg(inStream); | ||||
|  | ||||
|          // Verify that the service is enabled | ||||
|          if (m_enabledSvcsConfig.svcEnabled(getAuthPolicyReqMsg.getHostName(), getAuthPolicyReqMsg.getServiceName())) | ||||
|          { | ||||
|             // Get the auth policy for the service | ||||
|             byte[] authPolicy = m_enabledSvcsConfig.getAuthPolicyFileDataForSvc(getAuthPolicyReqMsg.getHostName(), | ||||
|                                                                                 getAuthPolicyReqMsg.getServiceName()); | ||||
|             if (authPolicy != null) | ||||
|             { | ||||
|                // Write out the response | ||||
|                GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpOkStatusMsg, | ||||
|                                                                                     ProtoDefs.httpOkStatusCode, | ||||
|                                                                                     new String(Base64Coder.encode(authPolicy))); | ||||
|                out.println(getAuthPolicyRespMsg.toString()); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                System.err.println("GetAuthPolicy.invoke()- authPolicy is null for enabled service: " + getAuthPolicyReqMsg.getServiceName());  | ||||
|                GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg, | ||||
|                                                                                     ProtoDefs.httpServerErrorStatusCode); | ||||
|                out.println(getAuthPolicyRespMsg.toString()); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             // The service has not been enabled to utilize our authentication tokens | ||||
|             GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpNotFoundStatusMsg, | ||||
|                                                                                  ProtoDefs.httpNotFoundStatusCode); | ||||
|             out.println(getAuthPolicyRespMsg.toString()); | ||||
|          } | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          System.err.println("GetAuthPolicy.invoke()- Exception: " + e.toString());  | ||||
|  | ||||
|          // Write out the response | ||||
|          try | ||||
|          { | ||||
|             GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg, | ||||
|                                                                                  ProtoDefs.httpServerErrorStatusCode); | ||||
|             out.println(getAuthPolicyRespMsg.toString()); | ||||
|          } | ||||
|          catch (Exception e2) | ||||
|          { | ||||
|             System.err.println("GetAuthPolicy.invoke()- Exception trying to construct response msg: " + e2.toString());  | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Return the method id. | ||||
|     */ | ||||
|    public String getId() | ||||
|    { | ||||
|       return "GetAuthPolicy"; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,282 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.InputStream; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
| /** | ||||
|  * GetAuthPolicyReqMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent by Casa Client when requesting | ||||
|  * authenication policy to authenticate an entity to a particular service. | ||||
|  * The format of the the message is as follows: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_policy_req> | ||||
|  * <service>service name</service> | ||||
|  * <host>host name</host> | ||||
|  * </get_auth_policy_req> | ||||
|  *  | ||||
|  */ | ||||
| public class GetAuthPolicyReqMsg | ||||
| { | ||||
|  | ||||
|    protected String  m_serviceName = null; | ||||
|    protected String  m_hostName = null; | ||||
|  | ||||
|    /* | ||||
|     * Class for handling GetAuthPolicyReq msg 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_SERVICE_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_SERVICE_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_SERVICE_DATA = 4; | ||||
|       private final static int AWAITING_HOST_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_HOST_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_HOST_DATA = 7; | ||||
|       private final static int DONE_PARSING = 8; | ||||
|  | ||||
|       private GetAuthPolicyReqMsg   m_GetAuthPolicyReqMsg; | ||||
|       private int             m_state; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (GetAuthPolicyReqMsg GetAuthPolicyReqMsg) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_GetAuthPolicyReqMsg = GetAuthPolicyReqMsg; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("GetAuthPolicyReqMsg SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * 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 (ProtoDefs.getAuthPolicyRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SERVICE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SERVICE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.serviceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SERVICE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.hostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_HOST_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|  | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.getAuthPolicyRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SERVICE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.serviceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_HOST_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.hostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthPolicyReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("GetAuthPolicyReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_SERVICE_DATA: | ||||
|                // Consume the data | ||||
|                m_GetAuthPolicyReqMsg.m_serviceName = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SERVICE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_DATA: | ||||
|                // Consume the data | ||||
|                m_GetAuthPolicyReqMsg.m_hostName = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_HOST_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public GetAuthPolicyReqMsg (InputStream inStream) throws Exception | ||||
|    { | ||||
|       try | ||||
|       { | ||||
|          // Parse the GetAuthPolicyReqMsg | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          System.err.println("GetAuthPolicyReqMsg()- Parse exception: " + e.toString());  | ||||
|          throw new Exception("Protocol error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the service name.  | ||||
|     */ | ||||
|    public String getServiceName() throws Exception | ||||
|    { | ||||
|       return m_serviceName; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the host name.  | ||||
|     */ | ||||
|    public String getHostName() throws Exception | ||||
|    { | ||||
|       return m_hostName; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,111 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * GetAuthPolicyRespMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent to the Casa Client as a | ||||
|  * response to a get authentication token request. The format of | ||||
|  * the message is as follows when the response includes an | ||||
|  * authentication token: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_policy_resp> | ||||
|  * <status><description>OK</description>200</status> | ||||
|  * <auth_policy>authentication policy data</auth_policy> | ||||
|  * </get_auth_policy_resp> | ||||
|  *  | ||||
|  * The format of the message is as follows when the response does not | ||||
|  * include an authentication token. | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_policy_resp> | ||||
|  * <status><description>status description</description>status code</status> | ||||
|  * </get_auth_policy_resp> | ||||
|  *  | ||||
|  * Plase note that the protocol utilizes the status codes defined | ||||
|  * in the HTTP 1.1 Specification. | ||||
|  * | ||||
|  */ | ||||
| public class GetAuthPolicyRespMsg | ||||
| { | ||||
|  | ||||
|    String   m_msg; | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that does not include the authentication policy. | ||||
|     */ | ||||
|    public GetAuthPolicyRespMsg ( | ||||
|                                String statusDescription, | ||||
|                                String statusCode) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that includes the authentication policy. | ||||
|     */ | ||||
|    public GetAuthPolicyRespMsg ( | ||||
|                                String statusDescription, | ||||
|                                String statusCode, | ||||
|                                String authPolicy) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "</" + ProtoDefs.authPolicyElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the GetAuthPolicyRespMsg. | ||||
|     */ | ||||
|    public String toString() | ||||
|    { | ||||
|       return m_msg; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,331 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.InputStream; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
| /** | ||||
|  * GetAuthTokReqMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent by Casa Client when requesting | ||||
|  * a token to authenticate an entity to a particular service. The format of | ||||
|  * the message is as follows: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_token_req> | ||||
|  * <service>service name</service> | ||||
|  * <host>host name</host> | ||||
|  * <session_token>session token data</session_token> | ||||
|  * </get_auth_token_req> | ||||
|  *  | ||||
|  */ | ||||
| public class GetAuthTokReqMsg | ||||
| { | ||||
|  | ||||
|    protected String  m_serviceName = null; | ||||
|    protected String  m_hostName = null; | ||||
|    protected String  m_sessionToken = null; | ||||
|  | ||||
|    /* | ||||
|     * Class for handling GetAuthTokReq msg 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_SERVICE_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_SERVICE_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_SERVICE_DATA = 4; | ||||
|       private final static int AWAITING_HOST_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_HOST_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_HOST_DATA = 7; | ||||
|       private final static int AWAITING_SESSION_TOKEN_ELEMENT_START = 8; | ||||
|       private final static int AWAITING_SESSION_TOKEN_ELEMENT_END = 9; | ||||
|       private final static int AWAITING_SESSION_TOKEN_DATA = 10; | ||||
|       private final static int DONE_PARSING = 11; | ||||
|  | ||||
|       private GetAuthTokReqMsg   m_GetAuthTokReqMsg; | ||||
|       private int          m_state; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (GetAuthTokReqMsg GetAuthTokReqMsg) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_GetAuthTokReqMsg = GetAuthTokReqMsg; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("GetAuthTokReqMsg SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * 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 (ProtoDefs.getAuthTokRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SERVICE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SERVICE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.serviceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SERVICE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.hostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_HOST_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|  | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SESSION_TOKEN_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.sessionTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SESSION_TOKEN_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.getAuthTokRequestElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SERVICE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.serviceElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_HOST_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.hostElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SESSION_TOKEN_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SESSION_TOKEN_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.sessionTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("GetAuthTokReqMsg SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("GetAuthTokReqMsg SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_SERVICE_DATA: | ||||
|                // Consume the data | ||||
|                m_GetAuthTokReqMsg.m_serviceName = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SERVICE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_HOST_DATA: | ||||
|                // Consume the data | ||||
|                m_GetAuthTokReqMsg.m_hostName = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_HOST_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SESSION_TOKEN_DATA: | ||||
|                // Consume the data | ||||
|                m_GetAuthTokReqMsg.m_sessionToken = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SESSION_TOKEN_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public GetAuthTokReqMsg (InputStream inStream) throws Exception | ||||
|    { | ||||
|       try | ||||
|       { | ||||
|          // Parse the GetAuthTokReqMsg | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          System.err.println("GetAuthTokReqMsg()- Parse exception: " + e.toString());  | ||||
|          throw new Exception("Protocol error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the service name.  | ||||
|     */ | ||||
|    public String getServiceName() throws Exception | ||||
|    { | ||||
|       return m_serviceName; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the host name.  | ||||
|     */ | ||||
|    public String getHostName() throws Exception | ||||
|    { | ||||
|       return m_hostName; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the session token.  | ||||
|     */ | ||||
|    public String getSessionToken() throws Exception | ||||
|    { | ||||
|       return m_sessionToken; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,115 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * GetAuthTokRespMsg Class. | ||||
|  *  | ||||
|  * This class deals with the message sent to the Casa Client as a | ||||
|  * response to a get authentication token request. The format of | ||||
|  * the message is as follows when the response includes an | ||||
|  * authentication token: | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_tok_resp> | ||||
|  * <status><description>OK</description>200</status> | ||||
|  * <auth_token><lifetime>lifetime value</lifetime>authentication token data</auth_token> | ||||
|  * </get_auth_tok_resp> | ||||
|  *  | ||||
|  * The format of the message is as follows when the response does not | ||||
|  * include an authentication token. | ||||
|  *  | ||||
|  * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
|  * <get_auth_tok_resp> | ||||
|  * <status><description>status description</description>status code</status> | ||||
|  * </get_auth_tok_resp> | ||||
|  *  | ||||
|  * Plase note that the protocol utilizes the status codes defined | ||||
|  * in the HTTP 1.1 Specification. | ||||
|  * | ||||
|  */ | ||||
| public class GetAuthTokRespMsg | ||||
| { | ||||
|  | ||||
|    String   m_msg; | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that does not include the authentication token. | ||||
|     */ | ||||
|    public GetAuthTokRespMsg ( | ||||
|                             String statusDescription, | ||||
|                             String statusCode) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor for a msg that includes the authentication token. | ||||
|     */ | ||||
|    public GetAuthTokRespMsg ( | ||||
|                             String statusDescription, | ||||
|                             String statusCode, | ||||
|                             String authToken, | ||||
|                             String authTokenLifetime) throws Exception | ||||
|    { | ||||
|       // Get a StringBuffer to help us with the construction of the message | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.statusElementName + ">" | ||||
|                 + "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">" | ||||
|                 + ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.authTokenElementName + ">" | ||||
|                 + "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">" | ||||
|                 + authToken + "</" + ProtoDefs.authTokenElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // The message has now been built, save it. | ||||
|       m_msg = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the GetAuthTokRespMsg. | ||||
|     */ | ||||
|    public String toString() | ||||
|    { | ||||
|       return m_msg; | ||||
|    } | ||||
| } | ||||
|  | ||||
| @@ -0,0 +1,146 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.PrintWriter; | ||||
|  | ||||
| /** | ||||
|  * GetAuthToken Class. | ||||
|  *  | ||||
|  * This class processes requests for tokens to authenticate an entity | ||||
|  * to a particular service. | ||||
|  *  | ||||
|  */ | ||||
| public class GetAuthToken implements RpcMethod | ||||
| { | ||||
|    private SvcConfig          m_svcConfig; | ||||
|    private EnabledSvcsConfig  m_enabledSvcsConfig; | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public GetAuthToken() throws Exception | ||||
|    { | ||||
|       // Nothing to do at this time | ||||
|    }      | ||||
|  | ||||
|    /* | ||||
|     * Initialize the Rpc method. | ||||
|     */ | ||||
|    public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception | ||||
|    { | ||||
|       m_svcConfig = svcConfig; | ||||
|       m_enabledSvcsConfig = enabledSvcsConfig; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Process Rpc. | ||||
|     */ | ||||
|    public void invoke(InputStream inStream, PrintWriter out) throws IOException | ||||
|    { | ||||
|       try | ||||
|       { | ||||
|          System.err.println("GetAuthToken.invoke()"); | ||||
|  | ||||
|          // Parse the GetAuthTokReqMsg sent from the client | ||||
|          GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream); | ||||
|  | ||||
|          // Verify that the service is enabled | ||||
|          if (m_enabledSvcsConfig.svcEnabled(getAuthTokReqMsg.getHostName(), | ||||
|                                             getAuthTokReqMsg.getServiceName())) | ||||
|          { | ||||
|             // Now create a session token (This validates the session token provided). | ||||
|             SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken()); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                // Create the Authentication Token | ||||
|                AuthToken authToken = new AuthToken(sessionToken.getIdentId(), | ||||
|                                                    sessionToken.getRealm(), | ||||
|                                                    getAuthTokReqMsg.getServiceName(), | ||||
|                                                    getAuthTokReqMsg.getHostName(), | ||||
|                                                    m_svcConfig, | ||||
|                                                    m_enabledSvcsConfig); | ||||
|  | ||||
|                // Write out the response | ||||
|                GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg, | ||||
|                                                                            ProtoDefs.httpOkStatusCode, | ||||
|                                                                            authToken.toString(), | ||||
|                                                                            authToken.getLifetime()); | ||||
|                out.println(getAuthTokRespMsg.toString()); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());  | ||||
|  | ||||
|                // Write out the response | ||||
|                try | ||||
|                { | ||||
|                   GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpUnauthorizedStatusMsg, | ||||
|                                                                               ProtoDefs.httpUnauthorizedStatusCode); | ||||
|                   out.println(getAuthTokRespMsg.toString()); | ||||
|                } | ||||
|                catch (Exception e2) | ||||
|                { | ||||
|                   System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());  | ||||
|                } | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             // The service has not been enabled to utilize our authentication tokens | ||||
|             GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpNotFoundStatusMsg, | ||||
|                                                                         ProtoDefs.httpNotFoundStatusCode); | ||||
|             out.println(getAuthTokRespMsg.toString()); | ||||
|          } | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());  | ||||
|  | ||||
|          // Write out the response | ||||
|          try | ||||
|          { | ||||
|             GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg, | ||||
|                                                                         ProtoDefs.httpServerErrorStatusCode); | ||||
|             out.println(getAuthTokRespMsg.toString()); | ||||
|          } | ||||
|          catch (Exception e2) | ||||
|          { | ||||
|             System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());  | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Return the method id. | ||||
|     */ | ||||
|    public String getId() | ||||
|    { | ||||
|       return "GetAuthToken"; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,294 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * IdenTokenConfig Class. | ||||
|  *  | ||||
|  * This class obtains and maintains identity token configuration. | ||||
|  *  | ||||
|  */ | ||||
| public class IdenTokenConfig | ||||
| { | ||||
|    // Well known identity token configuration settings | ||||
|    public final static String EncryptAttributes = "EncryptAttributes"; | ||||
|    public final static String Attributes = "Attributes"; | ||||
|  | ||||
|    // Default configuration values | ||||
|    private String m_defaultEncryptAttributesValue = "false"; | ||||
|    private String m_defaultAttributesValue = "sn"; | ||||
|  | ||||
|    private Map       m_tokenSettingsMap; | ||||
|    private String[]  m_identityAttributes; | ||||
|  | ||||
|    /* | ||||
|     * 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("IdenTokenConfig 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("IdenTokenConfig 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("IdenTokenConfig 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_DATA: | ||||
|             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("IdenTokenConfig SAXHandler.endElement()- Un-expected element"); | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("IdenTokenConfig 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 | ||||
|             // tbd - Add code to aggregate attributes specified as multiple elements | ||||
|             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 IdenTokenConfig() throws Exception | ||||
|    { | ||||
|       System.err.println("IdenTokenConfig()- Default"); | ||||
|  | ||||
|       // Create a map to keep track of the token settings | ||||
|       m_tokenSettingsMap = new HashMap(); | ||||
|  | ||||
|       // Set the default settings in our map | ||||
|       m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public IdenTokenConfig(String idenTokenSettingsFileName) throws Exception | ||||
|    { | ||||
|       System.err.println("IdenTokenConfig()-"); | ||||
|  | ||||
|       // Create a map to keep track of the token settings | ||||
|       m_tokenSettingsMap = new HashMap(); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Get an input stream to read from the token settings file | ||||
|          File f = new File(idenTokenSettingsFileName); | ||||
|          FileInputStream inStream = new FileInputStream(f); | ||||
|  | ||||
|          // Parse the file | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(m_tokenSettingsMap); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|           | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|  | ||||
|          inStream.close(); | ||||
|  | ||||
|          // Process the specified attributes | ||||
|          if (m_tokenSettingsMap.containsKey(Attributes) == false) | ||||
|          { | ||||
|             System.err.println("IdenTokenConfig()- Attributes not configured, defaulting them."); | ||||
|             m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue); | ||||
|          } | ||||
|          String attributes = (String) m_tokenSettingsMap.get(Attributes); | ||||
|          m_identityAttributes = attributes.split(","); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|         System.err.println("IdenTokenConfig()- " + idenTokenSettingsFileName + " format error, exception: " + e.toString());  | ||||
|         throw new Exception("IdenTokenConfig()- authtoken.settings format error"); | ||||
|       } | ||||
|       catch (SecurityException e) | ||||
|       { | ||||
|          System.err.println("IdenTokenConfig()- SecurityException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|          throw new Exception("IdenTokenConfig()- Not able to access file"); | ||||
|       } | ||||
|       catch (FileNotFoundException e) | ||||
|       { | ||||
|          System.err.println("IdenTokenConfig()- File " + idenTokenSettingsFileName + " not found"); | ||||
|          throw new Exception("IdenTokenConfig()- File not found"); | ||||
|       } | ||||
|       catch (IOException e) | ||||
|       { | ||||
|          System.err.println("IdenTokenConfig()- IOException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString()); | ||||
|          throw new Exception("IdenTokenConfig()- 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_tokenSettingsMap.get(settingName); | ||||
|       if (value == null) | ||||
|       { | ||||
|          System.err.println("IdenTokenConfig.getSetting()- Did not find setting " + settingName); | ||||
|  | ||||
|          // The setting is not in our map, check if it is one to | ||||
|          // which we have defaults. | ||||
|          if (settingName.equals(EncryptAttributes) == true) | ||||
|          { | ||||
|             value = m_defaultEncryptAttributesValue; | ||||
|             System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_tokenSettingsMap.put(EncryptAttributes, m_defaultEncryptAttributesValue); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          System.err.println("IdenTokenConfig.getSetting()- Found setting " + settingName); | ||||
|          System.err.println("IdenTokenConfig.getSetting()- Setting value = " + value); | ||||
|       } | ||||
|  | ||||
|       return value; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns the identity attributes that must be included in the token. | ||||
|     */ | ||||
|    public String[] getAttributes() throws Exception | ||||
|    { | ||||
|       return m_identityAttributes; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,93 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /* | ||||
|  * IdentityToken Interface. | ||||
|  *  | ||||
|  * This is the interface implemented by Identity Token Providers. | ||||
|  */ | ||||
| public interface IdentityToken | ||||
| { | ||||
|    /* | ||||
|     * Initialize the token with parameters. | ||||
|     */ | ||||
|    void initialize(String identityId, | ||||
|                    String sourceName, | ||||
|                    String targetService, | ||||
|                    String targetHost, | ||||
|                    SvcConfig svcConfig) throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Initialize the token object with encoded token string. | ||||
|     */ | ||||
|    void initialize(String encodedToken) throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns encoded token string. | ||||
|     *  | ||||
|     * IMPORTANT: The token string can not contain the substring "]]>" | ||||
|     * within it. | ||||
|     */ | ||||
|    String getEncodedToken() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the identity token provider type. | ||||
|     */ | ||||
|    String getProviderType() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the identity id. | ||||
|     */ | ||||
|    String getIdentityId() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the name associated with the | ||||
|     * identity source. | ||||
|     */ | ||||
|    String getSourceName() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the url associated with the | ||||
|     * identity source. | ||||
|     */ | ||||
|    String getSourceUrl() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the name of the targeted service. | ||||
|     */ | ||||
|    String getTargetService() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containig the name of the host where the | ||||
|     * targeted service resides. | ||||
|     */ | ||||
|    String getTargetHost() throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Returns the attributes of the identity. | ||||
|     */ | ||||
|    javax.naming.directory.Attributes getAttributes() throws Exception; | ||||
| } | ||||
| @@ -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.Serializable; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.PrintWriter; | ||||
| import java.util.Hashtable; | ||||
|  | ||||
| import javax.naming.Context; | ||||
| import javax.naming.NamingEnumeration; | ||||
| import javax.naming.NamingException; | ||||
| import javax.naming.directory.Attributes; | ||||
| import javax.naming.directory.BasicAttribute; | ||||
| import javax.naming.directory.BasicAttributes; | ||||
| import javax.naming.directory.DirContext; | ||||
| import javax.naming.directory.InitialDirContext; | ||||
| import javax.naming.directory.SearchResult; | ||||
| import javax.naming.directory.SearchControls; | ||||
|  | ||||
| import org.ietf.jgss.GSSContext; | ||||
| import org.ietf.jgss.GSSCredential; | ||||
| import org.ietf.jgss.GSSException; | ||||
| import org.ietf.jgss.GSSManager; | ||||
| import org.ietf.jgss.GSSName; | ||||
| import org.ietf.jgss.Oid; | ||||
|  | ||||
| import org.bandit.ia.IAContext; | ||||
|  | ||||
| /** | ||||
|  * Krb5Authenticate Class. | ||||
|  *  | ||||
|  * This class implementes an authentication mechanism for | ||||
|  * the processing of authentication requests utilizing a | ||||
|  * Kerberos5 token. | ||||
|  *  | ||||
|  */ | ||||
| public class Krb5Authenticate implements AuthMechanism, Serializable | ||||
| { | ||||
|    private static final String ServicePrincipalNameSetting = "ServicePrincipalName"; | ||||
|  | ||||
|    private SvcConfig       m_svcConfig; | ||||
|    private AuthMechConfig  m_mechConfig; | ||||
|  | ||||
|    /* | ||||
|     * GSS Long Lived variables | ||||
|     */ | ||||
|    protected GSSManager       m_manager; | ||||
|    protected Oid              m_krb5; | ||||
|    protected GSSName          m_svcName; | ||||
|    protected GSSCredential    m_credential;  | ||||
|  | ||||
|    /* | ||||
|     * Krb5 Token Class. | ||||
|     */ | ||||
|    private class Krb5Token | ||||
|    { | ||||
|       private String m_principalName = ""; | ||||
|  | ||||
|       /* | ||||
|        * The format of the Krb5 token is as follows: | ||||
|        *  | ||||
|        * Base64.encode(GSS-API Token data)); | ||||
|        */ | ||||
|       public Krb5Token(String encodedToken, Krb5Authenticate parent) throws Exception | ||||
|       { | ||||
|          // Decode the token | ||||
|          char[] tokenChars = new char[encodedToken.length()]; | ||||
|          encodedToken.getChars(0, tokenChars.length, tokenChars, 0); | ||||
|          byte[] tokenBytes = Base64Coder.decode(tokenChars); | ||||
|  | ||||
|          try | ||||
|          { | ||||
|             // Create a context and validate the token | ||||
|             GSSContext context = parent.m_manager.createContext(parent.m_credential); | ||||
|             System.err.println("tokenLength = " + tokenBytes.length); | ||||
|             context.acceptSecContext(tokenBytes, 0, tokenBytes.length); | ||||
|  | ||||
|             // Save the principal name of the authenticated entity | ||||
|             GSSName principalName = context.getSrcName(); | ||||
|             m_principalName = principalName.toString(); | ||||
|  | ||||
|             // Clean up | ||||
|             context.dispose(); | ||||
|          } | ||||
|          catch (GSSException e) | ||||
|          { | ||||
|             System.err.println("Krb5Authenticate Krb5Token()- GSS Exception caught: " + e.getLocalizedMessage()); | ||||
|             throw new Exception("Authentication Failure"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * Returns the name of the authenticated principal | ||||
|        */ | ||||
|       public String getPrincipalName() | ||||
|       { | ||||
|          return m_principalName; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public Krb5Authenticate() throws Exception | ||||
|    { | ||||
|       // Nothing to do at this time | ||||
|    }      | ||||
|  | ||||
|    /* | ||||
|     * Initialize the mechanism. | ||||
|     */ | ||||
|    public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception | ||||
|    { | ||||
|       m_svcConfig = svcConfig; | ||||
|       m_mechConfig = mechConfig; | ||||
|  | ||||
|       String servicePrincipal = mechConfig.getSetting(ServicePrincipalNameSetting); | ||||
|       if (servicePrincipal != null) | ||||
|       { | ||||
|          try | ||||
|          { | ||||
|             // Initalize our GSS variables | ||||
|             // | ||||
|             // Get an instance of the default GSSManager | ||||
|             m_manager = GSSManager.getInstance(); | ||||
|  | ||||
|             // Create an OID specifying the Krb5 mechanism | ||||
|             m_krb5 = new Oid("1.2.840.113554.1.2.2"); | ||||
|  | ||||
|             // Create our host based service name | ||||
|             m_svcName = m_manager.createName(servicePrincipal, | ||||
|                                              GSSName.NT_HOSTBASED_SERVICE,  | ||||
|                                              m_krb5); | ||||
|  | ||||
|             // Now acquire our credentials | ||||
|             m_credential = m_manager.createCredential(m_svcName,  | ||||
|                                                       GSSCredential.INDEFINITE_LIFETIME,  | ||||
|                                                       m_krb5,  | ||||
|                                                       GSSCredential.ACCEPT_ONLY); | ||||
|          } | ||||
|          catch (GSSException e) | ||||
|          { | ||||
|             System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage()); | ||||
|             throw new Exception("Failed to instantiate needed GSS objects"); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          System.err.println("Krb5Authenticate()- Service Principal Name not configured"); | ||||
|          throw new Exception("Service Principal Name not configured"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * invoke() implementation. | ||||
|     */ | ||||
|    public String invoke(AuthReqMsg authReqMsg) throws Exception | ||||
|    { | ||||
|       String identId = null; | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          System.err.println("Krb5Authenticate.invoke()"); | ||||
|  | ||||
|          // Now parse the Kerberos Token | ||||
|          Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this); | ||||
|  | ||||
|          // Open a directory context and use it to identify the users | ||||
|          // associated with the specified surname. | ||||
|          Hashtable env = new Hashtable(); | ||||
|          env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); | ||||
|          env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); | ||||
|          env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm()); | ||||
|  | ||||
|          DirContext ctx = new InitialDirContext(env); | ||||
|  | ||||
|          // Now search for a user with a matching  kerberos principal name. | ||||
|          // | ||||
|          // Set up a search control so that the search is scoped to the sub-tree | ||||
|          SearchControls controls = new SearchControls(); | ||||
|          controls.setSearchScope(SearchControls.SUBTREE_SCOPE); | ||||
|  | ||||
|          // Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit | ||||
|          String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext); | ||||
|          if (searchContext == null) | ||||
|          { | ||||
|             // A start search context was not configured, start from the root. | ||||
|             searchContext = ""; | ||||
|          } | ||||
|  | ||||
|          // Perform the search | ||||
|          NamingEnumeration answer = ctx.search(searchContext, | ||||
|                                                "(krbPrincipalName={0})", | ||||
|                                                new String[] {krb5Token.getPrincipalName()}, | ||||
|                                                controls); | ||||
|  | ||||
|          // Proceed based on the result of the search | ||||
|          if (answer.hasMore()) | ||||
|          { | ||||
|             // The search succeeded, set the identity id. | ||||
|             SearchResult sr = (SearchResult)answer.next(); | ||||
|             if (searchContext.equals("")) | ||||
|             { | ||||
|                identId = sr.getNameInNamespace(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                identId = sr.getName() + "," + searchContext; | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|       catch (NamingException e) | ||||
|       { | ||||
|          // Log the error | ||||
|          System.err.println("Krb5Authenticate.invoke()- NamingException: " + e.getExplanation()); | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          System.err.println("Krb5Authenticate.invoke()- Exception: " + e.toString());  | ||||
|       } | ||||
|  | ||||
|       // Return the authentication result | ||||
|       return identId; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Return the mechanism id. | ||||
|     */ | ||||
|    public String getId() | ||||
|    { | ||||
|       return "Krb5Authenticate"; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
| <settings> | ||||
| 	<description>This is the authentication mechanism for the Krb5Authenticate scheme. The Krb5Authenticate scheme authenticates entities using Kerberos-V tokens.</description> | ||||
| 	<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName> | ||||
| 	<RelativeClassPath>WEB-INF/classes</RelativeClassPath> | ||||
| 	<ServicePrincipalName>Specify the service's kerberos principal name</ServicePrincipalName> | ||||
| </settings> | ||||
| @@ -0,0 +1,63 @@ | ||||
| ####################################################################### | ||||
| # | ||||
| #  Copyright (C) 2006 Novell, Inc. | ||||
| # | ||||
| #  This program is free software; you can redistribute it and/or | ||||
| #  modify it under the terms of the GNU General Public | ||||
| #  License as published by the Free Software Foundation; either | ||||
| #  version 2 of the License, or (at your option) any later version. | ||||
| # | ||||
| #  This program 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 | ||||
| #  General Public License for more details. | ||||
| # | ||||
| #  You should have received a copy of the GNU General Public | ||||
| #  License along with this program; if not, write to the Free | ||||
| #  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| # | ||||
| #  Author: Juan Carlos Luciani <jluciani@novell.com> | ||||
| # | ||||
| ####################################################################### | ||||
|  | ||||
| SUBDIRS =  | ||||
|  | ||||
| DIST_SUBDIRS = | ||||
|  | ||||
| JAVAFILES = ProtoDefs.java \ | ||||
| 	AuthMechConfig.java \ | ||||
| 	SvcConfig.java \ | ||||
| 	IdenTokenConfig.java \ | ||||
| 	AuthTokenConfig.java \ | ||||
| 	EnabledSvcsConfig.java \ | ||||
| 	AuthMechanism.java \ | ||||
| 	Authenticate.java \ | ||||
| 	RpcMethod.java \ | ||||
| 	Rpc.java \ | ||||
| 	GetAuthPolicy.java \ | ||||
| 	Base64Coder.java \ | ||||
| 	AuthReqMsg.java \ | ||||
| 	AuthRespMsg.java \ | ||||
| 	IdentityToken.java \ | ||||
| 	CasaIdentityToken.java \ | ||||
| 	AuthToken.java \ | ||||
| 	GetAuthPolicyReqMsg.java \ | ||||
| 	GetAuthPolicyRespMsg.java \ | ||||
| 	GetAuthToken.java \ | ||||
| 	GetAuthTokReqMsg.java \ | ||||
| 	GetAuthTokRespMsg.java \ | ||||
| 	Krb5Authenticate.java \ | ||||
| 	PwdAuthenticate.java \ | ||||
| 	SessionToken.java | ||||
|  | ||||
| EXTRA_DIST = $(JAVAFILES) \ | ||||
| 		Krb5_mechanism.settings \ | ||||
| 		Pwd_mechanism.settings | ||||
|  | ||||
| .PHONY: package package-clean package-install package-uninstall | ||||
| package package-clean package-install package-uninstall: | ||||
| 	$(MAKE) -C $(TARGET_OS) $@ | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile.in | ||||
|  | ||||
| @@ -0,0 +1,86 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /* | ||||
|  * ProDefs Class. | ||||
|  *  | ||||
|  * This class contains constants utilized in the Casa Client/Server | ||||
|  * protocol. | ||||
|  *  | ||||
|  */ | ||||
| public class ProtoDefs | ||||
| { | ||||
|  | ||||
|    /* | ||||
|     * XML Declaration used in the Casa Client/Server protocol | ||||
|     */ | ||||
|    public final static String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"; | ||||
|  | ||||
|    /* | ||||
|     * XML Element Name Constants for the documents exchanged between the | ||||
|     * Casa Client and the Casa Server. | ||||
|     */ | ||||
|    public final static String authRequestElementName = "auth_req"; | ||||
|    public final static String authResponseElementName = "auth_resp"; | ||||
|    public final static String getAuthPolicyRequestElementName = "get_auth_policy_req"; | ||||
|    public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp"; | ||||
|    public final static String getAuthTokRequestElementName = "get_auth_tok_req"; | ||||
|    public final static String getAuthTokResponseElementName = "get_auth_tok_resp"; | ||||
|    public final static String authMechTokenElementName = "auth_mech_token"; | ||||
|    public final static String statusElementName = "status"; | ||||
|    public final static String sessionTokenElementName = "session_token"; | ||||
|    public final static String authTokenElementName = "auth_token"; | ||||
|    public final static String authPolicyElementName = "auth_policy"; | ||||
|    public final static String identTokenElementName = "ident_token"; | ||||
|    public final static String lifetimeElementName = "lifetime"; | ||||
|    public final static String signatureElementName = "signature"; | ||||
|    public final static String typeElementName = "type"; | ||||
|    public final static String descriptionElementName = "description"; | ||||
|    public final static String serviceElementName = "service"; | ||||
|    public final static String hostElementName = "host"; | ||||
|    public final static String identIdElementName = "ident_id"; | ||||
|    public final static String realmElementName = "realm"; | ||||
|    public final static String authSourceElementName = "auth_source"; | ||||
|    public final static String mechanismElementName = "mechanism"; | ||||
|    public final static String mechanismInfoElementName = "mechanism_info"; | ||||
|  | ||||
|    /* | ||||
|     * Configurable operating parameters | ||||
|     */ | ||||
|    public String sessionTokenLifetime = "360"; | ||||
|  | ||||
|    /* | ||||
|     * HTTP Status Codes and Messages | ||||
|     */ | ||||
|    public final static String httpOkStatusCode = "200"; | ||||
|    public final static String httpOkStatusMsg = "OK"; | ||||
|    public final static String httpUnauthorizedStatusCode = "401"; | ||||
|    public final static String httpUnauthorizedStatusMsg = "Unauthorized"; | ||||
|    public final static String httpNotFoundStatusCode = "404"; | ||||
|    public final static String httpNotFoundStatusMsg = "Not Found"; | ||||
|    public final static String httpServerErrorStatusCode = "500"; | ||||
|    public final static String httpServerErrorStatusMsg = "Internal Server Error"; | ||||
| } | ||||
| @@ -0,0 +1,223 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.Serializable; | ||||
| import java.io.BufferedReader; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.PrintWriter; | ||||
| import java.io.StringReader; | ||||
| import java.util.Hashtable; | ||||
|  | ||||
| import javax.naming.Context; | ||||
| import javax.naming.NamingEnumeration; | ||||
| import javax.naming.directory.BasicAttribute; | ||||
| import javax.naming.directory.BasicAttributes; | ||||
| import javax.naming.directory.InitialDirContext; | ||||
| import javax.naming.directory.DirContext; | ||||
| import javax.naming.directory.Attributes; | ||||
| import javax.naming.directory.SearchResult; | ||||
| import javax.naming.directory.SearchControls; | ||||
| import javax.naming.NamingException; | ||||
|  | ||||
| import org.bandit.ia.IAContext; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * PwdAuthenticate Class. | ||||
|  *  | ||||
|  * This class implementes an authentication mechanism for | ||||
|  * the processing of authentication requests utilizing a | ||||
|  * username/password token. | ||||
|  *  | ||||
|  */ | ||||
| public class PwdAuthenticate implements AuthMechanism, Serializable | ||||
| { | ||||
|    private SvcConfig       m_svcConfig; | ||||
|    private AuthMechConfig  m_mechConfig; | ||||
|  | ||||
|    /* | ||||
|     * Password Token Class. | ||||
|     */ | ||||
|    private class PwToken | ||||
|    { | ||||
|       private String m_username = ""; | ||||
|       private String m_password = ""; | ||||
|  | ||||
|       /* | ||||
|        * The format of the Pw token is as follows: | ||||
|        *  | ||||
|        * Base64.encode(new String("username\r\n" + "password\r\n")); | ||||
|        */ | ||||
|       public PwToken(String encodedToken) throws IOException | ||||
|       { | ||||
|          // Decode the token | ||||
|          String token = Base64Coder.decode(encodedToken); | ||||
|  | ||||
|          BufferedReader tokenReader = new BufferedReader(new StringReader(token)); | ||||
|  | ||||
|          // The second line contains the "username" | ||||
|          m_username = tokenReader.readLine(); | ||||
|  | ||||
|          // The third line contains the "password" | ||||
|          m_password = tokenReader.readLine(); | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * Returns the username | ||||
|        */ | ||||
|       public String getUsername() | ||||
|       { | ||||
|          return m_username; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * Returns the password | ||||
|        */ | ||||
|       public String getPassword() | ||||
|       { | ||||
|          return m_password; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public PwdAuthenticate() throws Exception | ||||
|    { | ||||
|       // Nothing to do at this time | ||||
|    }      | ||||
|  | ||||
|    /* | ||||
|     * Initialize the mechanism. | ||||
|     */ | ||||
|    public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception | ||||
|    { | ||||
|       m_svcConfig = svcConfig; | ||||
|       m_mechConfig = mechConfig; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * invoke() implementation. | ||||
|     */ | ||||
|    public String invoke(AuthReqMsg authReqMsg) throws Exception | ||||
|    { | ||||
|       String identId = null; | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          System.err.println("PwdAuthenticate.invoke()"); | ||||
|  | ||||
|          // Now parse the PW Token | ||||
|          PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken()); | ||||
|  | ||||
|          // Open a directory context and use it to identify the users | ||||
|          // associated with the specified surname. | ||||
|          Hashtable env = new Hashtable(); | ||||
|          env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); | ||||
|          env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); | ||||
|          env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm()); | ||||
|  | ||||
|          DirContext ctx = new InitialDirContext(env); | ||||
|  | ||||
|          // Now search for a user with a matching surname. | ||||
|          // | ||||
|          // Set up a search control so that the search is scoped to the sub-tree | ||||
|          SearchControls controls = new SearchControls(); | ||||
|          controls.setSearchScope(SearchControls.SUBTREE_SCOPE); | ||||
|  | ||||
|          // Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit | ||||
|          String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext); | ||||
|          if (searchContext == null) | ||||
|          { | ||||
|             // A start search context was not configured, start from the root. | ||||
|             searchContext = ""; | ||||
|          } | ||||
|  | ||||
|          // Perform the search | ||||
|          NamingEnumeration answer = ctx.search(searchContext, | ||||
|                                                "(cn={0})", | ||||
|                                                new String[] {pwToken.getUsername()}, | ||||
|                                                controls); | ||||
|  | ||||
|          // Enumerate through the users returned checking the password | ||||
|          while (answer.hasMore()) | ||||
|          { | ||||
|             SearchResult sr = (SearchResult)answer.next(); | ||||
|  | ||||
|             // Open a directory context for the user as a way of verifying its password | ||||
|             try | ||||
|             { | ||||
|                Hashtable env2 = new Hashtable(); | ||||
|                env2.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); | ||||
|                env2.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); | ||||
|                env2.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());               | ||||
|                env2.put(Context.SECURITY_AUTHENTICATION, "simple"); | ||||
|                env2.put(Context.SECURITY_PRINCIPAL, sr.getNameInNamespace()); | ||||
|                env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword()); | ||||
|  | ||||
|                if ((new InitialDirContext(env2)) != null) | ||||
|                { | ||||
|                   // The password must be valid, set the identity Id. | ||||
|                   if (searchContext.equals("")) | ||||
|                   { | ||||
|                      identId = sr.getName(); | ||||
|                   } | ||||
|                   else | ||||
|                   { | ||||
|                      identId = sr.getName() + "," + searchContext; | ||||
|                   } | ||||
|                   break; | ||||
|                } | ||||
|             } | ||||
|             catch (NamingException e) | ||||
|             { | ||||
|                System.err.println("PwdAuthenticate.invoke()- NamingException: " + e.getExplanation());  | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|       catch (NamingException e) | ||||
|       { | ||||
|          // Log the error | ||||
|          System.err.println("PwdAuthenticate.invoke()- NamingException on Proxy User: " + e.getExplanation()); | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          System.err.println("PwdAuthenticate.invoke()- Exception: " + e.toString());  | ||||
|       } | ||||
|  | ||||
|       // Return the authentication result | ||||
|       return identId; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Return the mechanism id. | ||||
|     */ | ||||
|    public String getId() | ||||
|    { | ||||
|       return "PwdAuthenticate"; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
| <settings> | ||||
| 	<description>This is the authentication mechanism for the PwdAuthenticate scheme. The PwdAuthenticate scheme authenticates entities using username/password tokens.</description> | ||||
| 	<ClassName>com.novell.casa.authtoksvc.PwdAuthenticate</ClassName> | ||||
| 	<RelativeClassPath>WEB-INF/classes</RelativeClassPath> | ||||
| </settings> | ||||
| @@ -0,0 +1,285 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.PrintWriter; | ||||
|  | ||||
| import javax.servlet.*; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.http.*; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Rpc Servlet Class. | ||||
|  *  | ||||
|  * This class processes Rpcs to the Authentication Token Service. | ||||
|  *  | ||||
|  */ | ||||
| public class Rpc extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet | ||||
| { | ||||
|    private static final long serialVersionUID = -8264027868130334613L; | ||||
|  | ||||
|    private     String               m_appFolderPath = null; | ||||
|    private     String               m_configFolderPath = null; | ||||
|  | ||||
|    protected   ReconfigureThread    m_reconfigureThread = null; | ||||
|    protected   int                  m_reconfigureInterval; // seconds | ||||
|  | ||||
|    private Map                      m_methodsMap; | ||||
|  | ||||
|    /* | ||||
|     * Reconfigure Thread Class. | ||||
|     * | ||||
|     * This class implements a runnable thread that reconfigures an Rpc Servlet instance. | ||||
|     * | ||||
|     */ | ||||
|    private class ReconfigureThread implements Runnable | ||||
|    { | ||||
|       private Rpc       m_rpc; | ||||
|       private Thread    m_thread; | ||||
|  | ||||
|       /* | ||||
|        * Constructor. | ||||
|        */ | ||||
|       public ReconfigureThread (Rpc rpc) | ||||
|       { | ||||
|          m_rpc = rpc; | ||||
|          m_thread = new Thread(this); | ||||
|          m_thread.start(); | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * run() implementation. | ||||
|        */ | ||||
|       public void run () | ||||
|       { | ||||
|          System.err.println("ReconfigureThread.run()- Running"); | ||||
|  | ||||
|          while (true) | ||||
|          { | ||||
|             // Sleep an ammount equal the reconfigure interval for the Rpc | ||||
|             try | ||||
|             { | ||||
|                m_thread.sleep(m_rpc.m_reconfigureInterval * 1000); | ||||
|             } | ||||
|             catch (InterruptedException e) { /* nothing to do */ } | ||||
|  | ||||
|             // Re-configure the Rpc servlet. | ||||
|             try | ||||
|             { | ||||
|                m_rpc.configureServlet(); | ||||
|  | ||||
|                // Check if it is no longer necessary to re-configure the servlet | ||||
|                if (m_rpc.m_reconfigureInterval == 0) | ||||
|                { | ||||
|                   System.err.println("ReconfigureTask.run()- Configuration changed to no longer perform timed re-configuration"); | ||||
|                   break; | ||||
|                } | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                System.err.println("ReconfigureTask.run()- Exception caught during re-configure process, " + e.toString()); | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * stop() implementation. | ||||
|        */ | ||||
|       public void stop () | ||||
|       { | ||||
|          m_thread.stop(); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor. | ||||
|     */ | ||||
|    public Rpc () | ||||
|    { | ||||
|       super(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * configureServlet() implementation. | ||||
|     */ | ||||
|    protected void configureServlet () throws Exception | ||||
|    { | ||||
|       // Read service configuration | ||||
|       SvcConfig svcConfig = new SvcConfig(m_appFolderPath, m_configFolderPath); | ||||
|  | ||||
|       // Get the reconfigure interval | ||||
|       try | ||||
|       { | ||||
|          m_reconfigureInterval = Integer.parseInt(svcConfig.getSetting(SvcConfig.ReconfigureInterval)); | ||||
|       } | ||||
|       catch (NumberFormatException e) | ||||
|       { | ||||
|          System.err.println("Rpc.configureServlet()- Invalid reconfigure interval value format");  | ||||
|          m_reconfigureInterval = Integer.parseInt(SvcConfig.DefaultReconfigureIntervalValue); | ||||
|       } | ||||
|  | ||||
|       // Read enabled services configuration | ||||
|       EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(m_configFolderPath); | ||||
|  | ||||
|       // Create a map to keep track of the Rpc methods | ||||
|       Map methodsMap = new HashMap(); | ||||
|  | ||||
|       // Instantiate the Rpc Methods | ||||
|       RpcMethod getAuthPolicy = new GetAuthPolicy(); | ||||
|       getAuthPolicy.init(svcConfig, enabledSvcsConfig); | ||||
|       methodsMap.put(getAuthPolicy.getId(), getAuthPolicy); | ||||
|  | ||||
|       RpcMethod authenticate = new Authenticate(); | ||||
|       authenticate.init(svcConfig, enabledSvcsConfig); | ||||
|       methodsMap.put(authenticate.getId(), authenticate); | ||||
|  | ||||
|       RpcMethod getAuthToken = new GetAuthToken(); | ||||
|       getAuthToken.init(svcConfig, enabledSvcsConfig); | ||||
|       methodsMap.put(getAuthToken.getId(), getAuthToken); | ||||
|  | ||||
|       // Set the map as the methods map used by the servlet | ||||
|       m_methodsMap = methodsMap; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * init() implementation. | ||||
|     */ | ||||
|    public void init (ServletConfig config) throws ServletException | ||||
|    { | ||||
|       super.init(config); | ||||
|  | ||||
|       System.err.println("Rpc.init()"); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Get the path to our configuration folder | ||||
|          // | ||||
|          // First check if it has been specified via a system property | ||||
|          ServletContext context = config.getServletContext(); | ||||
|          m_appFolderPath = context.getRealPath(File.separator); | ||||
|          m_configFolderPath = System.getProperty("com.novell.casa.authtoksvc.config"); | ||||
|          if (m_configFolderPath == null) | ||||
|          { | ||||
|             // The path to the svc config folder was not specified via a system | ||||
|             // property, assume that it's location is off the WEB-INF folder for | ||||
|             // our web application. | ||||
|             m_configFolderPath = m_appFolderPath + "WEB-INF/conf"; | ||||
|          } | ||||
|  | ||||
|          // Configure ourselves | ||||
|          configureServlet(); | ||||
|  | ||||
|          // Check if we must start a thread to periodically reconfigure ourselves | ||||
|          if (m_reconfigureInterval != 0) | ||||
|          { | ||||
|             m_reconfigureThread = new ReconfigureThread(this); | ||||
|          } | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          System.err.println("Rpc.init()- Exception caught: " + e.toString());  | ||||
|          throw new ServletException("Exception caught while instantiating Rpc methods"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * destroy() implementation. | ||||
|     */ | ||||
|    public void destroy () | ||||
|    { | ||||
|       super.destroy(); | ||||
|  | ||||
|       System.err.println("Rpc.destroy()");  | ||||
|  | ||||
|       // Stop our re-configure thread | ||||
|       if (m_reconfigureThread != null) | ||||
|       { | ||||
|          m_reconfigureThread.stop(); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * doGet() implementation. | ||||
|     */ | ||||
|    protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException | ||||
|    { | ||||
|       doPost(request, response); | ||||
|    }      | ||||
|  | ||||
|    /* | ||||
|     * doPost() implementation. | ||||
|     */ | ||||
|    protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException | ||||
|    { | ||||
|       // Get ready to send back a reply | ||||
|       response.setContentType("text/html"); | ||||
|       PrintWriter out = response.getWriter(); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Obtain the input stream and execute the requested method | ||||
|          InputStream inStream = request.getInputStream(); | ||||
|  | ||||
|          String requestedMethod = request.getParameter("method"); | ||||
|          if (requestedMethod != null) | ||||
|          { | ||||
|             // Get the necessary method | ||||
|             RpcMethod method = (RpcMethod) m_methodsMap.get(requestedMethod); | ||||
|             if (method != null) | ||||
|             { | ||||
|                // Invoke the method to process the Rpc | ||||
|                method.invoke(inStream, out); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                // Unsupported method | ||||
|                System.err.println("Rpc.doPost()- Unsupported method");  | ||||
|                response.sendError(response.SC_BAD_REQUEST); | ||||
|             } | ||||
|          } | ||||
|          else | ||||
|          { | ||||
|             // Missing method parameter | ||||
|             System.err.println("Rpc.doPost()- Missing method parameter");  | ||||
|             response.sendError(response.SC_BAD_REQUEST); | ||||
|          } | ||||
|       } | ||||
|       catch (Exception e) | ||||
|       { | ||||
|          // tbd | ||||
|          System.err.println("Rpc.doPost()- Exception caught: " + e.toString());  | ||||
|          response.sendError(response.SC_INTERNAL_SERVER_ERROR); | ||||
|       } | ||||
|  | ||||
|       // Done sending out the reply | ||||
|       out.close(); | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,53 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.io.PrintWriter; | ||||
| import java.util.*; | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * RpcMethod Interface. | ||||
|  *  | ||||
|  * This is the interface implemented by Rpc Methods. | ||||
|  */ | ||||
| public interface RpcMethod | ||||
| { | ||||
|    /* | ||||
|     * Initialize the Rpc method. | ||||
|     */ | ||||
|    void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception; | ||||
|  | ||||
|    /* | ||||
|     * Process Rpc. | ||||
|     */ | ||||
|    void invoke(InputStream inStream, PrintWriter out) throws IOException; | ||||
|  | ||||
|    /* | ||||
|     * Return the method id. | ||||
|     */ | ||||
|    String getId(); | ||||
| } | ||||
| @@ -0,0 +1,416 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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.ByteArrayInputStream; | ||||
|  | ||||
| import org.xml.sax.InputSource; | ||||
| import org.xml.sax.SAXException; | ||||
| import org.xml.sax.XMLReader; | ||||
| import org.xml.sax.helpers.XMLReaderFactory; | ||||
|  | ||||
|  | ||||
| /* | ||||
| * SessionToken class. | ||||
| *  | ||||
| * This class constructs session tokens that Casa clients can present to | ||||
| * the Casa server to prove that an entity has been authenticated to | ||||
| * a particular realm. The format of the session token is as follows: | ||||
| *  | ||||
| * <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
| * <session_token> | ||||
| * <signature>signature value</signature> | ||||
| * <lifetime>lifetime value</lifetime> | ||||
| * <realm>realm value</realm> | ||||
| * <ident_id>identity id value</ident_id> | ||||
| * </session_token> | ||||
| * | ||||
| */ | ||||
| public class SessionToken | ||||
| { | ||||
|  | ||||
|    private String m_id; | ||||
|    private String m_realm; | ||||
|    private String m_lifetime; | ||||
|    private String m_signature; | ||||
|    private String m_token; | ||||
|  | ||||
|    /* | ||||
|     * 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_ROOT_ELEMENT_END = 1; | ||||
|       private final static int AWAITING_SIGNATURE_ELEMENT_START = 2; | ||||
|       private final static int AWAITING_SIGNATURE_ELEMENT_END = 3; | ||||
|       private final static int AWAITING_SIGNATURE_DATA = 4; | ||||
|       private final static int AWAITING_LIFETIME_ELEMENT_START = 5; | ||||
|       private final static int AWAITING_LIFETIME_ELEMENT_END = 6; | ||||
|       private final static int AWAITING_LIFETIME_DATA = 7; | ||||
|       private final static int AWAITING_REALM_ELEMENT_START = 8; | ||||
|       private final static int AWAITING_REALM_ELEMENT_END = 9; | ||||
|       private final static int AWAITING_REALM_DATA = 10; | ||||
|       private final static int AWAITING_IDENT_ID_ELEMENT_START = 11; | ||||
|       private final static int AWAITING_IDENT_ID_ELEMENT_END = 12; | ||||
|       private final static int AWAITING_IDENT_ID_DATA = 13; | ||||
|       private final static int DONE_PARSING = 14; | ||||
|  | ||||
|       private SessionToken m_SessionToken; | ||||
|       private int       m_state; | ||||
|  | ||||
|       /* | ||||
|        * Constructor | ||||
|        */ | ||||
|       public SAXHandler (SessionToken SessionToken) | ||||
|       { | ||||
|          super(); | ||||
|  | ||||
|          // Initialize our members | ||||
|          m_SessionToken = SessionToken; | ||||
|          m_state = AWAITING_ROOT_ELEMENT_START; | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endDocument() implementation. | ||||
|        */ | ||||
|       public void endDocument () throws SAXException | ||||
|       { | ||||
|          // Verify that we obtained all of the required elements | ||||
|          if (m_state != DONE_PARSING) | ||||
|          { | ||||
|             System.err.println("SessionToken SAXHandler.endDocument()- Missing element");  | ||||
|             throw new SAXException("Missing element"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * 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 (ProtoDefs.sessionTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SIGNATURE_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SIGNATURE_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.signatureElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_SIGNATURE_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.lifetimeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_LIFETIME_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|  | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_REALM_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.realmElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_REALM_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_ID_ELEMENT_START: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.identIdElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_IDENT_ID_DATA; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.startElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("SessionToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * endElement() immplementation. | ||||
|        */ | ||||
|       public void endElement (String uri, String name, String qName) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_ROOT_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.sessionTokenElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = DONE_PARSING; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_SIGNATURE_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.signatureElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_LIFETIME_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.lifetimeElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_REALM_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_REALM_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.realmElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_IDENT_ID_ELEMENT_START; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_ID_ELEMENT_END: | ||||
|                // Verify that we are processing the expected tag | ||||
|                if (ProtoDefs.identIdElementName.equals(qName)) | ||||
|                { | ||||
|                   // Advance to the next state | ||||
|                   m_state = AWAITING_ROOT_ELEMENT_END; | ||||
|                } | ||||
|                else | ||||
|                { | ||||
|                   System.err.println("SessionToken SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("SessionToken SAXHandler.startElement()- State error");  | ||||
|                throw new SAXException("State error"); | ||||
|          } | ||||
|       } | ||||
|  | ||||
|       /* | ||||
|        * character() implementation. | ||||
|        */ | ||||
|       public void characters (char ch[], int start, int length) throws SAXException | ||||
|       { | ||||
|          // Proceed based on our state | ||||
|          switch (m_state) | ||||
|          { | ||||
|              | ||||
|             case AWAITING_SIGNATURE_DATA: | ||||
|                // Consume the data | ||||
|                m_SessionToken.m_signature = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_SIGNATURE_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_LIFETIME_DATA: | ||||
|                // Consume the data | ||||
|                m_SessionToken.m_lifetime = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_LIFETIME_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_REALM_DATA: | ||||
|                // Consume the data | ||||
|                m_SessionToken.m_realm = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_REALM_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             case AWAITING_IDENT_ID_DATA: | ||||
|                // Consume the data | ||||
|                m_SessionToken.m_id = new String(ch, start, length); | ||||
|  | ||||
|                // Advance to the next state | ||||
|                m_state = AWAITING_IDENT_ID_ELEMENT_END; | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                // Do nothing | ||||
|                break; | ||||
|          } | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor | ||||
|     */ | ||||
|    public SessionToken(String id, String realm, String lifetime) throws Exception | ||||
|    { | ||||
|       // Save copies of the input parameters | ||||
|       m_id = id; | ||||
|       m_realm = realm; | ||||
|       m_lifetime = lifetime; | ||||
|  | ||||
|       // Generate a signature | ||||
|       // tbd - Over id, realm, and lifetime data. | ||||
|       m_signature = "tbd"; | ||||
|  | ||||
|       // Get a StringBuffer to help us with the construction of the token | ||||
|       StringBuffer sb = new StringBuffer(); | ||||
|  | ||||
|       // Start building the message | ||||
|       sb.append(ProtoDefs.xmlDeclaration + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.sessionTokenElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.signatureElementName + ">" + m_signature + "</" + ProtoDefs.signatureElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.lifetimeElementName + ">" + m_lifetime + "</" + ProtoDefs.lifetimeElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.realmElementName + ">" + m_realm + "</" + ProtoDefs.realmElementName + ">" + "\r\n"); | ||||
|       sb.append("<" + ProtoDefs.identIdElementName + ">" + m_id + "</" + ProtoDefs.identIdElementName + ">" + "\r\n"); | ||||
|       sb.append("</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n"); | ||||
|  | ||||
|       // Save the token | ||||
|       m_token = sb.toString(); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Constructor given a session token string. The constructor | ||||
|     * validates the token as part of its processing. | ||||
|     */ | ||||
|    public SessionToken(String token) throws Exception | ||||
|    { | ||||
|       // Decode the token string | ||||
|       m_token = Base64Coder.decode(token); | ||||
|  | ||||
|       // Now parse the token into its elements | ||||
|       try | ||||
|       { | ||||
|          // Parse the SessionToken | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(this); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|  | ||||
|          ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes()); | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|  | ||||
|          // Verify the signature | ||||
|          // tbd | ||||
|  | ||||
|          // Verify that the token has not expired | ||||
|          // tbd | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|          System.err.println("SessionToken()- Parse exception: " + e.toString());  | ||||
|          throw new Exception("Protocol error"); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Returns a string containing the session token. | ||||
|     */ | ||||
|    public String toString() | ||||
|    { | ||||
|       return Base64Coder.encode(m_token); | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the Identity Id  | ||||
|     */ | ||||
|    public String getIdentId() throws Exception | ||||
|    { | ||||
|       return m_id; | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * Method to get the Identity Repository Reference (Realm).  | ||||
|     */ | ||||
|    public String getRealm() throws Exception | ||||
|    { | ||||
|       return m_realm; | ||||
|    } | ||||
| } | ||||
| @@ -0,0 +1,299 @@ | ||||
| /*********************************************************************** | ||||
|  *  | ||||
|  *  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; | ||||
|  | ||||
| /** | ||||
|  * SvcConfig Class. | ||||
|  *  | ||||
|  * This class obtains and maintains the service configuration. | ||||
|  *  | ||||
|  */ | ||||
| public class SvcConfig | ||||
| { | ||||
|    // Well known service configuration settings | ||||
|    // | ||||
|    // The LifetimeShorter value is the value by which token lifetime | ||||
|    // values are shorten when specified to clients to make sure that | ||||
|    // the clients detect token expirations before issuing the tokens | ||||
|    // to a service for authentication purposes. | ||||
|    public final static String SessionTokenLifetime = "SessionTokenLifetime"; | ||||
|    public final static String LifetimeShorter = "LifetimeShorter"; | ||||
|    public final static String IdentityAbstractionConfigFile = "IAConfigFile"; | ||||
|    public final static String StartSearchContext = "startSearchContext"; | ||||
|    public final static String ConfigFolderPath = "ConfigFolderPath"; | ||||
|    public final static String AppRootPath = "AppRootPath"; | ||||
|    public final static String ReconfigureInterval = "ReconfigureInterval"; | ||||
|  | ||||
|    // Default configuration values | ||||
|    public final static  String DefaultSessionTokenLifetimeValue = "43200";    // Seconds | ||||
|    public final static  String DefaultLifetimeShorterValue = "5";             // Seconds | ||||
|    public final static  String DefaultReconfigureIntervalValue = "60";        // Seconds | ||||
|  | ||||
|    private static final String m_svcSettingsFileName = "svc.settings"; | ||||
|    private Map m_svcSettingsMap; | ||||
|  | ||||
|    /* | ||||
|     * Class for handling Authentication Request 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("SvcConfig 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("SvcConfig 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("SvcConfig 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_DATA: | ||||
|             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("SvcConfig SAXHandler.endElement()- Un-expected element");  | ||||
|                   throw new SAXException("Un-expected element"); | ||||
|                } | ||||
|                break; | ||||
|  | ||||
|             default: | ||||
|                System.err.println("SvcConfig 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. | ||||
|     */ | ||||
|    public SvcConfig(String appRootPath, String svcConfigPath) throws Exception | ||||
|    { | ||||
|       System.err.println("SvcConfig()-"); | ||||
|  | ||||
|       System.err.println("SvcConfig()- SvcConfigPath = " + svcConfigPath); | ||||
|  | ||||
|       // Create a map to keep track of the service settings | ||||
|       m_svcSettingsMap = new HashMap(); | ||||
|  | ||||
|       try | ||||
|       { | ||||
|          // Get an input stream to services settings file | ||||
|          File settingsFile = new File(svcConfigPath, m_svcSettingsFileName); | ||||
|          FileInputStream inStream = new FileInputStream(settingsFile); | ||||
|        | ||||
|          // Parse the file | ||||
|          XMLReader xr = XMLReaderFactory.createXMLReader(); | ||||
|          SAXHandler handler = new SAXHandler(m_svcSettingsMap); | ||||
|          xr.setContentHandler(handler); | ||||
|          xr.setErrorHandler(handler); | ||||
|           | ||||
|          InputSource source = new InputSource(inStream); | ||||
|          xr.parse(source); | ||||
|          inStream.close(); | ||||
|  | ||||
|          // Add the application and config folder path settings to our map | ||||
|          m_svcSettingsMap.put(AppRootPath, appRootPath); | ||||
|          m_svcSettingsMap.put(ConfigFolderPath, svcConfigPath); | ||||
|       } | ||||
|       catch (SAXException e) | ||||
|       { | ||||
|         System.err.println("SvcConfig()- Parse exception: " + e.toString());  | ||||
|         throw new Exception("SvcConfig()- svc.settings format error"); | ||||
|       } | ||||
|       catch (SecurityException e) | ||||
|       { | ||||
|          System.err.println("SvcConfig()- SecurityException caught while accessing " + svcConfigPath +  File.separator + m_svcSettingsFileName + " Exception=" + e.toString()); | ||||
|       } | ||||
|       catch (FileNotFoundException e) | ||||
|       { | ||||
|          System.err.println("SvcConfig()- File " + svcConfigPath +  File.separator + m_svcSettingsFileName + " not found"); | ||||
|       } | ||||
|       catch (IOException e) | ||||
|       { | ||||
|          System.err.println("SvcConfig()- IOException caught while trying to read " + svcConfigPath +  File.separator + m_svcSettingsFileName + " Exception=" + e.toString()); | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    /* | ||||
|     * 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_svcSettingsMap.get(settingName); | ||||
|       if (value == null) | ||||
|       { | ||||
|          System.err.println("SvcConfig.getSetting()- Did not find setting " + settingName); | ||||
|  | ||||
|          // The setting is not in our map, check if it is one to | ||||
|          // which we have defaults. | ||||
|          if (settingName.equals(SessionTokenLifetime) == true) | ||||
|          { | ||||
|             value = DefaultSessionTokenLifetimeValue; | ||||
|             System.err.println("SvcConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_svcSettingsMap.put(SessionTokenLifetime, DefaultSessionTokenLifetimeValue); | ||||
|          } | ||||
|          else if (settingName.equals(LifetimeShorter) == true) | ||||
|          { | ||||
|             value = DefaultLifetimeShorterValue; | ||||
|             System.err.println("SvcConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_svcSettingsMap.put(LifetimeShorter, DefaultLifetimeShorterValue); | ||||
|          } | ||||
|          else if (settingName.equals(ReconfigureInterval) == true) | ||||
|          { | ||||
|             value = DefaultReconfigureIntervalValue; | ||||
|             System.err.println("SvcConfig.getSetting()- Assigning default value " + value); | ||||
|  | ||||
|             // Add the key to the map so that it can be found quicker next time | ||||
|             m_svcSettingsMap.put(ReconfigureInterval, DefaultReconfigureIntervalValue); | ||||
|          } | ||||
|          else if (settingName.equals(IdentityAbstractionConfigFile) == true) | ||||
|          { | ||||
|             System.err.println("SvcConfig.getSetting()- Mandatory setting " + IdentityAbstractionConfigFile + " not set"); | ||||
|             throw new Exception("Missing mandatory configuration setting"); | ||||
|          } | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          System.err.println("SvcConfig.getSetting()- Found setting " + settingName); | ||||
|          System.err.println("SvcConfig.getSetting()- Setting value = " + value); | ||||
|  | ||||
|          // Do some sanity checking | ||||
|          // tbd - Make sure that the token lifetime values are greater than the LifetimeShorter | ||||
|       } | ||||
|  | ||||
|       return value; | ||||
|    } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user