Most of the changes are to add configuration capabilities.

This commit is contained in:
Juan Carlos Luciani 2006-05-16 15:15:23 +00:00
parent 1a1d6c03a0
commit 484bf05fe4
16 changed files with 1897 additions and 414 deletions

View File

@ -0,0 +1,49 @@
/***********************************************************************
*
* 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.
*/
public interface AuthMechanism
{
/*
* Initialize the authentication mechanism.
*/
void init(SvcConfig svcConfig) 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();
}

View File

@ -42,6 +42,7 @@ import org.xml.sax.helpers.XMLReaderFactory;
* <?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>
*
@ -51,6 +52,7 @@ 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.
@ -62,13 +64,16 @@ public class AuthReqMsg
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_AUTH_MECH_TOKEN_ELEMENT_START = 5;
private final static int AWAITING_AUTH_MECH_TOKEN_ELEMENT_END = 6;
private final static int AWAITING_AUTH_MECH_TOKEN_DATA = 7;
private final static int DONE_PARSING = 8;
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;
private AuthReqMsg m_authReqMsg;
private int m_state;
/*
* Constructor
@ -103,7 +108,6 @@ public class AuthReqMsg
// 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))
@ -132,6 +136,20 @@ public class AuthReqMsg
}
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))
@ -160,7 +178,6 @@ public class AuthReqMsg
// 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))
@ -178,6 +195,20 @@ public class AuthReqMsg
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;
@ -217,7 +248,6 @@ public class AuthReqMsg
// Proceed based on our state
switch (m_state)
{
case AWAITING_REALM_DATA:
// Consume the data
m_authReqMsg.m_realm = new String(ch, start, length);
@ -226,6 +256,14 @@ public class AuthReqMsg
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);
@ -279,4 +317,12 @@ public class AuthReqMsg
{
return m_authMechToken;
}
/*
* Method to get the authentication mechanism id.
*/
public String getMechanismId() throws Exception
{
return m_authMechanism;
}
}

View File

@ -52,6 +52,7 @@ 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;
@ -328,58 +329,67 @@ public class AuthToken
/*
* Constructor.
*/
public AuthToken (
String identityId,
public AuthToken(String identityId,
String realm,
String targetService,
String targetHost) throws Exception
String targetHost,
SvcConfig svcConfig,
EnabledSvcsConfig enabledSvcsConfig) throws Exception
{
try
// Get access to the authentication token configuration for this service
AuthTokenConfig authTokenConfig = enabledSvcsConfig.getAuthTokenConfig(targetHost, targetService);
if (authTokenConfig != null)
{
// Verify that we have support for the specified service.
// tbd
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);
// 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();
identityToken.initialize(identityId,
realm,
targetService,
targetHost);
m_identityToken = new StringBuffer();
m_identityToken.append(identityToken.getEncodedToken());
m_identityTokenType = identityToken.getProviderType();
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);
m_lifetime = "56"; // tbd
// Generate a signature
// tbd - Over identToken, identToken type, and lifetime data.
m_signature = "tbd";
// 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();
// 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");
// 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();
// Save the token
m_token = sb.toString();
}
catch (Exception e)
{
// tbd
System.err.println("AuthToken()- Exception: " + e.toString());
}
}
catch (Exception e)
else
{
// tbd
System.err.println("AuthToken()- Exception: " + e.toString());
throw new Exception("Error: Missing authentication token config for " + targetService);
}
}
@ -434,7 +444,7 @@ public class AuthToken
*/
public String getLifetime()
{
// tbd
// tbd - Convert to tokenLifetime and lifetimeShorter to ints, substractand then convert result to string
return "60";
}

View File

@ -0,0 +1,297 @@
/***********************************************************************
*
* 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 = "360"; // 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_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;
}
}

View File

@ -85,6 +85,7 @@ public class CasaIdentityToken implements IdentityToken
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;
@ -441,7 +442,10 @@ public class CasaIdentityToken implements IdentityToken
// At this point we now have the target service and host names,
// check if our configuration says that the attributes have been
// encrypted.
m_encryptedAttrs = EncryptAttributes(m_service, m_host);
// 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;
@ -476,26 +480,27 @@ public class CasaIdentityToken implements IdentityToken
/*
* Constructor.
*/
public CasaIdentityToken ()
public CasaIdentityToken(IdenTokenConfig idenTokenConfig)
{
// Initialize our members
m_token = null;
m_attributes = new javax.naming.directory.BasicAttributes();
m_idenTokenConfig = idenTokenConfig;
}
/*
* Initialize with parameters.
*/
public void initialize (
String identityId,
public void initialize(String identityId,
String sourceName,
String targetService,
String targetHost) throws Exception
String targetHost,
SvcConfig svcConfig) throws Exception
{
// Save input parameters
m_identityId = identityId;
m_sourceName = sourceName;
m_sourceUrl = "ldap://jcserver.provo.novell.com:389"; // tbd - Obtain from config or Higgins
m_sourceUrl = "ldap://myldaphost.novell.com:389"; // tbd - Obtain from Identity Abstraction layer
m_service = targetService;
m_host = targetHost;
@ -506,8 +511,8 @@ public class CasaIdentityToken implements IdentityToken
// 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, "/home/jluciani/workspace/IdentityAbstraction/realms.xml");
// env.put(IAContext.IA_REALM_SELECTOR, "");
env.put(IAContext.IA_REALM_CONFIG_LOCATION, svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
env.put(IAContext.IA_REALM_SELECTOR, sourceName);
DirContext ctx = new InitialDirContext(env);
@ -524,28 +529,47 @@ public class CasaIdentityToken implements IdentityToken
sb.append("<" + attributesElementName + ">" + "\r\n");
// Get the necessary attributes of the specified services in the identity token
Set attributesNeeded = getAttributesNeededByService(m_service, m_host);
boolean encryptAttributes = EncryptAttributes(m_service, m_host);
Attributes attrs = ctx.getAttributes(identityId);
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();
// Append the attribute if it is one that we want.
// tbd - This needs to be customized on a per service basis.
if (attributesNeeded.contains(attr.getID()))
NamingEnumeration enumeration = attr.getAll();
while (enumeration.hasMore())
{
NamingEnumeration enumeration = attr.getAll();
while (enumeration.hasMore())
String attrValue = null;
Object o = enumeration.next();
if (o == null)
{
System.err.println("CasaIdentityToken.initialize()- null");
}
if (o instanceof java.lang.String)
{
System.err.println("CasaIdentityToken.initialize()- Type string");
attrValue = (String) o;
}
else if (o instanceof java.lang.Byte)
{
System.err.println("CasaIdentityToken.initialize()- Type byte[]");
attrValue = ((byte[]) o).toString();
}
// Proceed if we were able to get the attribute value in String form
if (attrValue != null)
{
String attrValue = (String) enumeration.next();
m_attributes.put(attr.getID(), attrValue);
System.err.println("CasaIdentityToken.initialize()- Including attribute " + attr.getID() + " of value " + attrValue);
// Encrypt the attribute if necessary
if (encryptAttributes == true)
{
// tbd - Encrypt the attributes using the services public key, let the mechanism
// be configurable.
// be configurable. The services certificate should be Base64 encoded as a setting
// of the identoken.settings file.
sb.append("<" + attr.getID() + ">" + attrValue + "</" + attr.getID() + ">" + "\r\n");
}
else
@ -553,6 +577,10 @@ public class CasaIdentityToken implements IdentityToken
sb.append("<" + attr.getID() + ">" + attrValue + "</" + attr.getID() + ">" + "\r\n");
}
}
else
{
System.err.println("CasaIdentityToken.initialize()- Unrecognized object type for attribute " + attr.getID());
}
}
}
sb.append("</" + attributesElementName + ">" + "\r\n");
@ -602,33 +630,6 @@ public class CasaIdentityToken implements IdentityToken
}
}
/*
* Return the attributes needed by the service.
*/
private Set getAttributesNeededByService(String serviceName, String hostName)
{
// tbd - Read the following from configuration
HashSet attributesNeeded = new HashSet();
attributesNeeded.add("sn");
attributesNeeded.add("groupMembership");
attributesNeeded.add("securityEquals");
attributesNeeded.add("uid");
attributesNeeded.add("uidNumber");
attributesNeeded.add("gidNumber");
return attributesNeeded;
}
/*
* Return indication of whether or not the identity attributes must be encrypted.
*/
private boolean EncryptAttributes(String serviceName, String hostName)
{
// tbd - Based return value based on the configuration for the service.
// Default is "false".
return false;
}
/*
* Returns encoded token string.
*

View File

@ -0,0 +1,392 @@
/***********************************************************************
*
* 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 + "/" + m_authPolicyFileName + " Exception=" + e.toString());
}
catch (FileNotFoundException e)
{
System.err.println("EnabledSvcsConfig()- File " + configFolder + "/" + m_authPolicyFileName + " not found");
}
catch (IOException e)
{
System.err.println("EnabledSvcsConfig()- IOException reading " + configFolder + "/" + m_authPolicyFileName + " Exception=" + e.toString());
}
// Try to obtain the default authentication token settings
try
{
defaultAuthTokenConfig = new AuthTokenConfig(configFolder + "/" + 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 + "/" + 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 + "/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 + "/" + 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 + "/" + m_authPolicyFileName + " Exception=" + e.toString());
}
try
{
authTokenConfig = new AuthTokenConfig(serviceFolder + "/" + m_authTokenSettingsFileName);
}
catch (Exception e)
{
System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + "/" + m_authTokenSettingsFileName + " Exception=" + e.toString());
}
try
{
idenTokenConfig = new IdenTokenConfig(serviceFolder + "/" + m_idenTokenSettingsFileName);
}
catch (Exception e)
{
System.err.println("EnabledSvcsConfig()- Exception accessing " + serviceFolder + "/" + 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());
}
// Now go through the services configured as enabled. Note that a service is configured as enabled by
// placing a folder in our conf directory with a name that matches the service's name.
}
catch (SecurityException e)
{
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;
}
}
}

View File

@ -26,69 +26,82 @@ package com.novell.casa.authtoksvc;
import java.io.*;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* GetAuthPolicy Servlet Class.
* GetAuthPolicy Class.
*
* This class processes authentication policy requests for a particular
* This class processes get authentication policy requests for a particular
* service.
*
*/
public class GetAuthPolicy extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
public class GetAuthPolicy implements RpcMethod
{
private static final long serialVersionUID = -8264027868130334613L;
private SvcConfig m_svcConfig;
private EnabledSvcsConfig m_enabledSvcsConfig;
/*
* Constructor.
*/
public GetAuthPolicy()
public GetAuthPolicy() throws Exception
{
super();
}
// Nothing to do at this time
}
/*
* doGet() implementation.
* Initialize the Rpc method.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
{
doPost(request, response);
}
m_svcConfig = svcConfig;
m_enabledSvcsConfig = enabledSvcsConfig;
}
/*
* doPost() implementation.
* Process Rpc.
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public void invoke(InputStream inStream, PrintWriter out) throws IOException
{
// Get ready to send back a reply
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try
{
System.err.println("GetAuthPolicy.invoke()");
// Read and parse the GetAuthPolicyReqMsg sent from the client
InputStream inStream = request.getInputStream();
GetAuthPolicyReqMsg getAuthPolicyReqMsg = new GetAuthPolicyReqMsg(inStream);
// Get the auth policy for the service
byte[] authPolicy = getAuthPolicyFileData(getAuthPolicyReqMsg.getServiceName(),
getAuthPolicyReqMsg.getHostName());
// Write out the response
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpOkStatusMsg,
ProtoDefs.httpOkStatusCode,
new String(Base64Coder.encode(authPolicy)));
out.println(getAuthPolicyRespMsg.toString());
// 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)
{
// tbd
System.err.println("GetAuthPolicy.doPost()- Exception caught: " + e.toString());
System.err.println("GetAuthPolicy.invoke()- Exception: " + e.toString());
// Write out the response
try
@ -99,38 +112,16 @@ public class GetAuthPolicy extends javax.servlet.http.HttpServlet implements jav
}
catch (Exception e2)
{
System.err.println("GetAuthPolicy.doPost()- Exception trying to construct response msg: " + e2.toString());
System.err.println("GetAuthPolicy.invoke()- Exception trying to construct response msg: " + e2.toString());
}
}
// Done sending out the reply
out.close();
}
/*
* Returns the data associated with the authentication policy file
* associated with the specified service.
* Return the method id.
*/
private byte[] getAuthPolicyFileData(String serviceName, String hostName)
public String getId()
{
// tdb - Read the file associated with the specified service
StringBuffer sb = new StringBuffer();
// Start building the policy data
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "</" + ProtoDefs.realmElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.mechanismElementName + ">" + "Krb5Authenticate" + "</" + ProtoDefs.mechanismElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "host/jcstation.dnsdhcp.provo.novell.com" + "</" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.authSourceElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.authSourceElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.realmElementName + ">" + "jctree" + "</" + ProtoDefs.realmElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.mechanismElementName + ">" + "PwdAuthenticate" + "</" + ProtoDefs.mechanismElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.mechanismInfoElementName + ">" + "" + "</" + ProtoDefs.mechanismInfoElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.authSourceElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
String s = sb.toString();
return s.getBytes();
return "GetAuthPolicy";
}
}

View File

@ -28,93 +28,99 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* GetAuthToken Servlet Class.
* GetAuthToken Class.
*
* This class processes requests for tokens to authenticate an entity
* to a particular service.
*
*/
public class GetAuthToken extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
public class GetAuthToken implements RpcMethod
{
private static final long serialVersionUID = -5792862615065914894L;
private SvcConfig m_svcConfig;
private EnabledSvcsConfig m_enabledSvcsConfig;
/*
* Constructor.
*/
public GetAuthToken()
public GetAuthToken() throws Exception
{
super();
// Nothing to do at this time
}
/*
* doGet() implementation.
* Initialize the Rpc method.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
{
// Just let doPost() handle it.
doPost(request, response);
}
m_svcConfig = svcConfig;
m_enabledSvcsConfig = enabledSvcsConfig;
}
/*
* doPost() implementation.
* Process Rpc.
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public void invoke(InputStream inStream, PrintWriter out) throws IOException
{
// Get ready to send back a reply
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try
{
// Read and parse the GetAuthTokReqMsg sent from the client
InputStream inStream = request.getInputStream();
System.err.println("GetAuthToken.invoke()");
// Parse the GetAuthTokReqMsg sent from the client
GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
// Now create a session token (This validates the session token provided).
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
try
// Verify that the service is enabled
if (m_enabledSvcsConfig.svcEnabled(getAuthTokReqMsg.getHostName(),
getAuthTokReqMsg.getServiceName()))
{
// Create the Authentication Token
AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
sessionToken.getRealm(),
getAuthTokReqMsg.getServiceName(),
getAuthTokReqMsg.getHostName());
// Now create a session token (This validates the session token provided).
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
// Write out the response
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
ProtoDefs.httpOkStatusCode,
authToken.toString(),
authToken.getLifetime());
out.println(getAuthTokRespMsg.toString());
}
catch (Exception e)
{
// tbd, use a custom exception and then set the status based
// on the type of exeption cached.
// Write out the response
try
{
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
ProtoDefs.httpUnauthorizedStatusCode);
// 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 e2)
catch (Exception e)
{
System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
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)
{
// tbd
System.err.println("GetAuthToken.doPost()- Exception caught: " + e.toString());
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
// Write out the response
try
@ -125,11 +131,16 @@ public class GetAuthToken extends javax.servlet.http.HttpServlet implements java
}
catch (Exception e2)
{
System.err.println("GetAuthToken.doPost()- Exception trying to construct response msg: " + e2.toString());
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
}
}
}
// Done sending out the reply
out.close();
/*
* Return the method id.
*/
public String getId()
{
return "GetAuthToken";
}
}

View File

@ -0,0 +1,293 @@
/***********************************************************************
*
* 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_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;
}
}

View File

@ -25,26 +25,25 @@
package com.novell.casa.authtoksvc;
/*
* IdentityTokenProvider Interface.
* IdentityToken Interface.
*
* This is the interface to Identity Token Providers.
* This is the interface implemented by Identity Token Providers.
*/
public interface IdentityToken
{
/*
* Initialize the token with parameters.
*/
void initialize (
String identityId,
void initialize(String identityId,
String sourceName,
String targetService,
String targetHost) throws Exception;
String targetHost,
SvcConfig svcConfig) throws Exception;
/*
* Initialize the token object with encoded token string.
*/
void initialize (String encodedToken) throws Exception;
void initialize(String encodedToken) throws Exception;
/*
* Returns encoded token string.

View File

@ -38,9 +38,6 @@ import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchResult;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
@ -52,30 +49,23 @@ import org.ietf.jgss.Oid;
import org.bandit.ia.IAContext;
/**
* Krb5Authenticate Servlet Class.
* Krb5Authenticate Class.
*
* This class processes authentication requests utilizing a kerberos-V token.
* This class implementes an authentication mechanism for
* the processing of authentication requests utilizing a
* Kerberos5 token.
*
*/
public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
public class Krb5Authenticate implements AuthMechanism
{
private static final long serialVersionUID = 7247746330553668339L;
/*
* tbd - This needs to be somewhere else so that the same parameter
* can be accessed by other authentication mechanisms.
*
* Configurable operating parameters
*
*/
public String sessionTokenLifetime = "360";
private SvcConfig m_svcConfig;
/*
* GSS Long Lived variables
*/
protected GSSManager m_manager;
protected Oid m_krb5;
protected GSSName m_svcName;
protected GSSManager m_manager;
protected Oid m_krb5;
protected GSSName m_svcName;
protected GSSCredential m_credential;
/*
@ -132,7 +122,15 @@ public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements
*/
public Krb5Authenticate() throws Exception
{
super();
// Nothing to do at this time
}
/*
* Initialize the mechanism.
*/
public void init(SvcConfig svcConfig) throws Exception
{
m_svcConfig = svcConfig;
try
{
@ -162,40 +160,28 @@ public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements
System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage());
throw new Exception("Failed to instantiate needed GSS objects");
}
}
}
/*
* doGet() implementation.
* invoke() implementation.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public String invoke(AuthReqMsg authReqMsg) throws Exception
{
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();
String identId = null;
try
{
// Read and parse the AuthReqMsg sent from the client
InputStream inStream = request.getInputStream();
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
System.err.println("Krb5Authenticate.invoke()");
// Now parse the PW Token
// 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, "/home/jluciani/workspace/IdentityAbstraction/realms.xml");
// env.put(IAContext.IA_REALM_SELECTOR, "");
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);
@ -203,76 +189,35 @@ public class Krb5Authenticate extends javax.servlet.http.HttpServlet implements
Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
matchAttrs.put(new BasicAttribute("krbPrincipalName", krb5Token.getPrincipalName()));
NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
NamingEnumeration answer = ctx.search(m_svcConfig.getSetting(SvcConfig.StartSearchContext), matchAttrs);
// Proceed based on the result of the search
String identId = null;
if (answer.hasMore())
{
// The search succeeded, set the identity id.
SearchResult sr = (SearchResult)answer.next();
identId = sr.getName() + ",o=novell";
identId = sr.getName() + "," + m_svcConfig.getSetting(SvcConfig.StartSearchContext);
}
// Create response based on the identity resolution results
if (identId != null)
{
// An identity was resolved, get a SessionToken for it.
SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
// Write out the response
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
ProtoDefs.httpOkStatusCode,
sessionToken.toString(),
sessionTokenLifetime);
out.println(authRespMsg.toString());
}
else
{
// Write out the response
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
ProtoDefs.httpUnauthorizedStatusCode);
out.println(authRespMsg.toString());
}
}
catch (NamingException e)
{
// tbd
// Log the error
System.err.println("Krb5Authenticate.doPost()- Exception caught: " + e.getExplanation());
// Write out the response
try
{
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
ProtoDefs.httpServerErrorStatusCode);
out.println(authRespMsg.toString());
}
catch (Exception e2)
{
System.err.println("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
}
System.err.println("Krb5Authenticate.invoke()- NamingException: " + e.getExplanation());
}
catch (Exception e)
{
// tbd
System.err.println("Krb5Authenticate.doPost()- 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("Krb5Authenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
}
System.err.println("Krb5Authenticate.invoke()- Exception: " + e.toString());
}
// Done sending out the reply
out.close();
}
// Return the authentication result
return identId;
}
/*
* Return the mechanism id.
*/
public String getId()
{
return "Krb5Authenticate";
}
}

View File

@ -79,6 +79,8 @@ public class ProtoDefs
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";
}

View File

@ -31,10 +31,6 @@ import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.BasicAttribute;
@ -49,25 +45,16 @@ import org.bandit.ia.IAContext;
/**
* PwdAuthenticate Servlet Class.
* PwdAuthenticate Class.
*
* This class processes authentication requests utilizing username and
* password materials.
* This class implementes an authentication mechanism for
* the processing of authentication requests utilizing a
* username/password token.
*
*/
public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet
public class PwdAuthenticate implements AuthMechanism
{
private static final long serialVersionUID = 3710685782114934264L;
/*
* tbd - This needs to be somewhere else so that the same parameter
* can be accessed by other authentication mechanisms.
*
* Configurable operating parameters
*
*/
public String sessionTokenLifetime = "360";
private SvcConfig m_svcConfig;
/*
* Password Token Class.
@ -116,34 +103,29 @@ public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements j
/*
* Constructor
*/
public PwdAuthenticate()
public PwdAuthenticate() throws Exception
{
super();
// Nothing to do at this time
}
/*
* doGet() implementation.
* Initialize the mechanism.
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public void init(SvcConfig svcConfig) throws Exception
{
// Just let doPost() handle it.
doPost(request, response);
}
m_svcConfig = svcConfig;
}
/*
* doPost() implementation.
* invoke() implementation.
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
public String invoke(AuthReqMsg authReqMsg) throws Exception
{
// Get ready to send back a reply
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String identId = null;
try
{
// Read and parse the AuthReqMsg sent from the client
InputStream inStream = request.getInputStream();
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
System.err.println("PwdAuthenticate.invoke()");
// Now parse the PW Token
PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken());
@ -152,8 +134,8 @@ public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements j
// 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, "/home/jluciani/workspace/IdentityAbstraction/realms.xml");
// env.put(IAContext.IA_REALM_SELECTOR, "");
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);
@ -161,102 +143,53 @@ public class PwdAuthenticate extends javax.servlet.http.HttpServlet implements j
Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
matchAttrs.put(new BasicAttribute("cn", pwToken.getUsername()));
NamingEnumeration answer = ctx.search("o=novell", matchAttrs);
NamingEnumeration answer = ctx.search(m_svcConfig.getSetting(SvcConfig.StartSearchContext), matchAttrs);
// Enumerate through the users returned checking the password
String identId = null;
while (answer.hasMore())
{
SearchResult sr = (SearchResult)answer.next();
System.err.println(sr.getName());
// 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, "/home/jluciani/workspace/IdentityAbstraction/realms.xml");
// env2.put(IAContext.IA_REALM_SELECTOR, "");
// env2.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// env2.put(Context.PROVIDER_URL, "ldap://jcserver.provo.novell.com:389");
// env2.put(Context.SECURITY_AUTHENTICATION, "simple");
// env2.put(Context.SECURITY_PRINCIPAL, sr.getName() + ",o=novell");
// env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword());
env2.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
env2.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
if ((new InitialDirContext(env2)) != null)
{
// The password must be valid, set the identity Id.
identId = sr.getName() + ",o=novell";
identId = sr.getName() + "," + m_svcConfig.getSetting(SvcConfig.StartSearchContext);
break;
}
}
catch (NamingException e)
{
System.err.println("PwdAuthenticate.doPost()- Naming Exception: " + e.getExplanation());
System.err.println("PwdAuthenticate.invoke()- NamingException: " + e.getExplanation());
}
}
// Create response based on the identity resolution results
if (identId != null)
{
// An identity was resolved, get a SessionToken for it.
SessionToken sessionToken = new SessionToken(identId, authReqMsg.getRealm(), sessionTokenLifetime);
// Write out the response
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
ProtoDefs.httpOkStatusCode,
sessionToken.toString(),
sessionTokenLifetime);
out.println(authRespMsg.toString());
}
else
{
// Write out the response
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
ProtoDefs.httpUnauthorizedStatusCode);
out.println(authRespMsg.toString());
}
}
catch (NamingException e)
{
// tbd
// Log the error
System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + e.getExplanation());
// Write out the response
try
{
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
ProtoDefs.httpServerErrorStatusCode);
out.println(authRespMsg.toString());
}
catch (Exception e2)
{
System.err.println("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
}
System.err.println("PwdAuthenticate.invoke()- NamingException on Proxy User: " + e.getExplanation());
}
catch (Exception e)
{
// tbd
System.err.println("PwdAuthenticate.doPost()- Naming Exception on Proxy User: " + 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("PwdAuthenticate.doPost()- Exception trying to construct response msg: " + e2.toString());
}
System.err.println("PwdAuthenticate.invoke()- Exception: " + e.toString());
}
// Done sending out the reply
out.close();
// Return the authentication result
return identId;
}
/*
* Return the mechanism id.
*/
public String getId()
{
return "PwdAuthenticate";
}
}

View File

@ -0,0 +1,170 @@
/***********************************************************************
*
* 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 EnabledSvcsConfig m_enabledSvcsConfig;
private Map m_methodsMap;
/*
* Constructor.
*/
public Rpc()
{
super();
}
/*
* init() implementation.
*/
public void init(ServletConfig config) throws ServletException
{
super.init(config);
System.err.println("Rpc.init()");
try
{
ServletContext context = config.getServletContext();
// Read service configuration
SvcConfig svcConfig = new SvcConfig(context.getRealPath("/") + "WEB-INF/conf");
// Read enabled services configuration
EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(context.getRealPath("/") + "WEB-INF/conf");
// Create a map to keep track of the Rpc methods
m_methodsMap = new HashMap();
// Instantiate the Rpc Methods
RpcMethod getAuthPolicy = new GetAuthPolicy();
getAuthPolicy.init(svcConfig, enabledSvcsConfig);
m_methodsMap.put(getAuthPolicy.getId(), getAuthPolicy);
RpcMethod authenticate = new Authenticate();
authenticate.init(svcConfig, enabledSvcsConfig);
m_methodsMap.put(authenticate.getId(), authenticate);
RpcMethod getAuthToken = new GetAuthToken();
getAuthToken.init(svcConfig, enabledSvcsConfig);
m_methodsMap.put(getAuthToken.getId(), getAuthToken);
}
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()");
}
/*
* 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();
}
}

View File

@ -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();
}

View File

@ -0,0 +1,291 @@
/***********************************************************************
*
* 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";
// Default configuration values
private String m_defaultSessionTokenLifetimeValue = "360"; // Seconds
private String m_defaultLifetimeShorterValue = "5"; // 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_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 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 config folder path setting to our map
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 + "/" + m_svcSettingsFileName + " Exception=" + e.toString());
}
catch (FileNotFoundException e)
{
System.err.println("SvcConfig()- File " + svcConfigPath + "/" + m_svcSettingsFileName + " not found");
}
catch (IOException e)
{
System.err.println("SvcConfig()- IOException caught while trying to read " + svcConfigPath + "/" + 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 = m_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, m_defaultSessionTokenLifetimeValue);
}
else if (settingName.equals(LifetimeShorter) == true)
{
value = m_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, m_defaultLifetimeShorterValue);
}
else if (settingName.equals(IdentityAbstractionConfigFile) == true)
{
System.err.println("SvcConfig.getSetting()- Mandatory setting " + IdentityAbstractionConfigFile + " not set");
throw new Exception("Missing mandatory configuration setting");
}
else if (settingName.equals(StartSearchContext) == true)
{
System.err.println("SvcConfig.getSetting()- Mandatory setting " + StartSearchContext + " 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;
}
}