major source structure and module name changes

This commit is contained in:
soochoi
2006-06-07 16:34:19 +00:00
parent 5c75241b4b
commit 1fa6f07e83
651 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CasaAuthServer</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jst.j2ee.ejb.annotations.xdoclet.xdocletbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
</natures>
<linkedResources>
<link>
<name>identity-abstraction.jar</name>
<type>1</type>
<location>/home/jluciani/dev-local/bandit/trunk/IdentityAbstraction/build/identity-abstraction.jar</location>
</link>
</linkedResources>
</projectDescription>

View File

@@ -0,0 +1,146 @@
#######################################################################
#
# 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.
#
#
#######################################################################
SUBDIRS =
DIST_SUBDIRS = src src/com src/com/novell src/com/novell/casa src/com/novell/casa/authtoksvc
EXTRA_DIST = $(JAVAFILES)
CASAROOT = ../../..
CASALIBDIR = $(CASAROOT)/$(LIB)
IDENT_ABSTRACTION_DIR = /home/jluciani/dev-local/bandit/trunk/IdentityAbstraction/build
IDENT_ABSTRACTION_DEPENDANCIES_DIR = /home/jluciani/dev-local/bandit/trunk/commons/bin
JAVAROOT = .
JAVAC= javac
WEBAPP_NAME = CasaAuthTokenSvc
WEBAPP_EXT = war
MODULE_NAME = CasaAuthToken
MODULE_EXT = jar
JAVAFILES = src/com/novell/casa/authtoksvc/ProtoDefs.java \
src/com/novell/casa/authtoksvc/AuthMechConfig.java \
src/com/novell/casa/authtoksvc/SvcConfig.java \
src/com/novell/casa/authtoksvc/IdenTokenConfig.java \
src/com/novell/casa/authtoksvc/AuthTokenConfig.java \
src/com/novell/casa/authtoksvc/EnabledSvcsConfig.java \
src/com/novell/casa/authtoksvc/AuthMechanism.java \
src/com/novell/casa/authtoksvc/Authenticate.java \
src/com/novell/casa/authtoksvc/RpcMethod.java \
src/com/novell/casa/authtoksvc/Rpc.java \
src/com/novell/casa/authtoksvc/GetAuthPolicy.java \
src/com/novell/casa/authtoksvc/Base64Coder.java \
src/com/novell/casa/authtoksvc/AuthReqMsg.java \
src/com/novell/casa/authtoksvc/AuthRespMsg.java \
src/com/novell/casa/authtoksvc/IdentityToken.java \
src/com/novell/casa/authtoksvc/CasaIdentityToken.java \
src/com/novell/casa/authtoksvc/AuthToken.java \
src/com/novell/casa/authtoksvc/GetAuthPolicyReqMsg.java \
src/com/novell/casa/authtoksvc/GetAuthPolicyRespMsg.java \
src/com/novell/casa/authtoksvc/GetAuthToken.java \
src/com/novell/casa/authtoksvc/GetAuthTokReqMsg.java \
src/com/novell/casa/authtoksvc/GetAuthTokRespMsg.java \
src/com/novell/casa/authtoksvc/Krb5Authenticate.java \
src/com/novell/casa/authtoksvc/PwdAuthenticate.java \
src/com/novell/casa/authtoksvc/SessionToken.java
BUILDDIR = build
WEBAPP = $(WEBAPP_NAME).$(WEBAPP_EXT)
#AUTHTOKEN_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthToken.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthToken$SAXHandler.cless \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenConfig.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenConfig$SAXHandler.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenConfig.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenConfig$SAXHandler.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdentityToken.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/CasaIdentityToken.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/CasaIdentityToken$SAXHandler.class \
# -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/Base64Coder.class
AUTHTOKEN_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com
CLASSES = $(addprefix $(BUILDDIR)/, $(JAVAFILES:%.java=%.class))
LIBS = /usr/share/java/servletapi5.jar
CLASSPATH = $(IDENT_ABSTRACTION_DIR):$(LIBS)
CUR_DIR := $(shell pwd)
all: $(BUILDDIR)/$(WEBAPP) $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT)
$(BUILDDIR)/%.class: %.java
@echo [======== Compiling $@ ========]
$(JAVAC) -sourcepath src -classpath $(CLASSPATH) -d $(BUILDDIR)/webapp/WEB-INF/classes $<
$(BUILDDIR)/$(WEBAPP): $(BUILDDIR) $(CLASSES)
@echo [======== Creating Webapp $@ ========]
cp web.xml $(BUILDDIR)/webapp/WEB-INF/web.xml
cp svc.settings $(BUILDDIR)/webapp/WEB-INF/conf/svc.settings
cp authtoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/authtoken.settings
cp identoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/identoken.settings
cp src/com/novell/casa/authtoksvc/Krb5_mechanism.settings $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate/mechanism.settings
cp src/com/novell/casa/authtoksvc/Pwd_mechanism.settings $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate/mechanism.settings
cp $(IDENT_ABSTRACTION_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
cp $(IDENT_ABSTRACTION_DEPENDANCIES_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
jar cvf $(BUILDDIR)/$(WEBAPP) -C $(BUILDDIR)/webapp .
cp $(BUILDDIR)/$(WEBAPP) $(CASALIBDIR)/java/
$(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT): $(BUILDDIR) $(CLASSES)
@echo [======== Jarring $@ ========]
jar cvf $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(AUTHTOKEN_FILES)
cp $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(CASALIBDIR)/java/
$(BUILDDIR):
[ -d $(BUILDDIR) ] || mkdir -p $(BUILDDIR)
[ -d $(BUILDDIR)/webapp ] || mkdir -p $(BUILDDIR)/webapp
[ -d $(BUILDDIR)/webapp/WEB-INF ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF
[ -d $(BUILDDIR)/webapp/WEB-INF/classes ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/classes
[ -d $(BUILDDIR)/webapp/WEB-INF/lib ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/lib
[ -d $(BUILDDIR)/webapp/WEB-INF/conf ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/enabled_services ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/enabled_services
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/auth_mechanisms ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/auth_mechanisms
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/Krb5Authenticate
[ -d $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate ] || mkdir -p $(BUILDDIR)/webapp/WEB-INF/conf/installed_auth_mechanisms/PwdAuthenticate
[ -d $(CASALIBDIR) ] || mkdir -p $(CASALIBDIR)
[ -d $(CASALIBDIR)/java ] || mkdir -p $(CASALIBDIR)/java
install-exec-local:
uninstall-local:
#installcheck-local: install
clean-local:
if [ -d $(BUILDDIR) ]; then rm -rf $(BUILDDIR); fi
if [ -f $(CASALIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT) ]; then rm -f $(CASALIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT); fi
if [ -f $(CASALIBDIR)/java/$(WEBAPP) ]; then rm -f $(CASALIBDIR)/java/$(WEBAPP); fi
distclean-local:
maintainer-clean-local:
rm -f Makefile.in
rm -f Makefile

View File

@@ -0,0 +1,292 @@
/***********************************************************************
*
* README for AuthTokenSvc
*
***********************************************************************/
INTRODUCTION
AuthTokenSvc is the CASA Authentication Token Service (ATS). It is implemented
as a Java servlet and supporting classes that execute in the Tomcat environment.
The ATS is responsible for providing clients with the necessary authentication
policy information, for authenticating client entities, and for providing
clients with Authentication Tokens that they can then use for authenticating
to CASA Authentication enabled services.
The ATS utilizes mechanism plug-ins for authenticating client entities as well
Identity Token Providers for the generation of Identity Tokens.
ENVIRONMENT SETTINGS
The following options must be set in the JAVA_OPTS setting before starting Tomcat
to allow the Kerberos authentication mechanism to work properly:
-Djavax.security.auth.useSubjectCredsOnly=false
-Djava.security.auth.login.config={replace with the path for JAAS configuration
file for the service}
After setting the above values in the JAVA_OPTS variable you must export it for
Tomcat to be able to make use of it.
The following entry should be included in the JAAS configuration file specified
in the java.security.auth.login.config option above to enable the Krb5 authentication
mechanism to work correctly:
other {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true
ticketCache="/var/cache/tomcat5/base/temp/ticket.cache"
useKeyTab=true
principal="host/server.company.com"
doNotPrompt=true
storeKey=true
keyTab="/etc/krb5.keytab";
}
Please adjust the ticketCache and principal setting to match your installation.
CONFIGURATION
AuthTokenSvc configuration consists of multiple entities. Most of the AuthTokenSvc
configuration is contained within the "conf" folder under the WEB-INF folder of the
application. For an example configuration setup for the AuthTokenSvc see the
sampleConf folder.
The location of the AuthTokenSvc configuration folder can be over-ridden by specifying
a different path via the com.novell.casa.authtoksvc.config system property.
CONFIGURING THE BASE SERVICE
The ATS base settings are configured in the svc.settings file under the conf folder.
Thhe following is an example svc.settings file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<SessionTokenLifetime>43200</SessionTokenLifetime>
<LifetimeShorter>10</LifetimeShorter>
<IAConfigFile>/home/jluciani/jakarta-tomcat-5.0.28/webapps/CasaAuthTokenSvc/WEB-INF/conf/iaRealms.xml</IAConfigFile>
<ReconfigureInterval>60</ReconfigureInterval>
<startSearchContext>o=novell</startSearchContext>
</settings>
Note the following about the sample svc.settings file:
- The settngs that you can specify in the svc.settings file are: SessionLifetime,
LifetimeShorter, IAConfigFile, and startSearchContext.
- The SessionTokenLifetime setting specifies the number of seconds for which a
session token is good for after being issued. The default value for this setting
is 43200 seconds. Note that a larger value reduces overhead.
- The LifetimeShorter setting specifies the number of seconds that should be substracted
from the SessionTokenLifetime when calculating the number of seconds that clients are
told that the session tokens are good for. The default value for this setting is 5
seconds.
- The IAConfigFile settings specifies the path to the identity abstraction
configuration file. The identity abstraction configuration file configures
the different realms (contexts) that the ATS can utilize to authenticate
entities and resolve identities. In the future the configuration of this
settng will be optional.
- The ReconfigureInterval setting specifies how often the ATS should refresh its
configuration. The default value for this setting is 60 seconds. A ReconfigureInterval
value of 0 means that the ATS will not refresh its configuration once it has been
initialized, thus requiring that the servlet be re-initialized to make configuration
changes take effect.
- The startSearchContext setting specifies the begin location for initiating
context searches. The absence of this setting will result in searches ocurring
from the root of the tree. This setting or an equivalent setting will be moved
to the identity abstraction configuration file where it belongs. Once this is done,
the setting will no longer be recognized within the svc.settings file.
CONFIGURING SERVICES TO CONSUME CASA AUTHENTICATION TOKENS
Services are configured to consume CASA authentication tokens by creating folders
under the conf/enabled_services folders. Since CASA distinguishes between services
of the same name existing in different hosts, the first folder that must be created
is one for the host where the service resides. The host folder name must match the
DNS name of the host where the service resides. Services are configured by creating
a folder under the appropriate host folder with a name matching the service name.
Note when configuring services that the service name and the host names must match
the service and host names specified by the client applications when requesting
tokens to authenticate to them.
The services folder must contain an auth.policy file, an authtoken.settings file,
and an identoken.settings file. In the absence of any one of those files, the ATS
will default to utilizing the files present under its conf folder.
The auth.policy file specifies the authentication realms (or contexts) to which
entities can authenticate to gain access to the service. The auth.policy file also
specifies the authentication mechanisms that can be utilized to authenticate to the
realms.
The following is an example auth.policy file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<auth_policy>
<auth_source>
<realm>CorpTree</realm>
<mechanism>Krb5Authenticate</mechanism>
<mechanism_info>host@tokenserver.company.novell.com</mechanism_info>
</auth_source>
<auth_source>
<realm>CorpTree</realm>
<mechanism>PwdAuthenticate</mechanism>
<mechanism_info></mechanism_info>
</auth_source>
</auth_policy>
Note the following about the sample auth.policy file:
- An authentication realm is specified in the auth.policy file by creating an
auth_policy entry for it. An auth_policy entry must contain the realm name along
with the entries for the authentication mechanisms.
- When a realm supports more than one authentication mechanism, you must create
an auth_source entry for each supported mechanism.
- The realm names correspond to the realmIDs configured in the Identity Abstraction
configuration file for the desired context entry.
- The authentication mechanism entries are: mechanism and mechanism_info. The mechanism
entry specifies the name of the authentication mechanism. The mechanism_info specifies
some mechanism specific information. Both authentication mechanism entries must be
specified for an auth_source entry.
- The name of the Krb5 Authentication mechanism is "Krb5Authenticate". This mechanism
requires that you specify the service's kerberos principal name under the mechanism_info
key.
- The name of the username/password authentication mechanism is "PwdAuthenticate" and
it does not require any information to be included under the mechanism_info key.
The authtoken.settings file contains settings that should be applied to authentication
tokens issued to authenticate to the service.
The following is an example authtoken.settings file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<TokenLifetime>3600</TokenLifetime>
<LifetimeShorter>10</LifetimeShorter>
<IdentityTokenType>CasaIdentityToken</IdentityTokenType>
</settings>
Note the following about the sample authtoken.settings file:
- The settings that you can specify in the authtoken.settings file are: TokenLifetime,
LifetimeShorter, and IdentityTokenType. If one of this tokens is not specified then
its default value is utilized.
- The TokenLifetime setting specifies the number of seconds for which a token is good
for after being issued. The default value for this setting is 3600 seconds. Note that
a larger value reduces overhead, but it also gives more time for an intruder to
utilize the token if it becomes compromized.
- The LifetimeShorter setting specifies the number of seconds that should be substracted
from the TokenLifetime when calculating the number of seconds that clients are told
that the tokens are good for. The default value for this setting is 5 seconds.
- The IdentityTokenType specifies the type of identity tokens that must be embedded in
the authentication tokens with identity information. The default value for this
setting is CasaIdentityToken.
The identoken.settings file contains settings that should be applied to identity tokens
embedded in authentication tokens.
The following is an example identoken.settings file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<Attributes>sn,groupMembership,guid</Attributes>
<EncryptAttributes>false</EncryptAttributes>
<Certificate>Base64 encoded certificate</Certificate>
</settings>
Note the following about the sample identoken.settings file:
- The settings that you can specify in the identoken.settings file are: Attributes.
EncryptAttributes, and Certificate.
- The Attributes setting specifies the identity attributes that must be included
as part of the identity token, The attributes are specified in the form of a coma
delimited list. The default velue for this setting is "sn".
- The EncryptAtributes setting specifies whether or not the identity information
contained in the identity token should be emcrypted with the services's Public
Certificate. The default value for this setting is "false". Please note that
to enable identity attribute encryption you must not allow the ATS to default to
the file present in its conf folder (Attribute encryption is not yet supported
by the Casa identity token provider).
- The Certificate setting specifies the certificate that must be utilized to encrypt
identity attribute data. The certificate contains the public key of the targeted
service. The certificate data is Base64 encoded.
- The identoken.settings file can also contain additional identity token provider
specific settings.
CONFIGURING AUTHENTICATION MECHANISMS
Authentication mechanisms available to the AuthTokenSvc are configured by creating
a sub-folder named after the authentication mechanism type under the
conf/auth_mechanisms folder. The authentication mechanism folders must contain a
settings file named mechanism.settings. The mechanism.settings file must contain the
name of the class implementing the mechanism along with path information which
can be utilized by the ATS to load the class. The mechanism.settings file can
also contain mechanism specific settings.
The following setting is mandatory:
ClassName - This is the name of the class implementing the authentication mechanism.
One of the following settings must be included:
RelativeClassPath - This is a relative path from the web application's root folder
to the folder containing the class implementing the mechanism.
ClassPath - This is an absolute path to the folder containing the path to the class
implementing the mechanism.
The following is an example mechanism.settings file for the Krb5Authentication
mechanism:
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName>
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
<ServicePrincipalName>host@authtokenserver.company.com</ServicePrincipalName>
</settings>
The base AuthTokenSvc package contains two authentication mechanisms, these are
Krb5Authenticate and PwdAuthenticate. The configuration under sampleConf is set up
to allow an AuthTokenSvc to leverage both mechanisms.
The Krb5Authenticate mechanism requires that the following setting also be included
in its mechanism.settings file:
ServicePrincipalName - This is the name of the Kerberos Service Principal that the
Authentication Token Service runs as when authenticating other entities.
CONFIGURING ADDITIONAL IDENTITY TOKEN PROVIDERS
- TBD -
SECURITY CONSIDERATIONS
- TBD -

View File

@@ -0,0 +1,21 @@
/***********************************************************************
*
* TODO for AuthTokenSvc
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for AuthTokenSvc.
OUTSTANDING ITEMS
- Switch to a Web Services model where the Client/Server protocol uses SOAP.
- Switch to use WS-Security, WS-Policy, and WS-Conversation for Authentication Tokens and Session Tokens.
- Add code to verify that client/server communications occur over HTTPS.
- Add logging.
- Create plug-in API for Identity Token Providers.
- Integrate into CASA build environment.
- Review Code.
- Change printfs used for debugging into a suitable mechanism.

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<TokenLifetime>3600</TokenLifetime>
</settings>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<EncryptAttributes>false</EncryptAttributes>
<Attributes>sn</Attributes>
</settings>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<auth_policy>
<auth_source>
<realm>CorpTree</realm>
<mechanism>Krb5Authenticate</mechanism>
<mechanism_info>host@authtokenserver.company.com</mechanism_info>
</auth_source>
<auth_source>
<realm>CorpTree</realm>
<mechanism>PwdAuthenticate</mechanism>
<mechanism_info></mechanism_info>
</auth_source>
</auth_policy>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<ClassName>com.novell.casa.authtoksvc.Krb5Authenticate</ClassName>
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
<ServicePrincipalName>host@tokenserver.company.novell.com</ServicePrincipalName>
</settings>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<ClassName>com.novell.casa.authtoksvc.PwdAuthenticate</ClassName>
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
</settings>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<TokenLifetime>3600</TokenLifetime>
</settings>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<auth_policy>
<auth_source>
<realm>CorpTree</realm>
<mechanism>Krb5Authenticate</mechanism>
<mechanism_info>host@tokenserver.company.novell.com</mechanism_info>
</auth_source>
<auth_source>
<realm>CorpTree</realm>
<mechanism>PwdAuthenticate</mechanism>
<mechanism_info></mechanism_info>
</auth_source>
</auth_policy>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<TokenLifetime>3600</TokenLifetime>
</settings>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<EncryptAttributes>false</EncryptAttributes>
<Attributes>sn,groupMembership</Attributes>
</settings>

View File

@@ -0,0 +1,25 @@
<bci:realms
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:bci="http://www.bandit-project.org/commonidentity"
xmlns:xacml="urn:oasis:names:tc:xacml:2.0:policy:schema:os"
xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:policy:schema:os:access_control-xacml-2.0-policy-schema-os.xsd">
<bci:realm
desc="My Corporate Directory"
connectorType="org.bandit.ia.connectors.LDAPConnectorInitialCtxFactory"
id="jctree">
<bci:connection xsi:type="bci:LDAPConnector">
<bci:address>ldap://dirserver.companyname.com:389</bci:address>
<bci:security>
<bci:authentication>simple</bci:authentication>
<bci:principal>cn=admin,o=companyname</bci:principal>
<bci:credentials>password</bci:credentials>
</bci:security>
</bci:connection>
</bci:realm>
<bci:realm desc="Realm Join Definition" id="E263CCC1-8F9D-4551-B786-068AA84E8564">
<bci:connection xsi:type="bci:JoinConnector">
<bci:realmID>CorpTree</bci:realmID>
</bci:connection>
</bci:realm>
</bci:realms>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<EncryptAttributes>false</EncryptAttributes>
<Attributes>sn</Attributes>
</settings>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<IAConfigFile>/home/jluciani/jakarta-tomcat-5.0.28/webapps/CasaAuthTokenSvc/WEB-INF/conf/iaRealms.xml</IAConfigFile>
<SessionTokenLifetime>43200</SessionTokenLifetime>
</settings>

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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";
}
}

View File

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

View File

@@ -0,0 +1,775 @@
/***********************************************************************
*
* 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("java.naming.ldap.attributes.binary", "guid");
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");
}
}
}

View File

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

View File

@@ -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";
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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";
}
}

View File

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

View File

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

View File

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

View File

@@ -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>

View File

@@ -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";
}

View File

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

View File

@@ -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>

View File

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

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,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;
}
}

View File

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

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<settings>
<IAConfigFile>Replace with path to the Identity Abstraction Realms Configuration File.</IAConfigFile>
<SessionTokenLifetime>43200</SessionTokenLifetime>
</settings>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>
CasaAuthTokenSvc</display-name>
<servlet>
<description>
The CasaAuthTokenSvc provides authentication tokens.
</description>
<display-name>
Rpc</display-name>
<servlet-name>Rpc</servlet-name>
<servlet-class>
com.novell.casa.authtoksvc.Rpc</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Rpc</servlet-name>
<url-pattern>/Rpc</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>