The "java" folder has been renamed "server-java" to reflect that it only
contains server components. In the process, I also flatened its directory structure.
This commit is contained in:
42
CASA-auth-token/server-java/Svc/.project
Normal file
42
CASA-auth-token/server-java/Svc/.project
Normal 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>
|
||||
205
CASA-auth-token/server-java/Svc/Makefile.am
Normal file
205
CASA-auth-token/server-java/Svc/Makefile.am
Normal file
@@ -0,0 +1,205 @@
|
||||
#######################################################################
|
||||
#
|
||||
# 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 = src
|
||||
DIST_SUBDIRS = src external tomcat5 linux manifest templates
|
||||
|
||||
EXTRA_DIST = README \
|
||||
TODO \
|
||||
web.xml
|
||||
|
||||
ROOT = ../
|
||||
|
||||
LIBDIR = $(ROOT)/$(LIB)
|
||||
|
||||
IDENT_ABSTRACTION_DIR = /usr/share/java/identity-abstraction
|
||||
AXIS_JARS_DIR = external
|
||||
|
||||
MANIFEST_DIR = manifest
|
||||
|
||||
JAVAROOT = .
|
||||
JAVAC= javac
|
||||
|
||||
WEBAPP_NAME = CasaAuthTokenSvc
|
||||
WEBAPP_EXT = war
|
||||
MODULE_NAME = CasaAuthToken
|
||||
MODULE_EXT = jar
|
||||
AUTH_TOKEN_SETTINGS_EDITOR_MODULE_NAME = CasaAuthTokenSettingsEditor
|
||||
IDEN_TOKEN_SETTINGS_EDITOR_MODULE_NAME = CasaIdenTokenSettingsEditor
|
||||
SVC_SETTINGS_EDITOR_MODULE_NAME = CasaSvcSettingsEditor
|
||||
AUTH_POLICY_EDITOR_MODULE_NAME = CasaAuthPolicyEditor
|
||||
|
||||
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/WSSecurity.java \
|
||||
src/com/novell/casa/authtoksvc/SessionToken.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/IVerifySetting.java \
|
||||
src/com/novell/casa/authtoksvc/SettingsFileUtil.java \
|
||||
src/com/novell/casa/authtoksvc/AuthPolicyEditor.java \
|
||||
src/com/novell/casa/authtoksvc/AuthTokenSettingsEditor.java \
|
||||
src/com/novell/casa/authtoksvc/IdenTokenSettingsEditor.java \
|
||||
src/com/novell/casa/authtoksvc/SvcSettingsEditor.java
|
||||
|
||||
BUILDDIR = build
|
||||
|
||||
AUTHTOKEN_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com
|
||||
|
||||
AUTH_TOKEN_SETTINGS_EDITOR_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IVerifySetting.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/SettingsFileUtil.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenSettingsEditor.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthTokenConfig.class
|
||||
|
||||
IDEN_TOKEN_SETTINGS_EDITOR_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IVerifySetting.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/SettingsFileUtil.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenSettingsEditor.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IdenTokenConfig.class
|
||||
|
||||
SVC_SETTINGS_EDITOR_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/IVerifySetting.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/SettingsFileUtil.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/SvcSettingsEditor.class \
|
||||
-C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/SvcConfig.class
|
||||
|
||||
AUTH_POLICY_EDITOR_FILES = -C $(BUILDDIR)/webapp/WEB-INF/classes com/novell/casa/authtoksvc/AuthPolicyEditor.class
|
||||
|
||||
WEBAPP = $(WEBAPP_NAME).$(WEBAPP_EXT)
|
||||
|
||||
AUTH_TOKEN_SETTINGS_EDITOR = $(AUTH_TOKEN_SETTINGS_EDITOR_MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
IDEN_TOKEN_SETTINGS_EDITOR = $(IDEN_TOKEN_SETTINGS_EDITOR_MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
SVC_SETTINGS_EDITOR = $(SVC_SETTINGS_EDITOR_MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
AUTH_POLICY_EDITOR = $(AUTH_POLICY_EDITOR_MODULE_NAME).$(MODULE_EXT)
|
||||
|
||||
CLASSES = $(addprefix $(BUILDDIR)/, $(JAVAFILES:%.java=%.class))
|
||||
|
||||
#AXIS_LIBS = $(AXIS_JARS_DIR)/axis.jar:$(AXIS_JARS_DIR)/axis-ant.jar:$(AXIS_JARS_DIR)/commons-discovery-0.2.jar:$(AXIS_JARS_DIR)/commons-logging-1.0.4.jar:$(AXIS_JARS_DIR)/commons-logging-api.jar:$(AXIS_JARS_DIR)/jaxrpc.jar:$(AXIS_JARS_DIR)/log4j-1.2.8.jar:$(AXIS_JARS_DIR)/saaj.jar:$(AXIS_JARS_DIR)/wsdl4j-1.5.1.jar:$(AXIS_JARS_DIR)/wss4j-1.5.0.jar:$(AXIS_JARS_DIR)/xalan.jar:$(AXIS_JARS_DIR)/xercesImpl.jar:$(AXIS_JARS_DIR)/xml-apis.jar:$(AXIS_JARS_DIR)/xmlsec-1.2.1.jar
|
||||
AXIS_LIBS = $(AXIS_JARS_DIR)/axis.jar:$(AXIS_JARS_DIR)/saaj.jar:$(AXIS_JARS_DIR)/wss4j-1.5.0.jar:$(AXIS_JARS_DIR)/xmlsec-1.2.1.jar
|
||||
#AXIS_LIBS = $(AXIS_JARS_DIR)/wss4j-1.5.0.jar
|
||||
|
||||
LIBS = /usr/share/java/servletapi5.jar
|
||||
CLASSPATH = $(AXIS_LIBS):$(IDENT_ABSTRACTION_DIR)/identity-abstraction.jar:$(LIBS)
|
||||
|
||||
CUR_DIR := $(shell pwd)
|
||||
|
||||
all: $(BUILDDIR)/$(WEBAPP) $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(BUILDDIR)/$(AUTH_TOKEN_SETTINGS_EDITOR) $(BUILDDIR)/$(IDEN_TOKEN_SETTINGS_EDITOR) $(BUILDDIR)/$(SVC_SETTINGS_EDITOR) $(BUILDDIR)/$(AUTH_POLICY_EDITOR)
|
||||
|
||||
$(BUILDDIR)/%.class: %.java
|
||||
@echo [======== Compiling $@ ========]
|
||||
$(JAVAC) -g -sourcepath src -classpath $(CLASSPATH) -d $(BUILDDIR)/webapp/WEB-INF/classes $<
|
||||
|
||||
# The following two lines may need to be added below before we jar-up the war for builds where there is no identity-abstraction install
|
||||
# cp $(IDENT_ABSTRACTION_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
|
||||
# rm $(BUILDDIR)/webapp/WEB-INF/lib/identity-abstraction.jar
|
||||
|
||||
$(BUILDDIR)/$(WEBAPP): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Creating Webapp $@ ========]
|
||||
cp web.xml $(BUILDDIR)/webapp/WEB-INF/web.xml
|
||||
cp templates/svc.settings $(BUILDDIR)/webapp/WEB-INF/conf/svc.settings
|
||||
cp templates/authtoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/authtoken.settings
|
||||
cp templates/identoken.settings $(BUILDDIR)/webapp/WEB-INF/conf/identoken.settings
|
||||
cp linux/crypto.properties $(BUILDDIR)/webapp/WEB-INF/classes/crypto.properties
|
||||
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 $(AXIS_JARS_DIR)/*.jar $(BUILDDIR)/webapp/WEB-INF/lib/
|
||||
ls $(BUILDDIR)/webapp/WEB-INF/lib/
|
||||
jar cvf $(BUILDDIR)/$(WEBAPP) -C $(BUILDDIR)/webapp .
|
||||
cp $(BUILDDIR)/$(WEBAPP) $(LIBDIR)/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) $(LIBDIR)/java/
|
||||
|
||||
$(BUILDDIR)/$(AUTH_TOKEN_SETTINGS_EDITOR): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Jarring $@ ========]
|
||||
jar cvmf $(MANIFEST_DIR)/AuthTokenSettingsEditor.txt $(BUILDDIR)/$(AUTH_TOKEN_SETTINGS_EDITOR) $(AUTH_TOKEN_SETTINGS_EDITOR_FILES)
|
||||
cp $(BUILDDIR)/$(AUTH_TOKEN_SETTINGS_EDITOR) $(LIBDIR)/java/
|
||||
|
||||
$(BUILDDIR)/$(IDEN_TOKEN_SETTINGS_EDITOR): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Jarring $@ ========]
|
||||
jar cvmf $(MANIFEST_DIR)/IdenTokenSettingsEditor.txt $(BUILDDIR)/$(IDEN_TOKEN_SETTINGS_EDITOR) $(IDEN_TOKEN_SETTINGS_EDITOR_FILES)
|
||||
cp $(BUILDDIR)/$(IDEN_TOKEN_SETTINGS_EDITOR) $(LIBDIR)/java/
|
||||
|
||||
$(BUILDDIR)/$(SVC_SETTINGS_EDITOR): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Jarring $@ ========]
|
||||
jar cvmf $(MANIFEST_DIR)/SvcSettingsEditor.txt $(BUILDDIR)/$(SVC_SETTINGS_EDITOR) $(SVC_SETTINGS_EDITOR_FILES)
|
||||
cp $(BUILDDIR)/$(SVC_SETTINGS_EDITOR) $(LIBDIR)/java/
|
||||
|
||||
$(BUILDDIR)/$(AUTH_POLICY_EDITOR): $(BUILDDIR) $(CLASSES)
|
||||
@echo [======== Jarring $@ ========]
|
||||
jar cvmf $(MANIFEST_DIR)/AuthPolicyEditor.txt $(BUILDDIR)/$(AUTH_POLICY_EDITOR) $(AUTH_POLICY_EDITOR_FILES)
|
||||
cp $(BUILDDIR)/$(AUTH_POLICY_EDITOR) $(LIBDIR)/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 $(LIBDIR) ] || mkdir -p $(LIBDIR)
|
||||
[ -d $(LIBDIR)/java ] || mkdir -p $(LIBDIR)/java
|
||||
|
||||
install-exec-local:
|
||||
|
||||
uninstall-local:
|
||||
|
||||
#installcheck-local: install
|
||||
|
||||
clean-local:
|
||||
if [ -d $(BUILDDIR) ]; then rm -rf $(BUILDDIR); fi
|
||||
if [ -f $(LIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT) ]; then rm -f $(LIBDIR)/java/$(MODULE_NAME).$(MODULE_EXT); fi
|
||||
if [ -f $(LIBDIR)/java/$(WEBAPP) ]; then rm -f $(LIBDIR)/java/$(WEBAPP); fi
|
||||
|
||||
distclean-local:
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
rm -f Makefile
|
||||
|
||||
339
CASA-auth-token/server-java/Svc/README
Normal file
339
CASA-auth-token/server-java/Svc/README
Normal file
@@ -0,0 +1,339 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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>
|
||||
*
|
||||
***********************************************************************/
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 environment variable before
|
||||
starting Tomcat to allow the Kerberos authentication mechanism to work properly
|
||||
with Sun's Java:
|
||||
|
||||
-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.
|
||||
|
||||
By default, AuthTokenSvc reads its configuration from the "conf" folder under
|
||||
the WEB-INF folder of the Tomcat Web Application ($CATALINA_HOME/webapps/CasaAuthTokenSvc/WEB-INF/conf).
|
||||
This can be over-ridden by setting the following option in the JAVA_OPTS environment variable:
|
||||
|
||||
-Dcom.novell.casa.authtoksvc.config={replace with the path to the configuration
|
||||
folder}
|
||||
|
||||
CONFIGURATION
|
||||
|
||||
AuthTokenSvc configuration consists of multiple entities. The authTokenSvc configuration
|
||||
is contained within the "conf" folder under the WEB-INF folder of the application
|
||||
($CATALINA_HOME/webapps/CasaAuthTokenSvc/WEB-INF/conf). 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.
|
||||
|
||||
The following is an example svc.settings file:
|
||||
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<SessionTokenLifetime>43200</SessionTokenLifetime>
|
||||
<LifetimeShorter>10</LifetimeShorter>
|
||||
<IAConfigFile>/etc/CASA/authtoken/svc/iaRealms.xml</IAConfigFile>
|
||||
<ReconfigureInterval>60</ReconfigureInterval>
|
||||
<SigningKeyAliasName>signingKey<SigningKeyAliasName>
|
||||
<SigningKeyPassword>secret<SigningKeyPassword>
|
||||
</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 SigningKeyAliasName setting specifies the alias name of the entry in the keystore
|
||||
with the private key utilized to sign tokens. The value of this setting defaults to
|
||||
"signingKey".
|
||||
|
||||
- The SigningKeyPassword setting specifies the password utilized to protect the private key
|
||||
used for signing tokens that is stored in the keystore. The value of this setting defaults to
|
||||
"secret".
|
||||
|
||||
ATSs digitally sign tokens, for this purpose it is necessary that keys be generated and installed
|
||||
in a keystore whose location and properties are configured in the crypto.properties file present in
|
||||
the "classes" folder under the WEB-INF folder of the AuthTokenSvc application
|
||||
($CATALINA_HOME/webapps/CasaAuthTokenSvc/WEB-INF/classes). Please note that you must edit the
|
||||
crypto.properties file with the appropriate information once the AuthTokenSvc is deployed to
|
||||
a Tomcat server to deal with your configuration requirements.
|
||||
|
||||
CONFIGURING SERVICES TO CONSUME CASA AUTHENTICATION TOKENS
|
||||
|
||||
By default, an ATS will issue CASA authentication tokens to be consumed by any service
|
||||
not explicitedly configured as a consumer in the ATS's configuration. This default
|
||||
behavior can be turned off by setting the following system property in the JAVA_OPTS
|
||||
environment variable:
|
||||
|
||||
-Dcom.novell.casa.authtoksvc.enabled_svcs_only=true
|
||||
|
||||
Services explicitedly configured as consumers of CASA authentication tokens by creating
|
||||
folders under the conf/anabled_services folder. 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 unless the service resides in the same
|
||||
host as the ATS in which case the host folder name must be "localhost". 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 folder and the host folder names must match
|
||||
the service and host names specified by the client applications when requesting tokens to
|
||||
authenticate to them with the exception of when the service resides in the same host as the
|
||||
ATS in which case the host folder name is "localhost" and the host name specified by the
|
||||
application is the host's DNS name.
|
||||
|
||||
The services folder can contain an auth.policy file, an authtoken.settings file,
|
||||
and an identoken.settings file. In the absence of any one of those files or if the service
|
||||
is not explicitedly configured, 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@KRB_REALM</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, the need for this entry is dependent on the
|
||||
configuration requirements of the specified mechanism.
|
||||
|
||||
- The name of the Krb5 Authentication mechanism is "Krb5Authenticate". This mechanism
|
||||
defaults the service principal name to host/hostname@KERBEROS_REALM. You can use a
|
||||
different service 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 compromised.
|
||||
|
||||
- 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>
|
||||
</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 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</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 defaults the service principal name to "host/hostname",
|
||||
you can over-ride this parameter by adding the following entry to 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
|
||||
|
||||
<This feature is not currently supported>
|
||||
|
||||
SECURITY CONSIDERATIONS
|
||||
|
||||
- TBD -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
19
CASA-auth-token/server-java/Svc/TODO
Normal file
19
CASA-auth-token/server-java/Svc/TODO
Normal file
@@ -0,0 +1,19 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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.(This is under evaluation).
|
||||
- Add code to verify that client/server communications occur over HTTPS.
|
||||
- Add logging.
|
||||
- Create plug-in API for Identity Token Providers.
|
||||
- Change printfs used for debugging into a suitable mechanism.
|
||||
- Create tool to connect Tomcat instance to Apache Server and disabling port 2645 listener.
|
||||
|
||||
52
CASA-auth-token/server-java/Svc/external/Makefile.am
vendored
Normal file
52
CASA-auth-token/server-java/Svc/external/Makefile.am
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = axis.jar \
|
||||
axis-ant.jar \
|
||||
commons-discovery-0.2.jar \
|
||||
commons-logging-1.0.4.jar \
|
||||
commons-logging-api.jar \
|
||||
jaxrpc.jar \
|
||||
log4j.properties \
|
||||
log4j-1.2.8.jar \
|
||||
README \
|
||||
saaj.jar \
|
||||
wsdl4j-1.5.1.jar \
|
||||
wss4j-1.5.0.jar \
|
||||
xalan.jar \
|
||||
xercesImpl.jar \
|
||||
xml-apis.jar \
|
||||
xmlsec-1.2.1.jar
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
25
CASA-auth-token/server-java/Svc/external/README
vendored
Normal file
25
CASA-auth-token/server-java/Svc/external/README
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
The following describes the source of the files present in this folder.
|
||||
|
||||
axis-1_4 ----> axis-ant.jar
|
||||
axis-1_4 ----> axis.jar
|
||||
axis-1_4 ----> commons-discovery-0.2.jar
|
||||
axis-1_4 ----> commons-logging-1.0.4.jar
|
||||
xml-security-1_2_1 ----> commons-logging-api.jar
|
||||
axis-1_4 ----> jaxrpc.jar
|
||||
axis-1_4 ----> log4j-1.2.8.jar
|
||||
axis-1_4 ----> log4j.properties
|
||||
axis-1_4 ----> saaj.jar
|
||||
axis-1_4 ----> wsdl4j-1.5.1.jar
|
||||
wss4j-1.5 ----> wss4j-1.5.0.jar
|
||||
xml-security-1_2_1 ----> xalan.jar
|
||||
xml-security-1_2_1 ----> xercesImpl.jar
|
||||
xml-security-1_2_1 ----> xml-apis.jar
|
||||
xml-security-1_2_1 ----> xmlsec-1.2.1.jar
|
||||
|
||||
xml-security-1_2_1 - URL: http://xml.apache.org/security/dist/java-library/ - File: xml-security-bin-1_2_1.zip
|
||||
|
||||
axis-1_4 - URL: http://www.apache.org/dyn/closer.cgi/ws/axis/1_4 - File: axis-bin-1_4.tar.gz
|
||||
|
||||
wss4j-1.5 - URL: http://www.apache.org/dyn/dyn/closer.cgi/ws/wss4j/ - File: wss4j-bin-1.5.0.zip
|
||||
|
||||
|
||||
BIN
CASA-auth-token/server-java/Svc/external/axis-ant.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/axis-ant.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/axis.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/axis.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/commons-discovery-0.2.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/commons-discovery-0.2.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/commons-logging-1.0.4.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/commons-logging-1.0.4.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/commons-logging-api.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/commons-logging-api.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/jaxrpc.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/jaxrpc.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/log4j-1.2.8.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/log4j-1.2.8.jar
vendored
Normal file
Binary file not shown.
20
CASA-auth-token/server-java/Svc/external/log4j.properties
vendored
Normal file
20
CASA-auth-token/server-java/Svc/external/log4j.properties
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Set root category priority to INFO and its only appender to CONSOLE.
|
||||
log4j.rootCategory=INFO, CONSOLE
|
||||
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
|
||||
|
||||
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
|
||||
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
|
||||
|
||||
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
|
||||
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.CONSOLE.Threshold=INFO
|
||||
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.CONSOLE.layout.ConversionPattern=- %m%n
|
||||
|
||||
# LOGFILE is set to be a File appender using a PatternLayout.
|
||||
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
|
||||
log4j.appender.LOGFILE.File=axis.log
|
||||
log4j.appender.LOGFILE.Append=true
|
||||
log4j.appender.LOGFILE.Threshold=INFO
|
||||
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.LOGFILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
|
||||
BIN
CASA-auth-token/server-java/Svc/external/saaj.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/saaj.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/wsdl4j-1.5.1.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/wsdl4j-1.5.1.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/wss4j-1.5.0.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/wss4j-1.5.0.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xalan.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xalan.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xercesImpl.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xercesImpl.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xml-apis.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xml-apis.jar
vendored
Normal file
Binary file not shown.
BIN
CASA-auth-token/server-java/Svc/external/xmlsec-1.2.1.jar
vendored
Normal file
BIN
CASA-auth-token/server-java/Svc/external/xmlsec-1.2.1.jar
vendored
Normal file
Binary file not shown.
11
CASA-auth-token/server-java/Svc/jaas.conf
Normal file
11
CASA-auth-token/server-java/Svc/jaas.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
other {
|
||||
com.sun.security.auth.module.Krb5LoginModule required
|
||||
useTicketCache=true
|
||||
ticketCache="/var/lib/CASA/authtoken/svc/ticket.cache"
|
||||
useKeyTab=true
|
||||
principal="host/jcserver2.provo.novell.com"
|
||||
doNotPrompt=true
|
||||
storeKey=true
|
||||
keyTab="/etc/krb5.keytab"
|
||||
debug=true;
|
||||
};
|
||||
37
CASA-auth-token/server-java/Svc/linux/CasaAuthPolicyEditor.sh
Executable file
37
CASA-auth-token/server-java/Svc/linux/CasaAuthPolicyEditor.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Script for editing auth.policy files
|
||||
#
|
||||
########################################################################
|
||||
|
||||
# Source our environment variables file
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
# Perform the operation requested
|
||||
$JAVA_HOME/bin/java -jar /usr/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.jar $*
|
||||
|
||||
37
CASA-auth-token/server-java/Svc/linux/CasaAuthTokenSettingsEditor.sh
Executable file
37
CASA-auth-token/server-java/Svc/linux/CasaAuthTokenSettingsEditor.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Script for editing authtoken.settings files
|
||||
#
|
||||
########################################################################
|
||||
|
||||
# Source our environment variables file
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
# Perform the operation requested
|
||||
$JAVA_HOME/bin/java -jar /usr/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor.jar $*
|
||||
|
||||
182
CASA-auth-token/server-java/Svc/linux/CasaAuthtokenSvcD
Normal file
182
CASA-auth-token/server-java/Svc/linux/CasaAuthtokenSvcD
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Startup script for the Casa Authtoken Service Daemon (casa_atsd)
|
||||
#
|
||||
# /etc/init.d/casa_atsd
|
||||
#
|
||||
# description: casa_atsd is the CASA Authentication Token Service
|
||||
# (ATS). CASA Client utilize this service to obtain CASA authentication
|
||||
# tokens to authenticate to other services. The ATS executes as a
|
||||
# tomcat webapp. casa_atsd is the tomcat process which contains
|
||||
# the ATS.
|
||||
#
|
||||
# Note that some of the content from this file was copied from
|
||||
# /etc/init.d/tomcat5 whose author was Petr Mladek.
|
||||
# /etc/init.d/tomcat5 has the following copyrights:
|
||||
#
|
||||
# Copyright (c) 1995-2001 SuSE GmbH Nuernberg, Germany.
|
||||
# Copyright (c) 2002 SuSE Linux AG Nuernberg, Germany.
|
||||
#
|
||||
# processname: casa_atsd
|
||||
# pidfile: None
|
||||
# config utility: None
|
||||
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: casa_atsd
|
||||
# Required-Start: $local_fs $remote_fs
|
||||
# X-UnitedLinux-Should-Start: $named $syslog $time
|
||||
# Required-Stop: $local_fs $remote_fs $network
|
||||
# X-UnitedLinux-Should-Stop: $named $syslog $time
|
||||
# Default-Start: 1 2 3 5
|
||||
# Default-Stop:
|
||||
# Short-Description: Casa Authtoken Service Daemon
|
||||
# Description: Start Casa Authtoken Service Daemon
|
||||
### END INIT INFO
|
||||
|
||||
. /etc/rc.status
|
||||
|
||||
# Shell functions sourced from /etc/rc.status:
|
||||
# rc_check check and set local and overall rc status
|
||||
# rc_status check and set local and overall rc status
|
||||
# rc_status -v ditto but be verbose in local rc status
|
||||
# rc_status -v -r ditto and clear the local rc status
|
||||
# rc_failed set local and overall rc status to failed
|
||||
# rc_reset clear local rc status (overall remains)
|
||||
# rc_exit exit appropriate to overall rc status
|
||||
|
||||
# First reset status of this service
|
||||
rc_reset
|
||||
|
||||
DAEMON_USER=casaatsd
|
||||
DAEMON_GROUP=casaauth
|
||||
|
||||
atsIsRunning()
|
||||
{
|
||||
ats_ps_log=`mktemp /var/tmp/ats-ps.log.XXXXXX`
|
||||
ps aux --cols 1024 >"$ats_ps_log"
|
||||
ats_is_running="false"
|
||||
if grep " -Dcatalina.base=$CATALINA_BASE.*-Dcatalina.home=$CATALINA_HOME.*org.apache.catalina.startup.Bootstrap" "$ats_ps_log" >/dev/null 2>/dev/null ; then
|
||||
ats_is_running="true"
|
||||
fi
|
||||
rm -f "$ats_ps_log"
|
||||
test "$ats_is_running" = "true"
|
||||
}
|
||||
|
||||
StartDAEMON()
|
||||
{
|
||||
# Start the daemon
|
||||
echo -n "Starting casa_atsd"
|
||||
## Start daemon with startproc(8). If this fails
|
||||
## the echo return value is set appropriate.
|
||||
|
||||
# NOTE: startproc return 0, even if service is
|
||||
# already running to match LSB spec.
|
||||
if atsIsRunning ; then
|
||||
rc_failed 0
|
||||
else
|
||||
# Try to fix permissions
|
||||
chown --dereference $DAEMON_USER:$DAEMON_GROUP "$CATALINA_BASE"
|
||||
for dir in "$CATALINA_BASE/conf" \
|
||||
"$CATALINA_BASE/logs" \
|
||||
"$CATALINA_BASE/temp" \
|
||||
"$CATALINA_BASE/webapps" \
|
||||
"$CATALINA_BASE/work" ; do
|
||||
# the command true is used because of for example conf directory may be mounted read-only
|
||||
test -d "$dir" && chown -R --dereference $DAEMON_USER:$DAEMON_GROUP "$dir" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# Make sure that the server.xml link has been made
|
||||
if [ ! -f /srv/www/casaats/conf/server.xml ]; then
|
||||
ln -s /srv/www/casaats/conf/server-ibm.xml /srv/www/casaats/conf/server.xml
|
||||
chown -h casaatsd:casaauth /srv/www/casaats/conf/server.xml
|
||||
fi
|
||||
|
||||
# Start it up
|
||||
su $DAEMON_USER -s /bin/bash -c "$CATALINA_HOME/bin/startup.sh" >"$CATALINA_BASE/logs//start.log" 2>&1
|
||||
sleep 1
|
||||
if atsIsRunning ; then
|
||||
rc_failed 0
|
||||
else
|
||||
rc_failed 7
|
||||
fi
|
||||
fi
|
||||
rc_status -v
|
||||
}
|
||||
|
||||
|
||||
StopDAEMON()
|
||||
{
|
||||
# Stop the daemon
|
||||
echo -n "Shutting casa_atsd"
|
||||
## Stop daemon with killproc(8) and if this fails
|
||||
## set echo the echo return value.
|
||||
if atsIsRunning ; then
|
||||
su $DAEMON_USER -s /bin/bash -c "$CATALINA_HOME/bin/shutdown.sh" >"$CATALINA_BASE/logs/stop.log" 2>&1
|
||||
# wait 60 sec for stop at maximum
|
||||
wait_sec=60
|
||||
while [ "$wait_sec" != "0" ] ; do
|
||||
sleep 1
|
||||
if ! atsIsRunning ; then
|
||||
# the server is stoped, end the loop
|
||||
wait_sec=0
|
||||
break
|
||||
fi
|
||||
wait_sec=$((wait_sec -1))
|
||||
done
|
||||
# check the final status
|
||||
if atsIsRunning ; then
|
||||
rc_failed 1
|
||||
else
|
||||
rc_failed 0
|
||||
fi
|
||||
else
|
||||
rc_failed 0
|
||||
fi
|
||||
# Remember status and be verbose
|
||||
rc_status -v
|
||||
}
|
||||
|
||||
|
||||
# Source the environments file for our daemon
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
StartDAEMON
|
||||
;;
|
||||
stop)
|
||||
StopDAEMON
|
||||
;;
|
||||
restart|reload|force-reload)
|
||||
StopDAEMON
|
||||
sleep 1
|
||||
StartDAEMON
|
||||
;;
|
||||
status)
|
||||
echo -n "Checking for casa_atsd"
|
||||
## Check status with checkproc(8), if process is running
|
||||
## checkproc will return with exit status 0.
|
||||
|
||||
# Status has a slightly different for the status command:
|
||||
# 0 - service running
|
||||
# 1 - service dead, but /var/run/ pid file exists
|
||||
# 2 - service dead, but /var/lock/ lock file exists
|
||||
# 3 - service not running
|
||||
|
||||
# NOTE: checkproc returns LSB compliant status values.
|
||||
if atsIsRunning ; then
|
||||
rc_failed 0
|
||||
else
|
||||
rc_failed 3
|
||||
fi
|
||||
rc_status -v
|
||||
;;
|
||||
*)
|
||||
echo -n "Usage: $0 {start|stop|restart|reload|force-reload}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
rc_exit
|
||||
|
||||
214
CASA-auth-token/server-java/Svc/linux/CasaBasicATSSetup.sh
Executable file
214
CASA-auth-token/server-java/Svc/linux/CasaBasicATSSetup.sh
Executable file
@@ -0,0 +1,214 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Scrip for setting up iaRealm.xml and auth.policy files for ATS
|
||||
# using a single LDAP Realm.
|
||||
#
|
||||
# Notice that this scrip is very basic and only supports a single LDAP
|
||||
# server.
|
||||
#
|
||||
########################################################################
|
||||
|
||||
DEFAULT_TEMPLATE_FILE_FOLDER=/etc/CASA/authtoken/svc/templates
|
||||
DEFAULT_CONFIG_FILE_FOLDER=/etc/CASA/authtoken/svc
|
||||
|
||||
function display_usage
|
||||
{
|
||||
echo "usage: CasaBasicATSSetup.sh [-h] [TemplateFileFolder] [ConfigFileFolder]"
|
||||
echo " where the position dependent parameters are:"
|
||||
echo " -h - Display this information"
|
||||
echo " TemplateFileFolder - Path to the folder containing the template files. If"
|
||||
echo " not specified, the parameter defaults to"
|
||||
echo " $DEFAULT_TEMPLATE_FILE_FOLDER."
|
||||
echo " ConfigFileFolder - Path to the output file folder. If not specified, the"
|
||||
echo " parameter defaults to $DEFAULT_CONFIG_FILE_FOLDER."
|
||||
echo ""
|
||||
echo " The following environment variables MUST be exported when"
|
||||
echo " executing this script:"
|
||||
echo " REALM - The name of the LDAP Realm, example: Tree name"
|
||||
echo " LDAP_HOST_NAME - The host name of the LDAP server"
|
||||
echo " PROXY_USER_NAME - The name of the LDAP Proxy User"
|
||||
echo " PROXY_USER_PW - The password of the LDAP Proxy User"
|
||||
echo ""
|
||||
echo " The following environment variables MAY be exported when"
|
||||
echo " executing this script:"
|
||||
echo " LDAP_LISTEN_PORT - The port used by the LDAP server to listen for connections"
|
||||
echo ""
|
||||
echo " WARNING: CURRENTLY THERE IS A LIMITATION THAT PREVENTS YOU FROM"
|
||||
echo " USING ENVIRONMENT VARIABLES WITH THE CHARACTER ':'."
|
||||
echo ""
|
||||
}
|
||||
|
||||
function setup_iaRealms_file
|
||||
{
|
||||
# Determine the file names
|
||||
TEMPLATE_FILE=$TEMPLATE_FILE_FOLDER/iaRealms.xml
|
||||
CONFIG_FILE=$CONFIG_FILE_FOLDER/iaRealms.xml
|
||||
|
||||
# Verify that the template file exists
|
||||
if [ ! -f $TEMPLATE_FILE ]; then
|
||||
echo "Template file $TEMPLATE_FILE does not exist"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Verify that the output folder exists
|
||||
if [ ! -d $CONFIG_FILE_FOLDER ]; then
|
||||
echo "Output folder $CONFIG_FILE_FOLDER does not exist"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Clean-up the output folder
|
||||
rm -f $CONFIG_FILE
|
||||
|
||||
# Verify that all of the appropriate environment variables have been set
|
||||
if [ "$REALM" != "" ]; then
|
||||
if [ "$LDAP_HOST_NAME" != "" ]; then
|
||||
if [ "$PROXY_USER_NAME" != "" ]; then
|
||||
if [ "$PROXY_USER_PW" != "" ]; then
|
||||
# Create and edit the output file
|
||||
sed s:REALM:$REALM:g $TEMPLATE_FILE > $CONFIG_FILE
|
||||
sed -i s:LDAP_HOST_NAME:$LDAP_HOST_NAME:g $CONFIG_FILE
|
||||
sed -i s:PROXY_USER_NAME:$PROXY_USER_NAME:g $CONFIG_FILE
|
||||
sed -i s:PROXY_USER_PW:$PROXY_USER_PW:g $CONFIG_FILE
|
||||
if [ "$LDAP_LISTEN_PORT" != '' ]; then
|
||||
sed -i s:LDAP_LISTEN_PORT:$LDAP_LISTEN_PORT:g $CONFIG_FILE
|
||||
else
|
||||
sed -i s:LDAP_LISTEN_PORT:389:g $CONFIG_FILE
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function setup_authPolicy_file
|
||||
{
|
||||
EDITOR=/usr/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.sh
|
||||
|
||||
# Determine the file name
|
||||
CONFIG_FILE=$CONFIG_FILE_FOLDER/auth.policy
|
||||
|
||||
# Verify that the output folder exists
|
||||
if [ ! -d $CONFIG_FILE_FOLDER ]; then
|
||||
echo "Output folder $CONFIG_FILE_FOLDER does not exist"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Clean-up the output folder
|
||||
rm -f $CONFIG_FILE
|
||||
|
||||
# Verify that all of the appropriate environment variables have been set
|
||||
if [ "$REALM" != "" ]; then
|
||||
# Create and setup the auth.policy file
|
||||
$EDITOR -create -file $CONFIG_FILE
|
||||
$EDITOR -append -entry $REALM:Krb5Authenticate -file $CONFIG_FILE
|
||||
$EDITOR -append -entry $REALM:PwdAuthenticate -file $CONFIG_FILE
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function setup_svcSettings_file
|
||||
{
|
||||
EDITOR=/usr/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.sh
|
||||
|
||||
# Determine the file name
|
||||
CONFIG_FILE=$CONFIG_FILE_FOLDER/svc.settings
|
||||
IAREALMS_FILE_PATH=$CONFIG_FILE_FOLDER/iaRealms.xml
|
||||
|
||||
# Verify that the output folder exists
|
||||
if [ ! -d $CONFIG_FILE_FOLDER ]; then
|
||||
echo "Output folder $CONFIG_FILE_FOLDER does not exist"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# Clean-up the output folder
|
||||
rm -f $CONFIG_FILE
|
||||
|
||||
# Create and setup the svc.settings file
|
||||
$EDITOR -create -file $CONFIG_FILE
|
||||
$EDITOR -set IAConfigFile $IAREALMS_FILE_PATH -file $CONFIG_FILE
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
#### MAIN ####
|
||||
|
||||
# Determine what folders to utilize based on the input
|
||||
# parameters and our defaults.
|
||||
if [ "$1" != "" ]; then
|
||||
if [ "$1" != "-h" ]; then
|
||||
TEMPLATE_FILE_FOLDER=$1
|
||||
else
|
||||
display_usage
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
TEMPLATE_FILE_FOLDER=$DEFAULT_TEMPLATE_FILE_FOLDER
|
||||
fi
|
||||
|
||||
if [ "$2" != "" ]; then
|
||||
CONFIG_FILE_FOLDER=$2
|
||||
else
|
||||
CONFIG_FILE_FOLDER=$DEFAULT_CONFIG_FILE_FOLDER
|
||||
fi
|
||||
|
||||
# Setup the configuration files
|
||||
setup_iaRealms_file
|
||||
RETVAL=$?
|
||||
if [ "$RETVAL" = "0" ]; then
|
||||
setup_authPolicy_file
|
||||
RETVAL=$?
|
||||
if [ "$RETVAL" = "0" ]; then
|
||||
setup_svcSettings_file
|
||||
RETVAL=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$RETVAL" != "0" ]; then
|
||||
if [ "$RETVAL" = "1" ]; then
|
||||
display_usage
|
||||
fi
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
|
||||
37
CASA-auth-token/server-java/Svc/linux/CasaIdenTokenSettingsEditor.sh
Executable file
37
CASA-auth-token/server-java/Svc/linux/CasaIdenTokenSettingsEditor.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Script for editing identoken.settings files
|
||||
#
|
||||
########################################################################
|
||||
|
||||
# Source our environment variables file
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
# Perform the operation requested
|
||||
$JAVA_HOME/bin/java -jar /usr/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor.jar $*
|
||||
|
||||
37
CASA-auth-token/server-java/Svc/linux/CasaSvcSettingsEditor.sh
Executable file
37
CASA-auth-token/server-java/Svc/linux/CasaSvcSettingsEditor.sh
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# Script for editing svc.settings files
|
||||
#
|
||||
########################################################################
|
||||
|
||||
# Source our environment variables file
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
# Perform the operation requested
|
||||
$JAVA_HOME/bin/java -jar /usr/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.jar $*
|
||||
|
||||
45
CASA-auth-token/server-java/Svc/linux/Makefile.am
Normal file
45
CASA-auth-token/server-java/Svc/linux/Makefile.am
Normal file
@@ -0,0 +1,45 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = CasaAuthtokenSvcD \
|
||||
envvars \
|
||||
server_keystore_setup.sh \
|
||||
crypto.properties \
|
||||
CasaBasicATSSetup.sh \
|
||||
CasaAuthPolicyEditor.sh \
|
||||
CasaAuthTokenSettingsEditor.sh \
|
||||
CasaIdenTokenSettingsEditor.sh \
|
||||
CasaSvcSettingsEditor.sh
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
6
CASA-auth-token/server-java/Svc/linux/crypto.properties
Normal file
6
CASA-auth-token/server-java/Svc/linux/crypto.properties
Normal file
@@ -0,0 +1,6 @@
|
||||
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
|
||||
org.apache.ws.security.crypto.merlin.keystore.type=jks
|
||||
org.apache.ws.security.crypto.merlin.keystore.password=secret
|
||||
org.apache.ws.security.crypto.merlin.keystore.alias=signingKey
|
||||
org.apache.ws.security.crypto.merlin.alias.password=secret
|
||||
org.apache.ws.security.crypto.merlin.file=/etc/CASA/authtoken/keys/server/jks-store
|
||||
14
CASA-auth-token/server-java/Svc/linux/envvars
Normal file
14
CASA-auth-token/server-java/Svc/linux/envvars
Normal file
@@ -0,0 +1,14 @@
|
||||
############################################################
|
||||
# #
|
||||
# Environment variable file for casa_atsd. #
|
||||
# #
|
||||
# Note: This file is sourced by the casa_atsd rc script #
|
||||
# when starting the service. #
|
||||
# #
|
||||
############################################################
|
||||
CATALINA_BASE="/srv/www/casaats"
|
||||
CATALINA_HOME="/usr/share/tomcat5"
|
||||
JAVA_HOME="/usr/lib/jvm/java-1.5.0-ibm"
|
||||
JAVA_OPTS="-Dcom.novell.casa.authtoksvc.config=/etc/CASA/authtoken/svc"
|
||||
export CATALINA_BASE CATALINA_HOME JAVA_HOME JAVA_OPTS
|
||||
|
||||
77
CASA-auth-token/server-java/Svc/linux/server_keystore_setup.sh
Executable file
77
CASA-auth-token/server-java/Svc/linux/server_keystore_setup.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/bin/sh
|
||||
########################################################################
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
########################################################################
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# CASA ATS Keystore Setup Script.
|
||||
#
|
||||
# An ATS signs tokens and communicates with clients over
|
||||
# SSL. This scrip sets up the necessary key-pairs and
|
||||
# certificates for the ATS to perform these functions.
|
||||
#
|
||||
# For token signing purposes, this scrip creates a self
|
||||
# signed certificate that it then exports. At this time it
|
||||
# is sufficient to utilize self signed certificates because
|
||||
# they are meant to be consumed by entities of the local
|
||||
# box.
|
||||
#
|
||||
########################################################################
|
||||
|
||||
# Source our environment variables file
|
||||
. /etc/CASA/authtoken/svc/envvars
|
||||
|
||||
# Perform the operation requested
|
||||
|
||||
# Do not do anything if the server keystore has already been created
|
||||
if [ -f /etc/CASA/authtoken/keys/server/jks-store ]; then
|
||||
echo "The server keystore is already setup"
|
||||
# Make sure that the keystore file is owned by our service
|
||||
chown casaatsd:casaauth /etc/CASA/authtoken/keys/server/jks-store
|
||||
else
|
||||
echo "Setting up the server's keystore"
|
||||
|
||||
KEYTOOL_PATH=$JAVA_HOME/bin/keytool
|
||||
|
||||
# Create the server keystore with the key that will be used for signing tokens
|
||||
host=`hostname -f`
|
||||
$KEYTOOL_PATH -genkey -alias signingKey -keystore /etc/CASA/authtoken/keys/server/jks-store -dname "cn=casaatsd@$host" -validity 3600 -keypass secret -storepass secret
|
||||
|
||||
# Export self-signed certificate for the signing key
|
||||
$KEYTOOL_PATH -export -keystore /etc/CASA/authtoken/keys/server/jks-store -alias signingKey -storepass secret -keypass secret -file /etc/CASA/authtoken/keys/casaatsdSigningCert
|
||||
|
||||
# Print the exported cert
|
||||
#$KEYTOOL_PATH -printcert -file /etc/CASA/authtoken/keys/casaatsdSigningCert
|
||||
|
||||
# Create a key for Tomcat to do SSL communications
|
||||
$KEYTOOL_PATH -genkey -alias tomcat -keyalg RSA -keystore /etc/CASA/authtoken/keys/server/jks-store -dname "cn=$host" -validity 3600 -keypass secret -storepass secret
|
||||
|
||||
# List the contents of the server's keystore
|
||||
#$KEYTOOL_PATH -list -rfc -keystore /etc/CASA/authtoken/keys/server/jks-store -storepass secret
|
||||
|
||||
# Make sure that the keystore is only accessible by the service
|
||||
chown casaatsd:casaauth /etc/CASA/authtoken/keys/server/jks-store
|
||||
chmod 600 /etc/CASA/authtoken/keys/server/jks-store
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Main-Class: com.novell.casa.authtoksvc.AuthPolicyEditor
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Main-Class: com.novell.casa.authtoksvc.AuthTokenSettingsEditor
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Main-Class: com.novell.casa.authtoksvc.IdenTokenSettingsEditor
|
||||
|
||||
40
CASA-auth-token/server-java/Svc/manifest/Makefile.am
Normal file
40
CASA-auth-token/server-java/Svc/manifest/Makefile.am
Normal file
@@ -0,0 +1,40 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = AuthPolicyEditor.txt \
|
||||
AuthTokenSettingsEditor.txt \
|
||||
IdenTokenSettingsEditor.txt \
|
||||
SvcSettingsEditor.txt
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Main-Class: com.novell.casa.authtoksvc.SvcSettingsEditor
|
||||
|
||||
13
CASA-auth-token/server-java/Svc/sampleConf/auth.policy
Normal file
13
CASA-auth-token/server-java/Svc/sampleConf/auth.policy
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
</settings>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<TokenLifetime>3600</TokenLifetime>
|
||||
</settings>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Attributes>sn,groupMembership</Attributes>
|
||||
</settings>
|
||||
|
||||
25
CASA-auth-token/server-java/Svc/sampleConf/iaRealms.xml
Normal file
25
CASA-auth-token/server-java/Svc/sampleConf/iaRealms.xml
Normal 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>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<EncryptAttributes>false</EncryptAttributes>
|
||||
<Attributes>sn</Attributes>
|
||||
</settings>
|
||||
|
||||
5
CASA-auth-token/server-java/Svc/sampleConf/svc.settings
Normal file
5
CASA-auth-token/server-java/Svc/sampleConf/svc.settings
Normal 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>
|
||||
37
CASA-auth-token/server-java/Svc/src/Makefile.am
Normal file
37
CASA-auth-token/server-java/Svc/src/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = com
|
||||
|
||||
DIST_SUBDIRS = com
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = $(CFILES)
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
37
CASA-auth-token/server-java/Svc/src/com/Makefile.am
Normal file
37
CASA-auth-token/server-java/Svc/src/com/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = novell
|
||||
|
||||
DIST_SUBDIRS = novell
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = $(CFILES)
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
37
CASA-auth-token/server-java/Svc/src/com/novell/Makefile.am
Normal file
37
CASA-auth-token/server-java/Svc/src/com/novell/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = casa
|
||||
|
||||
DIST_SUBDIRS = casa
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = $(CFILES)
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS = authtoksvc
|
||||
|
||||
DIST_SUBDIRS = authtoksvc
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = $(CFILES)
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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";
|
||||
public final static String Krb5ServicePrincipalName = "ServicePrincipalName";
|
||||
|
||||
// Default configuration values
|
||||
private String m_defaultKrb5ServicePrincipalNameValue = "host";
|
||||
|
||||
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);
|
||||
|
||||
// The setting is not in our map, check if it is one to
|
||||
// which we have defaults.
|
||||
if (settingName.equals(Krb5ServicePrincipalName) == true)
|
||||
{
|
||||
value = m_defaultKrb5ServicePrincipalNameValue;
|
||||
System.err.println("AuthMechConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_mechSettingsMap.put(Krb5ServicePrincipalName, m_defaultKrb5ServicePrincipalNameValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthMechConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("AuthMechConfig.getSetting()- Setting value = " + value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* AuthMechanism Interface.
|
||||
*
|
||||
* This is the interface implemented by Authentication Mechanisms.
|
||||
*
|
||||
* Please note that Authentication Machanisms must also implement the
|
||||
* Serializable interface.
|
||||
*
|
||||
*/
|
||||
public interface AuthMechanism
|
||||
{
|
||||
/*
|
||||
* Initialize the authentication mechanism.
|
||||
*/
|
||||
void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception;
|
||||
|
||||
/*
|
||||
* Process authenticate request. If successful, return the Id of the
|
||||
* authenticated identity.
|
||||
*/
|
||||
String invoke(AuthReqMsg authReqMsg) throws Exception;
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
String getId();
|
||||
}
|
||||
@@ -0,0 +1,871 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.apache.xerces.parsers.DOMParser;
|
||||
import org.apache.xml.serialize.OutputFormat;
|
||||
import org.apache.xml.serialize.XMLSerializer;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Formatter;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the creation and editing of auth.policy files.
|
||||
*
|
||||
**/
|
||||
public class AuthPolicyEditor
|
||||
{
|
||||
private static final String usage =
|
||||
"usage: AuthPolicyEditor -op [-entry realm:mechanismName[:mechanismInfo]] [-refentry realm:mechanismName] -file policyFilePath\n\n" +
|
||||
" where:\n" +
|
||||
" -op - Corresponds to one of the following operations:\n" +
|
||||
" -create - Create new auth policy file\n" +
|
||||
" -list - List auth source entries\n" +
|
||||
" -prepend - Insert auth source entry at the head\n" +
|
||||
" -append - Insert auth source entry at the tail\n" +
|
||||
" -insert - Insert auth source entry after specified reference entry\n" +
|
||||
" -remove - Remove auth source entry\n" +
|
||||
" -file - Path the the auth policy file\n" +
|
||||
" -entry - Auth source entry to be inserted or removed. Must be followed by\n" +
|
||||
" a string formated as follows:\n" +
|
||||
" insert operations format: realm:mechanismName or realm:mechanismName:mechanismInfo\n" +
|
||||
" remove operations format: realm:mechanismName\n" +
|
||||
" -refentry - Reference auth source entry. Must be followed by a string formated\n" +
|
||||
" as follows: realm:mechanismName\n";
|
||||
|
||||
private static final String initialPolicy =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<auth_policy>\n" +
|
||||
"</auth_policy>\n";
|
||||
|
||||
private final static String AuthSourceElementName = "auth_source";
|
||||
private final static String RealmElementName = "realm";
|
||||
private final static String MechanismElementName = "mechanism";
|
||||
private final static String MechanismInfoElementName = "mechanism_info";
|
||||
private final static String Krb5Mechanism = "Krb5Authenticate";
|
||||
private final static String PwdMechanism = "PwdAuthenticate";
|
||||
|
||||
|
||||
/**
|
||||
* Returns the formal mechanism name if well known
|
||||
*
|
||||
* @param mechName Name of mechanism.
|
||||
* @return Mechanism formal name.
|
||||
*/
|
||||
private static String mechFormalName(String mechName)
|
||||
{
|
||||
String formalName;
|
||||
|
||||
if (mechName.compareToIgnoreCase(Krb5Mechanism) == 0)
|
||||
formalName = Krb5Mechanism;
|
||||
else if (mechName.compareToIgnoreCase(PwdMechanism) == 0)
|
||||
formalName = PwdMechanism;
|
||||
else
|
||||
formalName = mechName;
|
||||
|
||||
return formalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the contents of the specified file with the provided
|
||||
* policy document.
|
||||
*
|
||||
* @param filePath Path to policy file to be updated.
|
||||
* @param doc Policy document.
|
||||
* @return True if successful.
|
||||
*/
|
||||
private static boolean updateFile(String filePath, Document doc)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
// Update the file with the specified document
|
||||
// after removing the text nodes.
|
||||
try
|
||||
{
|
||||
// Remove text nodes
|
||||
Element root = doc.getDocumentElement();
|
||||
Node child;
|
||||
Node next = (Node) root.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// Remove the node
|
||||
root.removeChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Update file
|
||||
File f = new File(filePath);
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
OutputFormat format = new OutputFormat(doc);
|
||||
XMLSerializer serializer = new XMLSerializer(out, format);
|
||||
serializer.serialize(doc.getDocumentElement());
|
||||
out.close();
|
||||
|
||||
result = true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Error writing to file " + filePath + ", exception: " + e.toString());
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("SecurityException writting to file " + filePath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets document for the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @return Document representation of the policy file.
|
||||
*/
|
||||
private static Document getPolicyFileDoc(String filePath)
|
||||
{
|
||||
Document doc = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from policy file
|
||||
File f = new File(filePath);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
InputSource source = new InputSource(inStream);
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.parse(source);
|
||||
doc = parser.getDocument();
|
||||
|
||||
inStream.close();
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("Policy file " + filePath + " not found");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("SecurityException accessing " + filePath);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("IOException accessing " + filePath + " Exception=" + e.toString());
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("Policy file " + filePath + " format error");
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a starting policy document
|
||||
*
|
||||
* @return Starting policy document.
|
||||
*/
|
||||
private static Document getPolicyDoc()
|
||||
{
|
||||
Document doc = null;
|
||||
|
||||
try
|
||||
{
|
||||
StringReader reader = new StringReader(initialPolicy);
|
||||
InputSource source = new InputSource(reader);
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.parse(source);
|
||||
doc = parser.getDocument();
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Program error, exception: " + e.toString());
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* List the auth_source entries in the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
private static boolean performListOperation(String filePath)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// List the auth sources present in the policy file
|
||||
Document doc = getPolicyFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Go through the elements of the document
|
||||
Element root = doc.getDocumentElement();
|
||||
Node auth_source_node;
|
||||
Node next_auth_source_node = root.getFirstChild();
|
||||
while ((auth_source_node = next_auth_source_node) != null)
|
||||
{
|
||||
next_auth_source_node = auth_source_node.getNextSibling();
|
||||
if (auth_source_node.getNodeType() == Node.ELEMENT_NODE
|
||||
&& auth_source_node.getLocalName().compareToIgnoreCase("auth_source") == 0)
|
||||
{
|
||||
System.out.println("Auth_Source: ");
|
||||
|
||||
// We are dealing with an auth_source, display its children.
|
||||
Node child;
|
||||
Node next = auth_source_node.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
if (child.getLocalName().compareToIgnoreCase("realm") == 0)
|
||||
{
|
||||
System.out.println(" Identity source: " + child.getTextContent());
|
||||
}
|
||||
else if (child.getLocalName().compareToIgnoreCase("mechanism") == 0)
|
||||
{
|
||||
System.out.println(" Authentication Mechanism: " + child.getTextContent());
|
||||
}
|
||||
else if (child.getLocalName().compareToIgnoreCase("mechanism_info") == 0)
|
||||
{
|
||||
System.out.println(" Authentication Mechanism Info: " + child.getTextContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create policy file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
private static boolean performCreateOperation(String filePath)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// create a policy file
|
||||
Document doc = getPolicyDoc();
|
||||
if (doc != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
File f = new File(filePath);
|
||||
boolean createStatus = f.createNewFile();
|
||||
if (createStatus == true)
|
||||
{
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
OutputFormat format = new OutputFormat(doc);
|
||||
XMLSerializer serializer = new XMLSerializer(out, format);
|
||||
serializer.serialize(doc.getDocumentElement());
|
||||
out.close();
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("File " + filePath + " already exists");
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Error creating file " + filePath + ", exception: " + e.toString());
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("SecurityException creating " + filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend the auth_source entry to the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @param entry Auth_source entry to be prepended. Entry is formated as
|
||||
* follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
* is optional).
|
||||
* @return True if operation is successfully performed.
|
||||
*/
|
||||
private static boolean performPrependOperation(String filePath, String entry)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Prepend auth source entry to the policy file
|
||||
Document doc = getPolicyFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Parse the entry into its components. Entry is formated as
|
||||
// follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
// is optional).
|
||||
String[] entryComponents = entry.split(":");
|
||||
if (entryComponents.length >= 2
|
||||
&& entryComponents.length <= 3)
|
||||
{
|
||||
// Create and prepend the entry elements
|
||||
Element root = doc.getDocumentElement();
|
||||
Element auth_source_element = doc.createElement(AuthSourceElementName);
|
||||
Element realm_element = doc.createElement(RealmElementName);
|
||||
realm_element.setTextContent(entryComponents[0]);
|
||||
auth_source_element.appendChild(realm_element);
|
||||
Element mechanism_element = doc.createElement(MechanismElementName);
|
||||
mechanism_element.setTextContent(mechFormalName(entryComponents[1]));
|
||||
auth_source_element.appendChild(mechanism_element);
|
||||
if (entryComponents.length == 3)
|
||||
{
|
||||
Element mechanism_info_element = doc.createElement(MechanismInfoElementName);
|
||||
mechanism_info_element.setTextContent(mechFormalName(entryComponents[2]));
|
||||
auth_source_element.appendChild(mechanism_info_element);
|
||||
}
|
||||
|
||||
Element firstEntry = null;
|
||||
Node child;
|
||||
Node next = (Node) root.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// This is the first entry
|
||||
firstEntry = (Element) child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (firstEntry != null)
|
||||
root.insertBefore(auth_source_element, firstEntry);
|
||||
else
|
||||
root.appendChild(auth_source_element);
|
||||
|
||||
// Update the file
|
||||
opPerformed = updateFile(filePath, doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Invalid entry format");
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the auth_source entry to the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @param entry Auth_source entry to be appended. Entry is formated as
|
||||
* follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
* is optional).
|
||||
* @return True if operation is successfully performed.
|
||||
*/
|
||||
private static boolean performAppendOperation(String filePath, String entry)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Append auth source entry to the policy file
|
||||
Document doc = getPolicyFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Parse the entry into its components. Entry is formated as
|
||||
// follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
// is optional).
|
||||
String[] entryComponents = entry.split(":");
|
||||
if (entryComponents.length >= 2
|
||||
&& entryComponents.length <= 3)
|
||||
{
|
||||
// Create and append the entry elements
|
||||
Element root = doc.getDocumentElement();
|
||||
Element auth_source_element = doc.createElement(AuthSourceElementName);
|
||||
Element realm_element = doc.createElement(RealmElementName);
|
||||
realm_element.setTextContent(entryComponents[0]);
|
||||
auth_source_element.appendChild(realm_element);
|
||||
Element mechanism_element = doc.createElement(MechanismElementName);
|
||||
mechanism_element.setTextContent(mechFormalName(entryComponents[1]));
|
||||
auth_source_element.appendChild(mechanism_element);
|
||||
if (entryComponents.length == 3)
|
||||
{
|
||||
Element mechanism_info_element = doc.createElement(MechanismInfoElementName);
|
||||
mechanism_info_element.setTextContent(mechFormalName(entryComponents[2]));
|
||||
auth_source_element.appendChild(mechanism_info_element);
|
||||
}
|
||||
root.appendChild(auth_source_element);
|
||||
|
||||
// Update the file
|
||||
opPerformed = updateFile(filePath, doc);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Invalid entry format");
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert the auth_source entry to the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @param entry Auth_source entry to be inserted. Entry is formated as
|
||||
* follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
* is optional).
|
||||
* @param refEntry Reference auth_source entry (New entry is inserted after
|
||||
* it). Entry is formated as follows: realm:mech.
|
||||
* @return True if operation is successfully performed.
|
||||
*/
|
||||
private static boolean performInsertOperation(String filePath, String entry, String refEntry)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Remove auth sources present in the policy file
|
||||
Document doc = getPolicyFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Parse the entries into their components. Entry is formated as
|
||||
// follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
// is optional).
|
||||
String[] entryComponents = entry.split(":");
|
||||
String[] refEntryComponents = refEntry.split(":");
|
||||
if (refEntryComponents.length == 2
|
||||
&& entryComponents.length >= 2
|
||||
&& entryComponents.length <= 3)
|
||||
{
|
||||
// Go through the elements of the document
|
||||
Element root = doc.getDocumentElement();
|
||||
Node curr_auth_source_node;
|
||||
Node next_auth_source_node = root.getFirstChild();
|
||||
while ((curr_auth_source_node = next_auth_source_node) != null)
|
||||
{
|
||||
next_auth_source_node = curr_auth_source_node.getNextSibling();
|
||||
if (curr_auth_source_node.getNodeType() == Node.ELEMENT_NODE
|
||||
&& curr_auth_source_node.getLocalName().compareToIgnoreCase("auth_source") == 0)
|
||||
{
|
||||
// We are dealing with an auth_source, check if this is the
|
||||
// reference entry.
|
||||
boolean realmMatch = false;
|
||||
boolean mechanismMatch = false;
|
||||
|
||||
Node child;
|
||||
Node next = curr_auth_source_node.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
if (child.getLocalName().compareToIgnoreCase(RealmElementName) == 0)
|
||||
{
|
||||
// Compare the realm name
|
||||
if (child.getTextContent().compareToIgnoreCase(refEntryComponents[0]) == 0)
|
||||
realmMatch = true;
|
||||
}
|
||||
else if (child.getLocalName().compareToIgnoreCase(MechanismElementName) == 0)
|
||||
{
|
||||
// Compare the realm name
|
||||
if (child.getTextContent().compareToIgnoreCase(mechFormalName(refEntryComponents[1])) == 0)
|
||||
mechanismMatch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert entry after current entry if we have a match for the reference entry
|
||||
if (realmMatch && mechanismMatch)
|
||||
{
|
||||
Element auth_source_element = doc.createElement(AuthSourceElementName);
|
||||
Element realm_element = doc.createElement(RealmElementName);
|
||||
realm_element.setTextContent(entryComponents[0]);
|
||||
auth_source_element.appendChild(realm_element);
|
||||
Element mechanism_element = doc.createElement(MechanismElementName);
|
||||
mechanism_element.setTextContent(mechFormalName(entryComponents[1]));
|
||||
auth_source_element.appendChild(mechanism_element);
|
||||
if (entryComponents.length == 3)
|
||||
{
|
||||
Element mechanism_info_element = doc.createElement(MechanismInfoElementName);
|
||||
mechanism_info_element.setTextContent(mechFormalName(entryComponents[2]));
|
||||
auth_source_element.appendChild(mechanism_info_element);
|
||||
}
|
||||
curr_auth_source_node.getNextSibling();
|
||||
Element nextEntry = null;
|
||||
next = (Node) curr_auth_source_node.getNextSibling();;
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
// This is the next entry
|
||||
nextEntry = (Element) child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nextEntry != null)
|
||||
root.insertBefore(auth_source_element, nextEntry);
|
||||
else
|
||||
root.appendChild(auth_source_element);
|
||||
|
||||
// Update the file
|
||||
opPerformed = updateFile(filePath, doc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Invalid entry format");
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the auth_source entry from the specified policy file.
|
||||
*
|
||||
* @param filePath Path to the policy file.
|
||||
* @param entry Auth_source entry to be removed. Entry is formated as
|
||||
* follows: realm:mech.
|
||||
* @return True if operation is successfully performed.
|
||||
*/
|
||||
private static boolean performRemoveOperation(String filePath, String entry)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Remove auth sources present in the policy file
|
||||
Document doc = getPolicyFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Parse the entry into its components. Entry is formated as
|
||||
// follows: realm:mech:mechinfo (Note that the mechinfo
|
||||
// is optional).
|
||||
String[] entryComponents = entry.split(":");
|
||||
if (entryComponents.length == 2)
|
||||
{
|
||||
// Go through the elements of the document
|
||||
Element root = doc.getDocumentElement();
|
||||
Node auth_source_node;
|
||||
Node next_auth_source_node = root.getFirstChild();
|
||||
while ((auth_source_node = next_auth_source_node) != null)
|
||||
{
|
||||
next_auth_source_node = auth_source_node.getNextSibling();
|
||||
if (auth_source_node.getNodeType() == Node.ELEMENT_NODE
|
||||
&& auth_source_node.getLocalName().compareToIgnoreCase("auth_source") == 0)
|
||||
{
|
||||
// We are dealing with an auth_source, check if this is the entry
|
||||
// that must be removed.
|
||||
boolean realmMatch = false;
|
||||
boolean mechanismMatch = false;
|
||||
|
||||
Node child;
|
||||
Node next = auth_source_node.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
if (child.getLocalName().compareToIgnoreCase(RealmElementName) == 0)
|
||||
{
|
||||
// Compare the realm name
|
||||
if (child.getTextContent().compareToIgnoreCase(entryComponents[0]) == 0)
|
||||
realmMatch = true;
|
||||
}
|
||||
else if (child.getLocalName().compareToIgnoreCase(MechanismElementName) == 0)
|
||||
{
|
||||
// Compare the realm name
|
||||
if (child.getTextContent().compareToIgnoreCase(mechFormalName(entryComponents[1])) == 0)
|
||||
mechanismMatch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove current entry if it matches
|
||||
if (realmMatch && mechanismMatch)
|
||||
{
|
||||
System.out.println("RemovingChild");
|
||||
root.removeChild(auth_source_node);
|
||||
|
||||
// Update the file
|
||||
opPerformed = updateFile(filePath, doc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Invalid entry format");
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applications Entry Point
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String op = null;
|
||||
boolean opPerformed = false;
|
||||
boolean argumentsError = false;
|
||||
String filePath = null;
|
||||
String entry = null;
|
||||
String refEntry = null;
|
||||
|
||||
// Process the command line arguments
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
// Proceed based on the command
|
||||
if (args[i].compareToIgnoreCase("-list") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "list";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-create") == 0)
|
||||
{
|
||||
// Create operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "create";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-prepend") == 0)
|
||||
{
|
||||
// Prepend operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "prepend";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-append") == 0)
|
||||
{
|
||||
// Append operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "append";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-insert") == 0)
|
||||
{
|
||||
// Insert operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "insert";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-remove") == 0)
|
||||
{
|
||||
// Remove operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "remove";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-entry") == 0)
|
||||
{
|
||||
// The next argument should contain the entry information
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
entry = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-refentry") == 0)
|
||||
{
|
||||
// The next argument should contain the reference entry information
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
refEntry = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-file") == 0)
|
||||
{
|
||||
// The next argument should contain the filepath
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
filePath = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed based on the specified parameters
|
||||
if (argumentsError == false)
|
||||
{
|
||||
if (filePath != null && op != null)
|
||||
{
|
||||
System.out.println("Dealing with policy file: " + filePath);
|
||||
|
||||
// Proceed based on the operation requested
|
||||
if (op.compareTo("list") == 0)
|
||||
{
|
||||
opPerformed = performListOperation(filePath);
|
||||
}
|
||||
else if (op.compareTo("create") == 0)
|
||||
{
|
||||
opPerformed = performCreateOperation(filePath);
|
||||
}
|
||||
else if (op.compareTo("prepend") == 0)
|
||||
{
|
||||
// Verify that the required parameters were specified
|
||||
if (entry != null)
|
||||
{
|
||||
opPerformed = performPrependOperation(filePath, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
else if (op.compareTo("append") == 0)
|
||||
{
|
||||
// Verify that the required parameters were specified
|
||||
if (entry != null)
|
||||
{
|
||||
opPerformed = performAppendOperation(filePath, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
else if (op.compareTo("insert") == 0)
|
||||
{
|
||||
// Verify that the required parameters were specified
|
||||
if (entry != null && refEntry != null)
|
||||
{
|
||||
opPerformed = performInsertOperation(filePath, entry, refEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
else if (op.compareTo("remove") == 0)
|
||||
{
|
||||
// Verify that the required parameters were specified
|
||||
if (entry != null)
|
||||
{
|
||||
opPerformed = performRemoveOperation(filePath, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Tool error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the usage string if we encountered an error with the
|
||||
// command line arguments.
|
||||
if (argumentsError)
|
||||
System.out.print(usage);
|
||||
|
||||
// Set the exit code appropriatedly
|
||||
if (opPerformed)
|
||||
System.exit(0);
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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_REALM_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_realm = m_authReqMsg.m_realm.concat(new String(ch, start, length));
|
||||
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_MECH_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_authMechanism = m_authReqMsg.m_authMechanism.concat(new String(ch, start, length));
|
||||
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;
|
||||
|
||||
case AWAITING_AUTH_MECH_TOKEN_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_authReqMsg.m_authMechToken = m_authReqMsg.m_authMechToken.concat(new String(ch, start, length));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public AuthReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the AuthReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication realm.
|
||||
*/
|
||||
public String getRealm() throws Exception
|
||||
{
|
||||
return m_realm;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication mechanism token.
|
||||
*/
|
||||
public String getAuthMechToken() throws Exception
|
||||
{
|
||||
return m_authMechToken;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the authentication mechanism id.
|
||||
*/
|
||||
public String getMechanismId() throws Exception
|
||||
{
|
||||
return m_authMechanism;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* AuthRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the CASA Client as a
|
||||
* response to an authentication request. The format of the message is
|
||||
* as follows when the response includes a session token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <auth_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
|
||||
* </auth_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include a session token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <auth_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </auth_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class AuthRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the session token.
|
||||
*/
|
||||
public AuthRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the session token.
|
||||
*/
|
||||
public AuthRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String sessionToken,
|
||||
String sessionTokenLifetime) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.sessionTokenElementName + ">"
|
||||
+ "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||
+ sessionToken + "</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the AuthRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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.apache.axis.Message;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.client.AxisClient;
|
||||
import org.apache.axis.configuration.NullProvider;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.axis.message.SOAPBody;
|
||||
import org.apache.axis.message.MessageElement;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.*;
|
||||
|
||||
// Un-comment the following line to print Authentication Token Messages
|
||||
//import org.apache.axis.utils.XMLUtils;
|
||||
|
||||
|
||||
/*
|
||||
* AuthToken Class.
|
||||
*
|
||||
* This class constructs authentication tokens that clients can present
|
||||
* to services for authentication. The authentication token consists of
|
||||
* a SOAP message secured with WSSecurity with the appropriate elements signed
|
||||
* and with a timestamp. The body of the SOAP message is as follows:
|
||||
*
|
||||
* <auth_token>
|
||||
* <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 = null;
|
||||
private String m_identityToken = null;
|
||||
|
||||
static final String authTokenSoapMsg =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<SOAP-ENV:Envelope" +
|
||||
" xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
" <SOAP-ENV:Body>" +
|
||||
" <auth_token><ident_token><type></type></ident_token></auth_token>" +
|
||||
" </SOAP-ENV:Body>" +
|
||||
"</SOAP-ENV:Envelope>";
|
||||
|
||||
static final private MessageContext axisMsgContext = new MessageContext(new AxisClient(new NullProvider()));
|
||||
|
||||
/*
|
||||
* 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 = identityToken.getEncodedToken();
|
||||
m_identityTokenType = identityToken.getProviderType();
|
||||
|
||||
m_lifetime = authTokenConfig.getSetting(AuthTokenConfig.TokenLifetime);
|
||||
m_lifetimeShorter = authTokenConfig.getSetting(AuthTokenConfig.LifetimeShorter);
|
||||
|
||||
// Create AuthTokenMessage
|
||||
Message authTokenMessage = getMessage(identityToken.getEncodedToken(),
|
||||
identityToken.getProviderType(),
|
||||
Integer.valueOf(m_lifetime).intValue(),
|
||||
svcConfig,
|
||||
(targetHost.compareTo("localhost") == 0) ? false : true);
|
||||
|
||||
// Un-comment the following line to print Authentication Token Messages
|
||||
//XMLUtils.PrettyElementToWriter(authTokenMessage.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
|
||||
|
||||
// Now save the message as a string
|
||||
OutputStream outStream = new ByteArrayOutputStream();
|
||||
authTokenMessage.writeTo(outStream);
|
||||
m_token = outStream.toString();
|
||||
outStream.close();
|
||||
}
|
||||
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,
|
||||
boolean encodedToken) throws Exception
|
||||
{
|
||||
// Decode the token string if necessary
|
||||
if (encodedToken)
|
||||
m_token = Base64Coder.decode(token);
|
||||
else
|
||||
m_token = token;
|
||||
|
||||
// Now instantiate a SOAP message with the string
|
||||
InputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
org.apache.axis.Message message;
|
||||
try
|
||||
{
|
||||
message = new Message(inStream);
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
System.err.println("AuthToken()- Exception caught creating message, msg: " + e.getMessage());
|
||||
throw new Exception("Invalid Authentication Token");
|
||||
}
|
||||
|
||||
// Get access to the SOAP Envelope
|
||||
SOAPEnvelope envelope = message.getSOAPEnvelope();
|
||||
|
||||
// Verify the message
|
||||
if (WSSecurity.verifyMessage(envelope))
|
||||
{
|
||||
// Message verification succeded, now obtain the identity token
|
||||
// and its type from the message body.
|
||||
SOAPBody body = (SOAPBody) envelope.getBody();
|
||||
QName authTokenElementName = new QName("auth_token");
|
||||
MessageElement authTokenElement = body.getChildElement(authTokenElementName);
|
||||
QName identTokenElementName = new QName("ident_token");
|
||||
MessageElement identTokenElement = authTokenElement.getChildElement(identTokenElementName);
|
||||
if (identTokenElement != null)
|
||||
{
|
||||
QName identTokenTypeElementName = new QName("type");
|
||||
MessageElement identTokenTypeElement = identTokenElement.getChildElement(identTokenTypeElementName);
|
||||
if (identTokenTypeElement != null)
|
||||
{
|
||||
m_identityToken = identTokenElement.getChildNodes().item(1).getNodeValue();
|
||||
m_identityTokenType = identTokenTypeElement.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_identityToken == null || m_identityTokenType == null)
|
||||
{
|
||||
System.out.println("AuthToken()- Required data missing from authentication token");
|
||||
throw new Exception("Error: Required data missing from Authentication Token");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message verification failed
|
||||
System.err.println("AuthToken()- Invalid Authentication Token");
|
||||
throw new Exception("Invalid Authentication Token");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get AuthToken SOAP Message
|
||||
*
|
||||
* @param identityToken String containing the identity token that should be part of the message
|
||||
* @param identityTokenType String containing the identity token type
|
||||
* @param lifetime Lifetime that should be specified in the message timestamp (seconds)
|
||||
* @param svcConfig Service configuration object
|
||||
* @param includeCert True if the message should include the Public Certificate
|
||||
* @return <code>Message<code> AuthToken message, null if the method fails.
|
||||
*/
|
||||
private Message getMessage(String identityToken,
|
||||
String identityTokenType,
|
||||
int lifetime,
|
||||
SvcConfig svcConfig,
|
||||
boolean includeCert)
|
||||
{
|
||||
Message secureMessage;
|
||||
|
||||
try
|
||||
{
|
||||
// Build SOAP Message with an identity token in the body
|
||||
//
|
||||
// First create a message and obtain its body
|
||||
InputStream inStream = new ByteArrayInputStream(authTokenSoapMsg.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
message.setMessageContext(axisMsgContext);
|
||||
SOAPBody body = (SOAPBody) message.getSOAPBody();
|
||||
|
||||
// Get access to the auth_token element
|
||||
QName authTokenElementName = new QName("auth_token");
|
||||
MessageElement authTokenElement = body.getChildElement(authTokenElementName);
|
||||
|
||||
// Get access to the ident_token element and set its value
|
||||
QName identTokenElementName = new QName("ident_token");
|
||||
MessageElement identTokenElement = authTokenElement.getChildElement(identTokenElementName);
|
||||
identTokenElement.addTextNode(identityToken);
|
||||
|
||||
// Get access to the identity token type element element and set its value
|
||||
QName identTokenTypeElementName = new QName("type");
|
||||
MessageElement identTokenTypeElement = identTokenElement.getChildElement(identTokenTypeElementName);
|
||||
identTokenTypeElement.setValue(identityTokenType);
|
||||
|
||||
// Now we need to secure the SOAP message that we created, we are doing to
|
||||
// do so by adding a timestamp and signing the timestamp as well as the body.
|
||||
// To do this we are going to leverage WS-Security.
|
||||
secureMessage = WSSecurity.secureSOAPEnvelope(message.getSOAPEnvelope(),
|
||||
lifetime,
|
||||
svcConfig,
|
||||
includeCert);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println("AuthToken.getMessage() - Exception caught building message, error: " + e.getMessage());
|
||||
secureMessage = null;
|
||||
}
|
||||
|
||||
return secureMessage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the Base64 encode token.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return Base64Coder.encode(m_token);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the lifetime of the token.
|
||||
*
|
||||
* Note: It is only valid to execute this procedure if its called on an object
|
||||
* instantiated via the constructor which takes a lifetime parameter.
|
||||
*/
|
||||
public String getLifetime() throws Exception
|
||||
{
|
||||
// Throw exeption if the lifetime parameter is not set
|
||||
if (m_lifetime.length() == 0)
|
||||
{
|
||||
System.out.println("AuthToken.getLifetime() - Called when lifetime is not set");
|
||||
throw new Exception("Error: Called getLifetime while not set");
|
||||
}
|
||||
|
||||
return Integer.toString(Integer.valueOf(m_lifetime).intValue() - Integer.valueOf(m_lifetimeShorter).intValue());
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token.
|
||||
*/
|
||||
public String getIdentityToken()
|
||||
{
|
||||
return m_identityToken;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token type.
|
||||
*/
|
||||
public String getIdentityTokenType()
|
||||
{
|
||||
return m_identityTokenType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Validates an authentication token. If successful it
|
||||
* returns a string containing the identity token associated
|
||||
* with the authentication token; otherwise it returns NULL;
|
||||
*
|
||||
* Note, the routine assumes that the token is not encoded.
|
||||
*/
|
||||
public static String validate(String authTokenString)
|
||||
{
|
||||
System.err.println("AuthToken.validate()- Start");
|
||||
// Instantiate the AuthToken, this validates the token itself.
|
||||
try
|
||||
{
|
||||
AuthToken authToken = new AuthToken(authTokenString, false);
|
||||
|
||||
// If we are here is because the token validation succeeded,
|
||||
// return the identity token string.
|
||||
System.err.println("AuthToken.validate()- Returning identity token");
|
||||
return authToken.getIdentityToken();
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// The validation of one of the tokens failed
|
||||
// tbd - Log
|
||||
System.err.println("AuthToken.validate()- Exception caught during token processing, msg: " + e.getMessage());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* AuthTokenConfig Class.
|
||||
*
|
||||
* This class obtains and maintains authentication token configuration.
|
||||
*
|
||||
*/
|
||||
public class AuthTokenConfig
|
||||
{
|
||||
// Well known authentication token configuration settings
|
||||
public final static String TokenLifetime = "TokenLifetime";
|
||||
public final static String LifetimeShorter = "LifetimeShorter";
|
||||
public final static String IdentityTokenType = "IdentityTokenType";
|
||||
|
||||
// Default configuration values
|
||||
private String m_defaultTokenLifetimeValue = "3600"; // Seconds
|
||||
private String m_defaultLifetimeShorterValue = "5"; // Seconds
|
||||
private String m_defaultIdentityTokenTypeValue = "CasaIdentityToken";
|
||||
|
||||
private Map m_tokenSettingsMap;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_SETTING_ELEMENT_START = 1;
|
||||
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
|
||||
private final static int AWAITING_SETTING_ELEMENT_END = 3;
|
||||
private final static int DONE_PARSING = 4;
|
||||
|
||||
private final static String m_rootElementName = "settings";
|
||||
|
||||
private Map m_keyMap;
|
||||
private int m_state;
|
||||
private String m_currentKey;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler(Map keyMap)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_keyMap = keyMap;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we are not in an invalid state
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
|
||||
throw new SAXException("Invalid state at endDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Keep track of the key name
|
||||
m_currentKey = qName;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at startElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_SETTING_ELEMENT_DATA:
|
||||
case AWAITING_SETTING_ELEMENT_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("AuthTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at endElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Consume the data if in the right state
|
||||
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
|
||||
{
|
||||
// Consume the data and add the key to map
|
||||
m_keyMap.put(m_currentKey, new String(ch, start, length));
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor which sets default configuration values.
|
||||
*/
|
||||
public AuthTokenConfig() throws Exception
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- Default");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
// Set the default settings in our map
|
||||
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
|
||||
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
|
||||
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public AuthTokenConfig(String authTokenSettingsFileName) throws Exception
|
||||
{
|
||||
System.err.println("AuthTokenConfig()-");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from the token settings file
|
||||
File f = new File(authTokenSettingsFileName);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
|
||||
// Parse the file
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
inStream.close();
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- " + authTokenSettingsFileName + " format error, exception: " + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- authtoken.settings format error");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- SecurityException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- Not able to access file");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- File " + authTokenSettingsFileName + " not found");
|
||||
throw new Exception("AuthTokenConfig()- File not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("AuthTokenConfig()- IOException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("AuthTokenConfig()- Read error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value associated with the specified setting.
|
||||
*/
|
||||
public String getSetting(String settingName) throws Exception
|
||||
{
|
||||
// Try to find the setting in our map
|
||||
String value = (String) m_tokenSettingsMap.get(settingName);
|
||||
if (value == null)
|
||||
{
|
||||
System.err.println("AuthTokenConfig.getSetting()- Did not find setting " + settingName);
|
||||
|
||||
// The setting is not in our map, check if it is one to
|
||||
// which we have defaults.
|
||||
if (settingName.equals(TokenLifetime) == true)
|
||||
{
|
||||
value = m_defaultTokenLifetimeValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
|
||||
}
|
||||
else if (settingName.equals(LifetimeShorter) == true)
|
||||
{
|
||||
value = m_defaultLifetimeShorterValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
|
||||
}
|
||||
else if (settingName.equals(IdentityTokenType) == true)
|
||||
{
|
||||
value = m_defaultLifetimeShorterValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("AuthTokenConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("AuthTokenConfig.getSetting()- Setting value = " + value);
|
||||
|
||||
// Do some sanity checking
|
||||
// tbd - Make sure that the token lifetime values are greater than the LifetimeShorter
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the creation and editing of authtoken.settings files.
|
||||
*
|
||||
**/
|
||||
public class AuthTokenSettingsEditor implements IVerifySetting
|
||||
{
|
||||
private static final String usage =
|
||||
"usage: AuthTokenSettingsEditor -op [settingName [settingValue]] -file settingsFilePath\n\n" +
|
||||
" where:\n" +
|
||||
" -op - Corresponds to one of the following operations:\n" +
|
||||
" -create - Create new authtoken settings file\n" +
|
||||
" -list - List settings\n" +
|
||||
" -get - Get settings, must be followed by settingName parameter\n" +
|
||||
" -set - Set settings, must be followed by settingName and settingValue parameters\n" +
|
||||
" -remove - Remove settings\n" +
|
||||
" -file - Path the the authtoken settings file\n" +
|
||||
" settingName - Name of the setting being retrieved or set\n" +
|
||||
" settingValue - Value of the setting being set\n\n" +
|
||||
" The following settings are valid:\n" +
|
||||
" TokenLifetime\n" +
|
||||
" LifetimeShorter\n";
|
||||
|
||||
private static final String settings =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<settings>\n" +
|
||||
"</settings>\n";
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @return True if the specified setting is valid.
|
||||
*/
|
||||
public boolean validSetting(String setting)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (setting.compareToIgnoreCase(AuthTokenConfig.TokenLifetime) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(AuthTokenConfig.LifetimeShorter) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(AuthTokenConfig.IdentityTokenType) == 0)
|
||||
result = true;
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid in conjunction
|
||||
* with the specified value.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @param value The value of the specified setting.
|
||||
* @return The formal name of the setting if found to be valid.
|
||||
*/
|
||||
public String validSettingNameAndValue(String setting,
|
||||
String value)
|
||||
{
|
||||
String validSetting = null;
|
||||
|
||||
if (setting.compareToIgnoreCase(AuthTokenConfig.TokenLifetime) == 0)
|
||||
{
|
||||
// Verify that we are dealing with a numeric value
|
||||
try
|
||||
{
|
||||
Integer.valueOf(value);
|
||||
|
||||
// Good
|
||||
validSetting = AuthTokenConfig.TokenLifetime;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.println("Invalid setting value specified");
|
||||
}
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(AuthTokenConfig.LifetimeShorter) == 0)
|
||||
{
|
||||
// Verify that we are dealing with a numeric value
|
||||
try
|
||||
{
|
||||
Integer.valueOf(value);
|
||||
|
||||
// Good
|
||||
validSetting = AuthTokenConfig.LifetimeShorter;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.println("Invalid setting value specified");
|
||||
}
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(AuthTokenConfig.IdentityTokenType) == 0)
|
||||
{
|
||||
// Always succeed
|
||||
validSetting = AuthTokenConfig.IdentityTokenType;
|
||||
}
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return validSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applications Entry Point
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String op = null;
|
||||
boolean opPerformed = false;
|
||||
boolean argumentsError = false;
|
||||
String filePath = null;
|
||||
String setting = null;
|
||||
String value = null;
|
||||
AuthTokenSettingsEditor editor = new AuthTokenSettingsEditor();
|
||||
|
||||
// Process the command line arguments
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
// Proceed based on the command
|
||||
if (args[i].compareToIgnoreCase("-file") == 0)
|
||||
{
|
||||
// The next argument should contain the filepath
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
filePath = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-list") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "list";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-create") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "create";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-get") == 0)
|
||||
{
|
||||
// Get setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "get";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-set") == 0)
|
||||
{
|
||||
// Set setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "set";
|
||||
|
||||
// The next two arguments should contain the setting name
|
||||
// and the setting value.
|
||||
if (args.length > (i + 2))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
value = args[i + 2];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-remove") == 0)
|
||||
{
|
||||
// Remove setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "remove";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed based on the specified parameters
|
||||
if (argumentsError == false)
|
||||
{
|
||||
if (filePath != null && op != null)
|
||||
{
|
||||
System.out.println("Dealing with settings file: " + filePath);
|
||||
|
||||
// Proceed based on the operation requested
|
||||
if (op.compareTo("list") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performListOperation(filePath);
|
||||
}
|
||||
else if (op.compareTo("create") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performCreateOperation(filePath, settings);
|
||||
}
|
||||
else if (op.compareTo("get") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performGetOperation(filePath, setting, editor);
|
||||
}
|
||||
else if (op.compareTo("set") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performSetOperation(filePath, setting, value, editor);
|
||||
}
|
||||
else if (op.compareTo("remove") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performRemoveOperation(filePath, setting, editor);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Tool error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the usage string if we encountered an error with the
|
||||
// command line arguments.
|
||||
if (argumentsError)
|
||||
System.out.print(usage);
|
||||
|
||||
// Set the exit code appropriatedly
|
||||
if (opPerformed)
|
||||
System.exit(0);
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
m_svcConfig);
|
||||
|
||||
// Write out the response
|
||||
String respLifetime = Integer.toString(Integer.valueOf(m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime)).intValue()
|
||||
- Integer.valueOf(m_svcConfig.getSetting(SvcConfig.LifetimeShorter)).intValue());
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||
ProtoDefs.httpOkStatusCode,
|
||||
sessionToken.toString(),
|
||||
respLifetime);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- identId not resolved");
|
||||
|
||||
// Write out the response
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||
ProtoDefs.httpUnauthorizedStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Unsupported mechanism " + authReqMsg.getMechanismId());
|
||||
|
||||
// Write out the response
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpNotFoundStatusMsg,
|
||||
ProtoDefs.httpNotFoundStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
AuthRespMsg authRespMsg = new AuthRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(authRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("Authenticate.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "Authenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* A Base64 Encoder/Decoder.
|
||||
*
|
||||
* This class is used to encode and decode data in Base64 format
|
||||
* as described in RFC 1521.
|
||||
*
|
||||
* <p>
|
||||
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br>
|
||||
* License: This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license.
|
||||
* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.<br>
|
||||
* Home page: <a href="http://www.source-code.biz" target="_top">www.source-code.biz</a><br>
|
||||
*
|
||||
* <p>
|
||||
* Version history:<br>
|
||||
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
|
||||
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
public class Base64Coder {
|
||||
|
||||
// Mapping table from 6-bit nibbles to Base64 characters.
|
||||
private static char[] map1 = new char[64];
|
||||
static {
|
||||
int i=0;
|
||||
for (char c='A'; c<='Z'; c++) map1[i++] = c;
|
||||
for (char c='a'; c<='z'; c++) map1[i++] = c;
|
||||
for (char c='0'; c<='9'; c++) map1[i++] = c;
|
||||
map1[i++] = '+'; map1[i++] = '/'; }
|
||||
|
||||
// Mapping table from Base64 characters to 6-bit nibbles.
|
||||
private static byte[] map2 = new byte[128];
|
||||
static {
|
||||
for (int i=0; i<map2.length; i++) map2[i] = -1;
|
||||
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
|
||||
|
||||
/**
|
||||
* Encodes a string into Base64 format.
|
||||
* No blanks or line breaks are inserted.
|
||||
* @param s a String to be encoded.
|
||||
* @return A String with the Base64 encoded data.
|
||||
*/
|
||||
public static String encode (String s) {
|
||||
return new String(encode(s.getBytes())); }
|
||||
|
||||
/**
|
||||
* Encodes a byte array into Base64 format.
|
||||
* No blanks or line breaks are inserted.
|
||||
* @param in an array containing the data bytes to be encoded.
|
||||
* @return A character array with the Base64 encoded data.
|
||||
*/
|
||||
public static char[] encode (byte[] in) {
|
||||
int iLen = in.length;
|
||||
int oDataLen = (iLen*4+2)/3; // output length without padding
|
||||
int oLen = ((iLen+2)/3)*4; // output length including padding
|
||||
char[] out = new char[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++] & 0xff;
|
||||
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
|
||||
int o0 = i0 >>> 2;
|
||||
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
|
||||
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
|
||||
int o3 = i2 & 0x3F;
|
||||
out[op++] = map1[o0];
|
||||
out[op++] = map1[o1];
|
||||
out[op] = op < oDataLen ? map1[o2] : '='; op++;
|
||||
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
|
||||
return out; }
|
||||
|
||||
/**
|
||||
* Decodes a Base64 string.
|
||||
* @param s a Base64 String to be decoded.
|
||||
* @return A String containing the decoded data.
|
||||
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||
*/
|
||||
public static String decode (String s) {
|
||||
return new String(decode(s.toCharArray())); }
|
||||
|
||||
/**
|
||||
* Decodes Base64 data.
|
||||
* No blanks or line breaks are allowed within the Base64 encoded data.
|
||||
* @param in a character array containing the Base64 encoded data.
|
||||
* @return An array containing the decoded data bytes.
|
||||
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
|
||||
*/
|
||||
public static byte[] decode (char[] in) {
|
||||
int iLen = in.length;
|
||||
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
|
||||
while (iLen > 0 && in[iLen-1] == '=') iLen--;
|
||||
int oLen = (iLen*3) / 4;
|
||||
byte[] out = new byte[oLen];
|
||||
int ip = 0;
|
||||
int op = 0;
|
||||
while (ip < iLen) {
|
||||
int i0 = in[ip++];
|
||||
int i1 = in[ip++];
|
||||
int i2 = ip < iLen ? in[ip++] : 'A';
|
||||
int i3 = ip < iLen ? in[ip++] : 'A';
|
||||
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
|
||||
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||
int b0 = map2[i0];
|
||||
int b1 = map2[i1];
|
||||
int b2 = map2[i2];
|
||||
int b3 = map2[i3];
|
||||
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
|
||||
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
|
||||
int o0 = ( b0 <<2) | (b1>>>4);
|
||||
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
|
||||
int o2 = ((b2 & 3)<<6) | b3;
|
||||
out[op++] = (byte)o0;
|
||||
if (op<oLen) out[op++] = (byte)o1;
|
||||
if (op<oLen) out[op++] = (byte)o2; }
|
||||
return out; }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
import org.bandit.ia.IAContext;
|
||||
|
||||
/*
|
||||
* CasaIdentityToken Class.
|
||||
*
|
||||
* This class constructs Casa Identity tokens.
|
||||
*
|
||||
* A Casa Identity Token is a simple XML Document
|
||||
* with information about an identity in the form
|
||||
* of:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <casa_ident_tok>
|
||||
* <id>identity id</id>
|
||||
* <source_name>identity data source name</source_name>
|
||||
* <source_url>identity data source url</source_url>
|
||||
* <target_service>target service name</target_service>
|
||||
* <target_host>target host name</target_host>
|
||||
* <attributes>
|
||||
* <attribute name>attribute value</attribute name>
|
||||
* <attribute2 name>attribute2 value</attribute name>
|
||||
* ...
|
||||
* </attributes>
|
||||
* </casa_ident_tok>
|
||||
*
|
||||
*
|
||||
* attribute/values pairs. The attribute names
|
||||
* being the XML elements of the documents.
|
||||
*
|
||||
*/
|
||||
public class CasaIdentityToken implements IdentityToken
|
||||
{
|
||||
/*
|
||||
* XML Element Name Constants for the documents exchanged between the
|
||||
* Casa Client and the Casa Server.
|
||||
*/
|
||||
private final static String casaIdentTokElementName = "casa_ident_tok";
|
||||
private final static String idElementName = "id";
|
||||
private final static String sourceNameElementName = "source_name";
|
||||
private final static String sourceUrlElementName = "source_url";
|
||||
private final static String targetServiceElementName = "target_service";
|
||||
private final static String targetHostElementName = "target_host";
|
||||
private final static String attributesElementName = "attributes";
|
||||
|
||||
private IdenTokenConfig m_idenTokenConfig;
|
||||
|
||||
private String m_identityId = null;
|
||||
private String m_sourceName = null;
|
||||
private String m_sourceUrl = null;
|
||||
private String m_service = null;
|
||||
private String m_host = null;
|
||||
private String m_token = null;
|
||||
private javax.naming.directory.Attributes m_attributes = null;
|
||||
|
||||
/*
|
||||
* Class for handling Authentication Request parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_ROOT_ELEMENT_END = 1;
|
||||
private final static int AWAITING_ID_ELEMENT_START = 2;
|
||||
private final static int AWAITING_ID_ELEMENT_END = 3;
|
||||
private final static int AWAITING_ID_DATA = 4;
|
||||
private final static int AWAITING_SOURCE_NAME_ELEMENT_START = 5;
|
||||
private final static int AWAITING_SOURCE_NAME_ELEMENT_END = 6;
|
||||
private final static int AWAITING_SOURCE_NAME_DATA = 7;
|
||||
private final static int AWAITING_SOURCE_URL_ELEMENT_START = 8;
|
||||
private final static int AWAITING_SOURCE_URL_ELEMENT_END = 9;
|
||||
private final static int AWAITING_SOURCE_URL_DATA = 10;
|
||||
private final static int AWAITING_TARGET_SERVICE_ELEMENT_START = 11;
|
||||
private final static int AWAITING_TARGET_SERVICE_ELEMENT_END = 12;
|
||||
private final static int AWAITING_TARGET_SERVICE_DATA = 13;
|
||||
private final static int AWAITING_TARGET_HOST_ELEMENT_START = 14;
|
||||
private final static int AWAITING_TARGET_HOST_ELEMENT_END = 15;
|
||||
private final static int AWAITING_TARGET_HOST_DATA = 16;
|
||||
private final static int AWAITING_ATTRIBUTES_ELEMENT_START = 17;
|
||||
private final static int AWAITING_ATTRIBUTE_START = 18;
|
||||
private final static int AWAITING_ATTRIBUTE_END = 19;
|
||||
private final static int AWAITING_ATTRIBUTE_DATA = 20;
|
||||
private final static int AWAITING_BINARY_ATTRIBUTE_DATA = 21;
|
||||
private final static int DONE_PARSING = 22;
|
||||
|
||||
private CasaIdentityToken m_casaIdentToken;
|
||||
private int m_state;
|
||||
private String m_currAttribute;
|
||||
private boolean m_encryptedAttrs;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler (CasaIdentityToken casaIdentityToken)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_casaIdentToken = casaIdentityToken;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we obtained all of the required elements
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endDocument()- Missing element");
|
||||
throw new SAXException("Missing element");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (casaIdentTokElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ID_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (idElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceNameElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceUrlElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetServiceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetHostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTES_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (attributesElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_START:
|
||||
// Save the element name as the current attribute
|
||||
m_currAttribute = qName;
|
||||
|
||||
// Advance to the next state based on the attribute type
|
||||
String attrType = atts.getValue("type");
|
||||
if (attrType != null && attrType.equals("binary"))
|
||||
{
|
||||
// We are dealing with a binary attribute. We are going to
|
||||
// assume that binary attributes are always base64 encoded.
|
||||
m_state = AWAITING_BINARY_ATTRIBUTE_DATA;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume we are dealing with an attribute of type string
|
||||
m_state = AWAITING_ATTRIBUTE_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ROOT_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (casaIdentTokElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ID_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (idElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceNameElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (sourceUrlElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetServiceElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_ELEMENT_END:
|
||||
// Verify that we are processing the expected tag
|
||||
if (targetHostElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTES_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_START;
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (attributesElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ROOT_ELEMENT_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("CasaIdentityToken SAXHandler.startElement()- State error");
|
||||
throw new SAXException("State error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
|
||||
case AWAITING_ID_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_identityId = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ID_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_NAME_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_sourceName = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_NAME_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_SOURCE_URL_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_sourceUrl = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SOURCE_URL_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_SERVICE_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_service = new String(ch, start, length);
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_SERVICE_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_TARGET_HOST_DATA:
|
||||
// Consume the data
|
||||
m_casaIdentToken.m_host = new String(ch, start, length);
|
||||
|
||||
// At this point we now have the target service and host names,
|
||||
// check if our configuration says that the attributes have been
|
||||
// encrypted.
|
||||
// tbd - Need to come up with a solution for obtaining configuration
|
||||
// information when instanstiated using a stream. May be the token should
|
||||
// carry an indication that the attributes are encrypted.
|
||||
m_encryptedAttrs = false;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_TARGET_HOST_ELEMENT_END;
|
||||
break;
|
||||
|
||||
case AWAITING_ATTRIBUTE_DATA:
|
||||
// Consume the data
|
||||
//
|
||||
// Decrypt the attribute data if necessary
|
||||
if (m_encryptedAttrs)
|
||||
{
|
||||
// tbd - Decrypt the attribute key and value with the private key of the service
|
||||
// using the configured mechanism.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_casaIdentToken.m_attributes.put(m_currAttribute, new String(ch, start, length));
|
||||
}
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_END;
|
||||
break;
|
||||
|
||||
case AWAITING_BINARY_ATTRIBUTE_DATA:
|
||||
// Consume the data
|
||||
//
|
||||
// Decrypt the attribute data if necessary
|
||||
if (m_encryptedAttrs)
|
||||
{
|
||||
// tbd - Decrypt the attribute key and value with the private key of the service
|
||||
// using the configured mechanism.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The data is base64 encoded
|
||||
char[] encodedChars = new char[length];
|
||||
System.arraycopy(ch, start, encodedChars, 0, length);
|
||||
m_casaIdentToken.m_attributes.put(m_currAttribute, Base64Coder.decode(encodedChars));
|
||||
}
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_ATTRIBUTE_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public CasaIdentityToken (IdenTokenConfig idenTokenConfig)
|
||||
{
|
||||
// Initialize our members
|
||||
m_token = null;
|
||||
m_attributes = new javax.naming.directory.BasicAttributes();
|
||||
m_idenTokenConfig = idenTokenConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public CasaIdentityToken ()
|
||||
{
|
||||
// Initialize our members
|
||||
m_token = null;
|
||||
m_attributes = new javax.naming.directory.BasicAttributes();
|
||||
m_idenTokenConfig = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize with parameters.
|
||||
*/
|
||||
public void initialize (String identityId,
|
||||
String sourceName,
|
||||
String targetService,
|
||||
String targetHost,
|
||||
SvcConfig svcConfig) throws Exception
|
||||
{
|
||||
// Save input parameters
|
||||
m_identityId = identityId;
|
||||
m_sourceName = sourceName;
|
||||
m_sourceUrl = "ldap://myldaphost.novell.com:389"; // tbd - Obtain from Identity Abstraction layer
|
||||
m_service = targetService;
|
||||
m_host = targetHost;
|
||||
|
||||
try
|
||||
{
|
||||
// Open a directory context and use it to read the identity attributes.
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env.put(IAContext.IA_REALM_CONFIG_LOCATION, svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env.put(IAContext.IA_REALM_SELECTOR, sourceName);
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
|
||||
// Setup a string buffer for building the IdentityToken, notice for now
|
||||
// we are not going to wrap the identity token.
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + casaIdentTokElementName + ">" + "\r\n");
|
||||
sb.append("<" + idElementName + ">" + identityId + "</" + idElementName + ">\r\n");
|
||||
sb.append("<" + sourceNameElementName + ">" + sourceName + "</" + sourceNameElementName + ">\r\n");
|
||||
sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "</" + sourceUrlElementName + ">\r\n");
|
||||
sb.append("<" + targetServiceElementName + ">" + m_service + "</" + targetServiceElementName + ">\r\n");
|
||||
sb.append("<" + targetHostElementName + ">" + m_host + "</" + targetHostElementName + ">\r\n");
|
||||
sb.append("<" + attributesElementName + ">" + "\r\n");
|
||||
|
||||
// Get the necessary attributes of the specified services in the identity token
|
||||
String[] attributesNeeded = m_idenTokenConfig.getAttributes();
|
||||
boolean encryptAttributes = "true".equals(m_idenTokenConfig.getSetting(IdenTokenConfig.EncryptAttributes));
|
||||
Attributes attrs = ctx.getAttributes(identityId, attributesNeeded);
|
||||
|
||||
// Now append the attributes to the token
|
||||
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
|
||||
{
|
||||
javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
|
||||
|
||||
NamingEnumeration enumeration = attr.getAll();
|
||||
while (enumeration.hasMore())
|
||||
{
|
||||
Object attrValue = enumeration.next();
|
||||
m_attributes.put(attr.getID(), attrValue);
|
||||
System.err.println("CasaIdentityToken.initialize()- Including attribute " + attr.getID());
|
||||
|
||||
// Encrypt the attribute if necessary
|
||||
if (encryptAttributes == true)
|
||||
{
|
||||
// tbd - Encrypt the attributes using the services public key, let the mechanism
|
||||
// be configurable. The service's certificate should be Base64 encoded as a setting
|
||||
// of the identoken.settings file.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proceed based on the attribute value type
|
||||
if (attrValue instanceof byte[])
|
||||
{
|
||||
// The attribute value is of type byte[], we need to encode it.
|
||||
sb.append("<" + attr.getID() + " type=\"binary\" encoding=\"base64\">" + new String(Base64Coder.encode((byte[]) attrValue)) + "</" + attr.getID() + ">" + "\r\n");
|
||||
System.err.println("Attribute " + attr.getID() + "included as " + new String(Base64Coder.encode((byte[]) attrValue)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume the attribute value is of type String
|
||||
sb.append("<" + attr.getID() + ">" + (String) attrValue + "</" + attr.getID() + ">" + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append("</" + attributesElementName + ">" + "\r\n");
|
||||
sb.append("</" + casaIdentTokElementName + ">" + "\r\n");
|
||||
|
||||
m_token = sb.toString();
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// tbd - Log the event???
|
||||
System.err.println("CasaIdentityToken.initialize()- Exception: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// tbd
|
||||
System.err.println("CasaIdentityToken.initialize()- Exception: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the token object with an ecoded token string.
|
||||
*/
|
||||
public void initialize (String encodedToken) throws Exception
|
||||
{
|
||||
// Save copy of the token
|
||||
m_token = Base64Coder.decode(encodedToken);
|
||||
|
||||
// Now parse the token into its elements
|
||||
try
|
||||
{
|
||||
// Parse the AuthReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
// tbd - Log this.
|
||||
System.err.println("CasaIdentityToken()- Parse exception: " + e.toString());
|
||||
throw new Exception("Token error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns encoded token string.
|
||||
*
|
||||
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||
* within it.
|
||||
*/
|
||||
public String getEncodedToken () throws Exception
|
||||
{
|
||||
if (m_token != null)
|
||||
{
|
||||
return Base64Coder.encode(m_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.toString()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing our type of identity token provider.
|
||||
*/
|
||||
public String getProviderType () throws Exception
|
||||
{
|
||||
// tbd - Change to a GUID
|
||||
return "CasaIdentityToken";
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity id.
|
||||
*/
|
||||
public String getIdentityId () throws Exception
|
||||
{
|
||||
if (m_identityId != null)
|
||||
return m_identityId;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getIdentityId()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the name associated with the
|
||||
* identity source.
|
||||
*/
|
||||
public String getSourceName () throws Exception
|
||||
{
|
||||
if (m_sourceName != null)
|
||||
return m_sourceName;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getSourceName()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the url associated with the
|
||||
* identity source.
|
||||
*/
|
||||
public String getSourceUrl () throws Exception
|
||||
{
|
||||
if (m_sourceUrl != null)
|
||||
return m_sourceUrl;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getSourceUrl()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the name of the targeted service.
|
||||
*/
|
||||
public String getTargetService () throws Exception
|
||||
{
|
||||
if (m_service != null)
|
||||
return m_service;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getTargetService()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containig the name of the host where the
|
||||
* targeted service resides.
|
||||
*/
|
||||
public String getTargetHost () throws Exception
|
||||
{
|
||||
if (m_host != null)
|
||||
return m_host;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getTargetHost()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the attributes of the identity.
|
||||
*/
|
||||
public javax.naming.directory.Attributes getAttributes () throws Exception
|
||||
{
|
||||
if (m_attributes != null)
|
||||
return m_attributes;
|
||||
else
|
||||
{
|
||||
System.err.println("CasaIdentityToken.getIdentityAttributes()- Not initialized");
|
||||
throw new Exception("Not initialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 boolean m_enabledSvcsOnly;
|
||||
|
||||
// Default auth policy, authtoken, and identtoken configs.
|
||||
byte[] m_defaultAuthPolicyData = null;
|
||||
AuthTokenConfig m_defaultAuthTokenConfig = null;
|
||||
IdenTokenConfig m_defaultIdenTokenConfig = null;
|
||||
|
||||
|
||||
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,
|
||||
boolean enabledSvcsOnly) throws Exception
|
||||
{
|
||||
System.err.println("EnabledSvcsConfig()-");
|
||||
System.err.println("EnabledSvcsConfig()- SvcConfigPath = " + svcConfigPath);
|
||||
|
||||
// Remember the enabledSvcsOnly setting
|
||||
m_enabledSvcsOnly = enabledSvcsOnly;
|
||||
|
||||
// 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);
|
||||
m_defaultAuthPolicyData = new byte[(int) f.length()];
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
int bytesRead = inStream.read(m_defaultAuthPolicyData);
|
||||
inStream.close();
|
||||
if (bytesRead != m_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
|
||||
{
|
||||
m_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.
|
||||
m_defaultAuthTokenConfig = new AuthTokenConfig();
|
||||
}
|
||||
|
||||
// Try to obtain the default identity token settings
|
||||
try
|
||||
{
|
||||
m_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.
|
||||
m_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)
|
||||
|| (m_defaultAuthPolicyData != null && m_defaultAuthPolicyData.length != 0))
|
||||
{
|
||||
// Instantiate SvcConfigEntry for this service and place it in our map
|
||||
SvcConfigEntry svcConfigEntry = new SvcConfigEntry((authPolicyData != null && authPolicyData.length != 0) ? authPolicyData : m_defaultAuthPolicyData,
|
||||
(authTokenConfig != null) ? authTokenConfig : m_defaultAuthTokenConfig,
|
||||
(idenTokenConfig != null) ? idenTokenConfig : m_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)
|
||||
{
|
||||
// Always return try if m_enabledSvcsOnly is configured "false" else
|
||||
// check the enabled svcs configuration.
|
||||
if (m_enabledSvcsOnly == false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
byte[] authPolicyData = null;
|
||||
|
||||
// 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)
|
||||
{
|
||||
authPolicyData = svcConfigEntry.m_authPolicyFileData;
|
||||
}
|
||||
}
|
||||
|
||||
// If m_enabledSvcsOnly is configured "false" and if no authentication policy
|
||||
// data was found for this service then return the default authentication policy
|
||||
// data.
|
||||
if (authPolicyData == null
|
||||
&& m_enabledSvcsOnly == false)
|
||||
{
|
||||
authPolicyData = m_defaultAuthPolicyData;
|
||||
}
|
||||
|
||||
return authPolicyData;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the authentication token configuration associated with the
|
||||
* specified service.
|
||||
*/
|
||||
public AuthTokenConfig getAuthTokenConfig(String hostName, String serviceName)
|
||||
{
|
||||
AuthTokenConfig authTokenConfig = null;
|
||||
|
||||
// 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)
|
||||
{
|
||||
authTokenConfig = svcConfigEntry.m_authTokenConfig;
|
||||
}
|
||||
}
|
||||
|
||||
// If m_enabledSvcsOnly is configured "false" and if no AuthTokenConfig
|
||||
// was found for this service then return the default AuthTokenConfig.
|
||||
if (authTokenConfig == null
|
||||
&& m_enabledSvcsOnly == false)
|
||||
{
|
||||
authTokenConfig = m_defaultAuthTokenConfig;
|
||||
}
|
||||
|
||||
return authTokenConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity token configuration associated with the
|
||||
* specified service.
|
||||
*/
|
||||
public IdenTokenConfig getIdenTokenConfig(String hostName, String serviceName)
|
||||
{
|
||||
IdenTokenConfig idenTokenConfig = null;
|
||||
|
||||
// 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)
|
||||
{
|
||||
idenTokenConfig = svcConfigEntry.m_idenTokenConfig;
|
||||
}
|
||||
}
|
||||
|
||||
// If m_enabledSvcsOnly is configured "false" and if no IdenTokenConfig
|
||||
// was found for this service then return the default IdenTokenConfig.
|
||||
if (idenTokenConfig == null
|
||||
&& m_enabledSvcsOnly == false)
|
||||
{
|
||||
idenTokenConfig = m_defaultIdenTokenConfig;
|
||||
}
|
||||
|
||||
return idenTokenConfig;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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());
|
||||
|
||||
System.err.println("GetAuthPolicy.invoke()- Service "
|
||||
+ getAuthPolicyReqMsg.getServiceName()
|
||||
+ " at " + getAuthPolicyReqMsg.getHostName()
|
||||
+ " not enabled");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthPolicyRespMsg getAuthPolicyRespMsg = new GetAuthPolicyRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(getAuthPolicyRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthPolicy.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "GetAuthPolicy";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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_SERVICE_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_GetAuthPolicyReqMsg.m_serviceName = m_GetAuthPolicyReqMsg.m_serviceName.concat(new String(ch, start, length));
|
||||
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;
|
||||
|
||||
case AWAITING_HOST_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_GetAuthPolicyReqMsg.m_hostName = m_GetAuthPolicyReqMsg.m_hostName.concat(new String(ch, start, length));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public GetAuthPolicyReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the GetAuthPolicyReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("GetAuthPolicyReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the service name.
|
||||
*/
|
||||
public String getServiceName() throws Exception
|
||||
{
|
||||
return m_serviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the host name.
|
||||
*/
|
||||
public String getHostName() throws Exception
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* GetAuthPolicyRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the Casa Client as a
|
||||
* response to a get authentication token request. The format of
|
||||
* the message is as follows when the response includes an
|
||||
* authentication token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_policy_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <auth_policy>authentication policy data</auth_policy>
|
||||
* </get_auth_policy_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include an authentication token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_policy_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </get_auth_policy_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class GetAuthPolicyRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the authentication policy.
|
||||
*/
|
||||
public GetAuthPolicyRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the authentication policy.
|
||||
*/
|
||||
public GetAuthPolicyRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String authPolicy) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the GetAuthPolicyRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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_SERVICE_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_serviceName = m_GetAuthTokReqMsg.m_serviceName.concat(new String(ch, start, length));
|
||||
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_HOST_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_hostName = m_GetAuthTokReqMsg.m_hostName.concat(new String(ch, start, length));
|
||||
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;
|
||||
|
||||
case AWAITING_SESSION_TOKEN_ELEMENT_END:
|
||||
// Consume the data
|
||||
m_GetAuthTokReqMsg.m_sessionToken = m_GetAuthTokReqMsg.m_sessionToken.concat(new String(ch, start, length));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public GetAuthTokReqMsg (InputStream inStream) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Parse the GetAuthTokReqMsg
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(this);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("GetAuthTokReqMsg()- Parse exception: " + e.toString());
|
||||
throw new Exception("Protocol error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the service name.
|
||||
*/
|
||||
public String getServiceName() throws Exception
|
||||
{
|
||||
return m_serviceName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the host name.
|
||||
*/
|
||||
public String getHostName() throws Exception
|
||||
{
|
||||
return m_hostName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the session token.
|
||||
*/
|
||||
public String getSessionToken() throws Exception
|
||||
{
|
||||
return m_sessionToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
* GetAuthTokRespMsg Class.
|
||||
*
|
||||
* This class deals with the message sent to the Casa Client as a
|
||||
* response to a get authentication token request. The format of
|
||||
* the message is as follows when the response includes an
|
||||
* authentication token:
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_tok_resp>
|
||||
* <status><description>OK</description>200</status>
|
||||
* <auth_token><lifetime>lifetime value</lifetime>authentication token data</auth_token>
|
||||
* </get_auth_tok_resp>
|
||||
*
|
||||
* The format of the message is as follows when the response does not
|
||||
* include an authentication token.
|
||||
*
|
||||
* <?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
* <get_auth_tok_resp>
|
||||
* <status><description>status description</description>status code</status>
|
||||
* </get_auth_tok_resp>
|
||||
*
|
||||
* Plase note that the protocol utilizes the status codes defined
|
||||
* in the HTTP 1.1 Specification.
|
||||
*
|
||||
*/
|
||||
public class GetAuthTokRespMsg
|
||||
{
|
||||
|
||||
String m_msg;
|
||||
|
||||
/*
|
||||
* Constructor for a msg that does not include the authentication token.
|
||||
*/
|
||||
public GetAuthTokRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor for a msg that includes the authentication token.
|
||||
*/
|
||||
public GetAuthTokRespMsg (
|
||||
String statusDescription,
|
||||
String statusCode,
|
||||
String authToken,
|
||||
String authTokenLifetime) throws Exception
|
||||
{
|
||||
// Get a StringBuffer to help us with the construction of the message
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
// Start building the message
|
||||
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
|
||||
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.statusElementName + ">"
|
||||
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
|
||||
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
|
||||
sb.append("<" + ProtoDefs.authTokenElementName + ">"
|
||||
+ "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
|
||||
+ authToken + "</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
|
||||
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
|
||||
|
||||
// The message has now been built, save it.
|
||||
m_msg = sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the GetAuthTokRespMsg.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return m_msg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* GetAuthToken Class.
|
||||
*
|
||||
* This class processes requests for tokens to authenticate an entity
|
||||
* to a particular service.
|
||||
*
|
||||
*/
|
||||
public class GetAuthToken implements RpcMethod
|
||||
{
|
||||
private SvcConfig m_svcConfig;
|
||||
private EnabledSvcsConfig m_enabledSvcsConfig;
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public GetAuthToken() throws Exception
|
||||
{
|
||||
// Nothing to do at this time
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the Rpc method.
|
||||
*/
|
||||
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
|
||||
{
|
||||
m_svcConfig = svcConfig;
|
||||
m_enabledSvcsConfig = enabledSvcsConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process Rpc.
|
||||
*/
|
||||
public void invoke(InputStream inStream, PrintWriter out) throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()");
|
||||
|
||||
// Parse the GetAuthTokReqMsg sent from the client
|
||||
GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
|
||||
|
||||
// Verify that the service is enabled
|
||||
if (m_enabledSvcsConfig.svcEnabled(getAuthTokReqMsg.getHostName(),
|
||||
getAuthTokReqMsg.getServiceName()))
|
||||
{
|
||||
// Now create a session token (This validates the session token provided).
|
||||
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
|
||||
|
||||
try
|
||||
{
|
||||
// Create the Authentication Token
|
||||
AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
|
||||
sessionToken.getRealm(),
|
||||
getAuthTokReqMsg.getServiceName(),
|
||||
getAuthTokReqMsg.getHostName(),
|
||||
m_svcConfig,
|
||||
m_enabledSvcsConfig);
|
||||
|
||||
// Write out the response
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
|
||||
ProtoDefs.httpOkStatusCode,
|
||||
authToken.toString(),
|
||||
authToken.getLifetime());
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
|
||||
ProtoDefs.httpUnauthorizedStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The service has not been enabled to utilize our authentication tokens
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpNotFoundStatusMsg,
|
||||
ProtoDefs.httpNotFoundStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
|
||||
|
||||
// Write out the response
|
||||
try
|
||||
{
|
||||
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
|
||||
ProtoDefs.httpServerErrorStatusCode);
|
||||
out.println(getAuthTokRespMsg.toString());
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "GetAuthToken";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface exported by users of the SettingsFileUtil class.
|
||||
*
|
||||
*/
|
||||
public interface IVerifySetting
|
||||
{
|
||||
/**
|
||||
* Checks if the specified setting is valid.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @return True if the specified setting is valid.
|
||||
*/
|
||||
boolean validSetting(String setting);
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid in conjunction
|
||||
* with the specified value.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @param value The value of the specified setting.
|
||||
* @return The formal name of the setting if found to be valid.
|
||||
*/
|
||||
String validSettingNameAndValue(String setting,
|
||||
String value);
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
/**
|
||||
* IdenTokenConfig Class.
|
||||
*
|
||||
* This class obtains and maintains identity token configuration.
|
||||
*
|
||||
*/
|
||||
public class IdenTokenConfig
|
||||
{
|
||||
// Well known identity token configuration settings
|
||||
public final static String EncryptAttributes = "EncryptAttributes";
|
||||
public final static String Attributes = "Attributes";
|
||||
|
||||
// Default configuration values
|
||||
private String m_defaultEncryptAttributesValue = "false";
|
||||
private String m_defaultAttributesValue = "sn";
|
||||
|
||||
private Map m_tokenSettingsMap;
|
||||
private String[] m_identityAttributes;
|
||||
|
||||
/*
|
||||
* Class for handling parsing events.
|
||||
*/
|
||||
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
|
||||
{
|
||||
private final static int AWAITING_ROOT_ELEMENT_START = 0;
|
||||
private final static int AWAITING_SETTING_ELEMENT_START = 1;
|
||||
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
|
||||
private final static int AWAITING_SETTING_ELEMENT_END = 3;
|
||||
private final static int DONE_PARSING = 4;
|
||||
|
||||
private final static String m_rootElementName = "settings";
|
||||
|
||||
private Map m_keyMap;
|
||||
private int m_state;
|
||||
private String m_currentKey;
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SAXHandler(Map keyMap)
|
||||
{
|
||||
super();
|
||||
|
||||
// Initialize our members
|
||||
m_keyMap = keyMap;
|
||||
m_state = AWAITING_ROOT_ELEMENT_START;
|
||||
}
|
||||
|
||||
/*
|
||||
* endDocument() implementation.
|
||||
*/
|
||||
public void endDocument () throws SAXException
|
||||
{
|
||||
// Verify that we are not in an invalid state
|
||||
if (m_state != DONE_PARSING)
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
|
||||
throw new SAXException("Invalid state at endDocument");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* startElement() implementation.
|
||||
*/
|
||||
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_ROOT_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.startElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Keep track of the key name
|
||||
m_currentKey = qName;
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("IdenTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at startElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endElement() immplementation.
|
||||
*/
|
||||
public void endElement (String uri, String name, String qName) throws SAXException
|
||||
{
|
||||
// Proceed based on our state
|
||||
switch (m_state)
|
||||
{
|
||||
case AWAITING_SETTING_ELEMENT_DATA:
|
||||
case AWAITING_SETTING_ELEMENT_END:
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_START;
|
||||
break;
|
||||
|
||||
case AWAITING_SETTING_ELEMENT_START:
|
||||
// Verify that we are processing the expected tag
|
||||
if (m_rootElementName.equals(qName))
|
||||
{
|
||||
// Advance to the next state
|
||||
m_state = DONE_PARSING;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig SAXHandler.endElement()- Un-expected element");
|
||||
throw new SAXException("Un-expected element");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("IdenTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
|
||||
throw new SAXException("Invalid state at endElement");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* character() implementation.
|
||||
*/
|
||||
public void characters (char ch[], int start, int length) throws SAXException
|
||||
{
|
||||
// Consume the data if in the right state
|
||||
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
|
||||
{
|
||||
// Consume the data and add the key to map
|
||||
// tbd - Add code to aggregate attributes specified as multiple elements
|
||||
m_keyMap.put(m_currentKey, new String(ch, start, length));
|
||||
|
||||
// Advance to the next state
|
||||
m_state = AWAITING_SETTING_ELEMENT_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor which sets default configuration values.
|
||||
*/
|
||||
public IdenTokenConfig() throws Exception
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- Default");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
// Set the default settings in our map
|
||||
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor.
|
||||
*/
|
||||
public IdenTokenConfig(String idenTokenSettingsFileName) throws Exception
|
||||
{
|
||||
System.err.println("IdenTokenConfig()-");
|
||||
|
||||
// Create a map to keep track of the token settings
|
||||
m_tokenSettingsMap = new HashMap();
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from the token settings file
|
||||
File f = new File(idenTokenSettingsFileName);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
|
||||
// Parse the file
|
||||
XMLReader xr = XMLReaderFactory.createXMLReader();
|
||||
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
|
||||
xr.setContentHandler(handler);
|
||||
xr.setErrorHandler(handler);
|
||||
|
||||
InputSource source = new InputSource(inStream);
|
||||
xr.parse(source);
|
||||
|
||||
inStream.close();
|
||||
|
||||
// Process the specified attributes
|
||||
if (m_tokenSettingsMap.containsKey(Attributes) == false)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- Attributes not configured, defaulting them.");
|
||||
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
|
||||
}
|
||||
String attributes = (String) m_tokenSettingsMap.get(Attributes);
|
||||
m_identityAttributes = attributes.split(",");
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- " + idenTokenSettingsFileName + " format error, exception: " + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- authtoken.settings format error");
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- SecurityException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- Not able to access file");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- File " + idenTokenSettingsFileName + " not found");
|
||||
throw new Exception("IdenTokenConfig()- File not found");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("IdenTokenConfig()- IOException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
|
||||
throw new Exception("IdenTokenConfig()- Read error");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the value associated with the specified setting.
|
||||
*/
|
||||
public String getSetting(String settingName) throws Exception
|
||||
{
|
||||
// Try to find the setting in our map
|
||||
String value = (String) m_tokenSettingsMap.get(settingName);
|
||||
if (value == null)
|
||||
{
|
||||
System.err.println("IdenTokenConfig.getSetting()- Did not find setting " + settingName);
|
||||
|
||||
// The setting is not in our map, check if it is one to
|
||||
// which we have defaults.
|
||||
if (settingName.equals(EncryptAttributes) == true)
|
||||
{
|
||||
value = m_defaultEncryptAttributesValue;
|
||||
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
|
||||
|
||||
// Add the key to the map so that it can be found quicker next time
|
||||
m_tokenSettingsMap.put(EncryptAttributes, m_defaultEncryptAttributesValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("IdenTokenConfig.getSetting()- Found setting " + settingName);
|
||||
System.err.println("IdenTokenConfig.getSetting()- Setting value = " + value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the identity attributes that must be included in the token.
|
||||
*/
|
||||
public String[] getAttributes() throws Exception
|
||||
{
|
||||
return m_identityAttributes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the creation and editing of identtoken.settings files.
|
||||
*
|
||||
**/
|
||||
public class IdenTokenSettingsEditor implements IVerifySetting
|
||||
{
|
||||
private static final String usage =
|
||||
"usage: IdenTokenSettingsEditor -op [settingName [settingValue]] -file settingsFilePath\n\n" +
|
||||
" where:\n" +
|
||||
" -op - Corresponds to one of the following operations:\n" +
|
||||
" -create - Create new identoken settings file\n" +
|
||||
" -list - List settings\n" +
|
||||
" -get - Get settings, must be followed by settingName parameter\n" +
|
||||
" -set - Set settings, must be followed by settingName and settingValue parameters\n" +
|
||||
" -remove - Remove settings\n" +
|
||||
" -file - Path the the identoken settings file\n" +
|
||||
" settingName - Name of the setting being retrieved or set\n" +
|
||||
" settingValue - Value of the setting being set\n\n" +
|
||||
" The following settings are valid:\n" +
|
||||
" Attributes\n";
|
||||
|
||||
private static final String settings =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<settings>\n" +
|
||||
"</settings>\n";
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @return True if the specified setting is valid.
|
||||
*/
|
||||
public boolean validSetting(String setting)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (setting.compareToIgnoreCase(IdenTokenConfig.EncryptAttributes) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(IdenTokenConfig.Attributes) == 0)
|
||||
result = true;
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid in conjunction
|
||||
* with the specified value.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @param value The value of the specified setting.
|
||||
* @return The formal name of the setting if found to be valid.
|
||||
*/
|
||||
public String validSettingNameAndValue(String setting,
|
||||
String value)
|
||||
{
|
||||
String validSetting = null;
|
||||
|
||||
if (setting.compareToIgnoreCase(IdenTokenConfig.EncryptAttributes) == 0)
|
||||
{
|
||||
// Always succeed
|
||||
validSetting = IdenTokenConfig.EncryptAttributes;
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(IdenTokenConfig.Attributes) == 0)
|
||||
{
|
||||
// Always succeed
|
||||
validSetting = IdenTokenConfig.Attributes;
|
||||
}
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return validSetting;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applications Entry Point
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String op = null;
|
||||
boolean opPerformed = false;
|
||||
boolean argumentsError = false;
|
||||
String filePath = null;
|
||||
String setting = null;
|
||||
String value = null;
|
||||
IdenTokenSettingsEditor editor = new IdenTokenSettingsEditor();
|
||||
|
||||
// Process the command line arguments
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
// Proceed based on the command
|
||||
if (args[i].compareToIgnoreCase("-file") == 0)
|
||||
{
|
||||
// The next argument should contain the filepath
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
filePath = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-list") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "list";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-create") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "create";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-get") == 0)
|
||||
{
|
||||
// Get setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "get";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-set") == 0)
|
||||
{
|
||||
// Set setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "set";
|
||||
|
||||
// The next two arguments should contain the setting name
|
||||
// and the setting value.
|
||||
if (args.length > (i + 2))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
value = args[i + 2];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-remove") == 0)
|
||||
{
|
||||
// Remove setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "remove";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed based on the specified parameters
|
||||
if (argumentsError == false)
|
||||
{
|
||||
if (filePath != null && op != null)
|
||||
{
|
||||
System.out.println("Dealing with settings file: " + filePath);
|
||||
|
||||
// Proceed based on the operation requested
|
||||
if (op.compareTo("list") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performListOperation(filePath);
|
||||
}
|
||||
else if (op.compareTo("create") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performCreateOperation(filePath, settings);
|
||||
}
|
||||
else if (op.compareTo("get") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performGetOperation(filePath, setting, editor);
|
||||
}
|
||||
else if (op.compareTo("set") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performSetOperation(filePath, setting, value, editor);
|
||||
}
|
||||
else if (op.compareTo("remove") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performRemoveOperation(filePath, setting, editor);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Tool error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the usage string if we encountered an error with the
|
||||
// command line arguments.
|
||||
if (argumentsError)
|
||||
System.out.print(usage);
|
||||
|
||||
// Set the exit code appropriatedly
|
||||
if (opPerformed)
|
||||
System.exit(0);
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* IdentityToken Interface.
|
||||
*
|
||||
* This is the interface implemented by Identity Token Providers.
|
||||
*/
|
||||
public interface IdentityToken
|
||||
{
|
||||
/*
|
||||
* Initialize the token with parameters.
|
||||
*/
|
||||
void initialize(String identityId,
|
||||
String sourceName,
|
||||
String targetService,
|
||||
String targetHost,
|
||||
SvcConfig svcConfig) throws Exception;
|
||||
|
||||
/*
|
||||
* Initialize the token object with encoded token string.
|
||||
*/
|
||||
void initialize(String encodedToken) throws Exception;
|
||||
|
||||
/*
|
||||
* Returns encoded token string.
|
||||
*
|
||||
* IMPORTANT: The token string can not contain the substring "]]>"
|
||||
* within it.
|
||||
*/
|
||||
String getEncodedToken() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity token provider type.
|
||||
*/
|
||||
String getProviderType() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the identity id.
|
||||
*/
|
||||
String getIdentityId() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the name associated with the
|
||||
* identity source.
|
||||
*/
|
||||
String getSourceName() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the url associated with the
|
||||
* identity source.
|
||||
*/
|
||||
String getSourceUrl() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containing the name of the targeted service.
|
||||
*/
|
||||
String getTargetService() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns a string containig the name of the host where the
|
||||
* targeted service resides.
|
||||
*/
|
||||
String getTargetHost() throws Exception;
|
||||
|
||||
/*
|
||||
* Returns the attributes of the identity.
|
||||
*/
|
||||
javax.naming.directory.Attributes getAttributes() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 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(AuthMechConfig.Krb5ServicePrincipalName);
|
||||
if (servicePrincipal != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Make sure that the system property "javax.security.auth.useSubjectCredsOnly"
|
||||
// is set to "false" to avoid having to utilize JAAS (at least if using IBM's JVM)
|
||||
System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
|
||||
|
||||
// Initalize our GSS variables
|
||||
//
|
||||
// Get an instance of the default GSSManager
|
||||
m_manager = GSSManager.getInstance();
|
||||
|
||||
// Create an OID specifying the Krb5 mechanism
|
||||
m_krb5 = new Oid("1.2.840.113554.1.2.2");
|
||||
|
||||
// Create our host based service name
|
||||
m_svcName = m_manager.createName(servicePrincipal,
|
||||
GSSName.NT_HOSTBASED_SERVICE,
|
||||
m_krb5);
|
||||
|
||||
// Now acquire our credentials
|
||||
m_credential = m_manager.createCredential(m_svcName,
|
||||
GSSCredential.INDEFINITE_LIFETIME,
|
||||
m_krb5,
|
||||
GSSCredential.ACCEPT_ONLY);
|
||||
}
|
||||
catch (GSSException e)
|
||||
{
|
||||
System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage());
|
||||
throw new Exception("Failed to instantiate needed GSS objects");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Krb5Authenticate()- Service Principal Name not configured");
|
||||
throw new Exception("Service Principal Name not configured");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* invoke() implementation.
|
||||
*/
|
||||
public String invoke(AuthReqMsg authReqMsg) throws Exception
|
||||
{
|
||||
String identId = null;
|
||||
|
||||
try
|
||||
{
|
||||
System.err.println("Krb5Authenticate.invoke()");
|
||||
|
||||
// Now parse the Kerberos Token
|
||||
Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this);
|
||||
|
||||
// Open a directory context and use it to identify the users
|
||||
// associated with the specified surname.
|
||||
Hashtable env = new Hashtable();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
|
||||
// Now search for a user with a matching kerberos principal name.
|
||||
//
|
||||
// Set up a search control so that the search is scoped to the sub-tree
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
|
||||
// Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit
|
||||
String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext);
|
||||
if (searchContext == null)
|
||||
{
|
||||
// A start search context was not configured, start from the root.
|
||||
searchContext = "";
|
||||
}
|
||||
|
||||
// Perform the search
|
||||
NamingEnumeration answer = ctx.search(searchContext,
|
||||
"(krbPrincipalName={0})",
|
||||
new String[] {krb5Token.getPrincipalName()},
|
||||
controls);
|
||||
|
||||
// Proceed based on the result of the search
|
||||
if (answer.hasMore())
|
||||
{
|
||||
// The search succeeded, set the identity id.
|
||||
SearchResult sr = (SearchResult)answer.next();
|
||||
if (searchContext.equals(""))
|
||||
{
|
||||
identId = sr.getNameInNamespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
identId = sr.getName() + "," + searchContext;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Krb5Authenticate.invoke()- No matching identity entities found");
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// Log the error
|
||||
System.err.println("Krb5Authenticate.invoke()- NamingException: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Krb5Authenticate.invoke()- Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Return the authentication result
|
||||
return identId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "Krb5Authenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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>
|
||||
</settings>
|
||||
@@ -0,0 +1,70 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
JAVAFILES = ProtoDefs.java \
|
||||
AuthMechConfig.java \
|
||||
SvcConfig.java \
|
||||
IdenTokenConfig.java \
|
||||
AuthTokenConfig.java \
|
||||
EnabledSvcsConfig.java \
|
||||
AuthMechanism.java \
|
||||
Authenticate.java \
|
||||
RpcMethod.java \
|
||||
Rpc.java \
|
||||
GetAuthPolicy.java \
|
||||
Base64Coder.java \
|
||||
AuthReqMsg.java \
|
||||
AuthRespMsg.java \
|
||||
IdentityToken.java \
|
||||
CasaIdentityToken.java \
|
||||
AuthToken.java \
|
||||
GetAuthPolicyReqMsg.java \
|
||||
GetAuthPolicyRespMsg.java \
|
||||
GetAuthToken.java \
|
||||
GetAuthTokReqMsg.java \
|
||||
GetAuthTokRespMsg.java \
|
||||
Krb5Authenticate.java \
|
||||
PwdAuthenticate.java \
|
||||
SessionToken.java \
|
||||
WSSecurity.java \
|
||||
AuthPolicyEditor.java \
|
||||
AuthTokenSettingsEditor.java \
|
||||
IdenTokenSettingsEditor.java \
|
||||
IVerifySetting.java \
|
||||
SettingsFileUtil.java \
|
||||
SvcSettingsEditor.java
|
||||
|
||||
EXTRA_DIST = $(JAVAFILES) \
|
||||
Krb5_mechanism.settings \
|
||||
Pwd_mechanism.settings
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
/*
|
||||
* ProDefs Class.
|
||||
*
|
||||
* This class contains constants utilized in the Casa Client/Server
|
||||
* protocol.
|
||||
*
|
||||
*/
|
||||
public class ProtoDefs
|
||||
{
|
||||
|
||||
/*
|
||||
* XML Declaration used in the Casa Client/Server protocol
|
||||
*/
|
||||
public final static String xmlDeclaration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||
|
||||
/*
|
||||
* XML Element Name Constants for the documents exchanged between the
|
||||
* Casa Client and the Casa Server.
|
||||
*/
|
||||
public final static String authRequestElementName = "auth_req";
|
||||
public final static String authResponseElementName = "auth_resp";
|
||||
public final static String getAuthPolicyRequestElementName = "get_auth_policy_req";
|
||||
public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp";
|
||||
public final static String getAuthTokRequestElementName = "get_auth_tok_req";
|
||||
public final static String getAuthTokResponseElementName = "get_auth_tok_resp";
|
||||
public final static String authMechTokenElementName = "auth_mech_token";
|
||||
public final static String statusElementName = "status";
|
||||
public final static String sessionTokenElementName = "session_token";
|
||||
public final static String authTokenElementName = "auth_token";
|
||||
public final static String authPolicyElementName = "auth_policy";
|
||||
public final static String identTokenElementName = "ident_token";
|
||||
public final static String lifetimeElementName = "lifetime";
|
||||
public final static String signatureElementName = "signature";
|
||||
public final static String typeElementName = "type";
|
||||
public final static String descriptionElementName = "description";
|
||||
public final static String serviceElementName = "service";
|
||||
public final static String hostElementName = "host";
|
||||
public final static String identIdElementName = "ident_id";
|
||||
public final static String realmElementName = "realm";
|
||||
public final static String authSourceElementName = "auth_source";
|
||||
public final static String mechanismElementName = "mechanism";
|
||||
public final static String mechanismInfoElementName = "mechanism_info";
|
||||
|
||||
/*
|
||||
* Configurable operating parameters
|
||||
*/
|
||||
public String sessionTokenLifetime = "360";
|
||||
|
||||
/*
|
||||
* HTTP Status Codes and Messages
|
||||
*/
|
||||
public final static String httpOkStatusCode = "200";
|
||||
public final static String httpOkStatusMsg = "OK";
|
||||
public final static String httpUnauthorizedStatusCode = "401";
|
||||
public final static String httpUnauthorizedStatusMsg = "Unauthorized";
|
||||
public final static String httpNotFoundStatusCode = "404";
|
||||
public final static String httpNotFoundStatusMsg = "Not Found";
|
||||
public final static String httpServerErrorStatusCode = "500";
|
||||
public final static String httpServerErrorStatusMsg = "Internal Server Error";
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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);
|
||||
if (!answer.hasMore())
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- No matching identity entities found");
|
||||
}
|
||||
|
||||
// Enumerate through the users returned checking the password
|
||||
while (answer.hasMore())
|
||||
{
|
||||
SearchResult sr = (SearchResult)answer.next();
|
||||
|
||||
// Open a directory context for the user as a way of verifying its password
|
||||
try
|
||||
{
|
||||
Hashtable env2 = new Hashtable();
|
||||
env2.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory");
|
||||
env2.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile));
|
||||
env2.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm());
|
||||
env2.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
env2.put(Context.SECURITY_PRINCIPAL, sr.getNameInNamespace());
|
||||
env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword());
|
||||
|
||||
if ((new InitialDirContext(env2)) != null)
|
||||
{
|
||||
// The password must be valid, set the identity Id.
|
||||
if (searchContext.equals(""))
|
||||
{
|
||||
identId = sr.getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
identId = sr.getName() + "," + searchContext;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- NamingException: " + e.getExplanation());
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we did not resolve the identity
|
||||
if (identId == null)
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- Failed to resolve identity for entity " + pwToken.getUsername());
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
// Log the error
|
||||
System.err.println("PwdAuthenticate.invoke()- NamingException on Proxy User: " + e.getExplanation());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("PwdAuthenticate.invoke()- Exception: " + e.toString());
|
||||
}
|
||||
|
||||
// Return the authentication result
|
||||
return identId;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the mechanism id.
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return "PwdAuthenticate";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<settings>
|
||||
<description>This is the authentication mechanism for the PwdAuthenticate scheme. The PwdAuthenticate scheme authenticates entities using username/password tokens.</description>
|
||||
<ClassName>com.novell.casa.authtoksvc.PwdAuthenticate</ClassName>
|
||||
<RelativeClassPath>WEB-INF/classes</RelativeClassPath>
|
||||
</settings>
|
||||
@@ -0,0 +1,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.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;
|
||||
|
||||
private boolean m_enabledSvcsOnly;
|
||||
|
||||
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, m_enabledSvcsOnly);
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
// Check if we support services that are not explicitedly enabled
|
||||
String enabledSvcsOnly = System.getProperty("com.novell.casa.authtoksvc.enabled_svcs_only");
|
||||
if (enabledSvcsOnly != null
|
||||
&& enabledSvcsOnly.compareToIgnoreCase("true") == 0)
|
||||
{
|
||||
m_enabledSvcsOnly = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_enabledSvcsOnly = false;
|
||||
}
|
||||
|
||||
// Configure ourselves
|
||||
configureServlet();
|
||||
|
||||
// Check if we must start a thread to periodically reconfigure ourselves
|
||||
if (m_reconfigureInterval != 0)
|
||||
{
|
||||
m_reconfigureThread = new ReconfigureThread(this);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Rpc.init()- Exception caught: " + e.toString());
|
||||
throw new ServletException("Exception caught while instantiating Rpc methods");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy() implementation.
|
||||
*/
|
||||
public void destroy ()
|
||||
{
|
||||
super.destroy();
|
||||
|
||||
System.err.println("Rpc.destroy()");
|
||||
|
||||
// Stop our re-configure thread
|
||||
if (m_reconfigureThread != null)
|
||||
{
|
||||
m_reconfigureThread.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* doGet() implementation.
|
||||
*/
|
||||
protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
/*
|
||||
* doPost() implementation.
|
||||
*/
|
||||
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
// Get ready to send back a reply
|
||||
response.setContentType("text/html");
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
try
|
||||
{
|
||||
// Obtain the input stream and execute the requested method
|
||||
InputStream inStream = request.getInputStream();
|
||||
|
||||
String requestedMethod = request.getParameter("method");
|
||||
if (requestedMethod != null)
|
||||
{
|
||||
// Get the necessary method
|
||||
RpcMethod method = (RpcMethod) m_methodsMap.get(requestedMethod);
|
||||
if (method != null)
|
||||
{
|
||||
// Invoke the method to process the Rpc
|
||||
method.invoke(inStream, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unsupported method
|
||||
System.err.println("Rpc.doPost()- Unsupported method");
|
||||
response.sendError(response.SC_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing method parameter
|
||||
System.err.println("Rpc.doPost()- Missing method parameter");
|
||||
response.sendError(response.SC_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// tbd
|
||||
System.err.println("Rpc.doPost()- Exception caught: " + e.toString());
|
||||
response.sendError(response.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// Done sending out the reply
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, Novell, Inc.
|
||||
*
|
||||
* To contact Novell about this file by physical or electronic mail,
|
||||
* you may find current contact information at www.novell.com.
|
||||
*
|
||||
* Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
package com.novell.casa.authtoksvc;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/*
|
||||
* RpcMethod Interface.
|
||||
*
|
||||
* This is the interface implemented by Rpc Methods.
|
||||
*/
|
||||
public interface RpcMethod
|
||||
{
|
||||
/*
|
||||
* Initialize the Rpc method.
|
||||
*/
|
||||
void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception;
|
||||
|
||||
/*
|
||||
* Process Rpc.
|
||||
*/
|
||||
void invoke(InputStream inStream, PrintWriter out) throws IOException;
|
||||
|
||||
/*
|
||||
* Return the method id.
|
||||
*/
|
||||
String getId();
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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.apache.axis.Message;
|
||||
import org.apache.axis.MessageContext;
|
||||
import org.apache.axis.client.AxisClient;
|
||||
import org.apache.axis.configuration.NullProvider;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.axis.message.SOAPBody;
|
||||
import org.apache.axis.message.MessageElement;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.*;
|
||||
|
||||
/*
|
||||
* SessionToken class.
|
||||
*
|
||||
* This class constructs sessions tokens that clients can present to an ATS
|
||||
* to prove that an entity has been authenticated to a particular realm.
|
||||
* The session token consists of a SOAP message secured with WSSecurity
|
||||
* with the appropriate elements signed and with a timestamp. The body of
|
||||
* the SOAP message is as follows:
|
||||
*
|
||||
* <session_token>
|
||||
* <realm>realm value</realm>
|
||||
* <ident_id>identity id value</ident_id>
|
||||
* </session_token>
|
||||
*
|
||||
*/
|
||||
public class SessionToken
|
||||
{
|
||||
|
||||
private String m_id = null;
|
||||
private String m_realm = null;
|
||||
private String m_token;
|
||||
|
||||
static final String sessionTokenSoapMsg =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<SOAP-ENV:Envelope" +
|
||||
" xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
|
||||
" <SOAP-ENV:Body>" +
|
||||
" <session_token><realm></realm><ident_id></ident_id></session_token>" +
|
||||
" </SOAP-ENV:Body>" +
|
||||
"</SOAP-ENV:Envelope>";
|
||||
|
||||
static final private MessageContext axisMsgContext = new MessageContext(new AxisClient(new NullProvider()));
|
||||
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
public SessionToken(String id,
|
||||
String realm,
|
||||
String lifetime,
|
||||
SvcConfig svcConfig) throws Exception
|
||||
{
|
||||
// Save copies of the input parameters
|
||||
m_id = id;
|
||||
m_realm = realm;
|
||||
|
||||
// Create SessionTokenMessage
|
||||
Message sessionTokenMessage = getMessage(realm,
|
||||
id,
|
||||
Integer.valueOf(lifetime).intValue(),
|
||||
svcConfig);
|
||||
|
||||
// Now save the message as a string
|
||||
OutputStream outStream = new ByteArrayOutputStream();
|
||||
sessionTokenMessage.writeTo(outStream);
|
||||
m_token = outStream.toString();
|
||||
outStream.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 instantiate a SOAP message with the string
|
||||
InputStream inStream = new ByteArrayInputStream(m_token.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
|
||||
// Get access to the SOAP Envelope
|
||||
SOAPEnvelope envelope = message.getSOAPEnvelope();
|
||||
|
||||
// Verify the message
|
||||
if (WSSecurity.verifyMessage(envelope))
|
||||
{
|
||||
// Message verification succeded, now obtain the realm and identity id
|
||||
// from the message body.
|
||||
SOAPBody body = (SOAPBody) envelope.getBody();
|
||||
QName sessionTokenElementName = new QName("session_token");
|
||||
MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName);
|
||||
QName realmElementName = new QName("realm");
|
||||
MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName);
|
||||
if (realmElement != null)
|
||||
{
|
||||
m_realm = realmElement.getChildNodes().item(0).getNodeValue();
|
||||
}
|
||||
QName identIdElementName = new QName("ident_id");
|
||||
MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName);
|
||||
if (identIdElement != null)
|
||||
{
|
||||
m_id = identIdElement.getChildNodes().item(0).getNodeValue();
|
||||
}
|
||||
|
||||
if (m_realm == null || m_id == null)
|
||||
{
|
||||
System.out.println("SessionToken()- Required data missing from session token");
|
||||
throw new Exception("Error: Required data missing from session Token");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message verification failed
|
||||
System.err.println("SessionToken()- Invalid Session Token");
|
||||
throw new Exception("Invalid Session Token");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SessionToken SOAP Message
|
||||
*
|
||||
* @param realm String containing the identity token that should be part of the message
|
||||
* @param identityId String containing the identity token type
|
||||
* @param lifetime Lifetime that should be specified in the message timestamp (seconds)
|
||||
* @param svcConfig Service Config object
|
||||
* @return <code>Message<code> SessionToken message, null if the method fails.
|
||||
*/
|
||||
private Message getMessage(String realm,
|
||||
String identityId,
|
||||
int lifetime,
|
||||
SvcConfig svcConfig)
|
||||
{
|
||||
Message secureMessage;
|
||||
|
||||
try
|
||||
{
|
||||
// Build SOAP Message with an identity token in the body
|
||||
//
|
||||
// First create a message and obtain its body
|
||||
InputStream inStream = new ByteArrayInputStream(sessionTokenSoapMsg.getBytes());
|
||||
Message message = new Message(inStream);
|
||||
message.setMessageContext(axisMsgContext);
|
||||
SOAPBody body = (SOAPBody) message.getSOAPBody();
|
||||
|
||||
// Get access to the session_token element
|
||||
QName sessionTokenElementName = new QName("session_token");
|
||||
MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName);
|
||||
|
||||
// Get access to the realm element and set its value
|
||||
QName realmElementName = new QName("realm");
|
||||
MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName);
|
||||
realmElement.addTextNode(realm);
|
||||
|
||||
// Get access to the ident_id element and set its value
|
||||
QName identIdElementName = new QName("ident_id");
|
||||
MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName);
|
||||
identIdElement.addTextNode(identityId);
|
||||
|
||||
// Now we need to secure the SOAP message that we created, we are doing to
|
||||
// do so by adding a timestamp and signing the timestamp as well as the body.
|
||||
// To do this we are going to leverage WS-Security.
|
||||
secureMessage = WSSecurity.secureSOAPEnvelope(message.getSOAPEnvelope(),
|
||||
lifetime,
|
||||
svcConfig,
|
||||
false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println("SessionToken.getMessage() - Exception caught building message, error: " + e.getMessage());
|
||||
secureMessage = null;
|
||||
}
|
||||
|
||||
return secureMessage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a string containing the session token.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return Base64Coder.encode(m_token);
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the Identity Id
|
||||
*/
|
||||
public String getIdentId() throws Exception
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method to get the Identity Repository Reference (Realm).
|
||||
*/
|
||||
public String getRealm() throws Exception
|
||||
{
|
||||
return m_realm;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 org.apache.xerces.parsers.DOMParser;
|
||||
import org.apache.xml.serialize.OutputFormat;
|
||||
import org.apache.xml.serialize.XMLSerializer;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the creation and editing of settings files.
|
||||
*
|
||||
**/
|
||||
public class SettingsFileUtil
|
||||
{
|
||||
/**
|
||||
* Gets document for the specified settings file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @return Document representation of the settings file.
|
||||
*/
|
||||
private static Document getSettingsFileDoc(String filePath)
|
||||
{
|
||||
Document doc = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Get an input stream to read from settings file
|
||||
File f = new File(filePath);
|
||||
FileInputStream inStream = new FileInputStream(f);
|
||||
InputSource source = new InputSource(inStream);
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.parse(source);
|
||||
doc = parser.getDocument();
|
||||
|
||||
inStream.close();
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
System.err.println("Settings file " + filePath + " not found");
|
||||
doc = null;
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.err.println("SecurityException accessing " + filePath);
|
||||
doc = null;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.err.println("IOException accessing " + filePath + " Exception=" + e.toString());
|
||||
doc = null;
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
System.err.println("Settings file " + filePath + " format error");
|
||||
doc = null;
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a starting settings document
|
||||
*
|
||||
* @param settings String with starting settings document.
|
||||
* @return Starting settings document.
|
||||
*/
|
||||
private static Document getSettingsDoc(String settings)
|
||||
{
|
||||
Document doc = null;
|
||||
|
||||
try
|
||||
{
|
||||
StringReader reader = new StringReader(settings);
|
||||
InputSource source = new InputSource(reader);
|
||||
|
||||
DOMParser parser = new DOMParser();
|
||||
parser.parse(source);
|
||||
doc = parser.getDocument();
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Program error, exception: " + e.toString());
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all of the settings present in the specified file.
|
||||
*
|
||||
* @param filePath` Path to the settings file.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
public static boolean performListOperation(String filePath)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// List the settings present in the file
|
||||
Document doc = getSettingsFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Go through the elements of the document
|
||||
Element root = doc.getDocumentElement();
|
||||
Node child;
|
||||
Node next = root.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
System.out.println(child.getLocalName() + "=" + child.getTextContent());
|
||||
}
|
||||
}
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create settings file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @param settings String containing an settings document.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
public static boolean performCreateOperation(String filePath,
|
||||
String settings)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// create a settings file
|
||||
Document doc = getSettingsDoc(settings);
|
||||
if (doc != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
File f = new File(filePath);
|
||||
boolean createStatus = f.createNewFile();
|
||||
if (createStatus == true)
|
||||
{
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
OutputFormat format = new OutputFormat(doc);
|
||||
XMLSerializer serializer = new XMLSerializer(out, format);
|
||||
serializer.serialize(doc.getDocumentElement());
|
||||
out.close();
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("File " + filePath + " already exists");
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Error creating file " + filePath + ", exception: " + e.toString());
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("SecurityException creating " + filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets value of the specified setting in the specified settings file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @param setting Name of the setting being queried.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
public static boolean performGetOperation(String filePath,
|
||||
String setting,
|
||||
IVerifySetting settingVerifier)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Validate the setting name specified
|
||||
if (settingVerifier.validSetting(setting))
|
||||
{
|
||||
// Get settings present in the file
|
||||
Document doc = getSettingsFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Go through the elements of the document until
|
||||
// we find the one specified.
|
||||
Element root = doc.getDocumentElement();
|
||||
Node child;
|
||||
Node next = root.getFirstChild();
|
||||
boolean settingFound = false;
|
||||
while ((child = next) != null
|
||||
&& settingFound == false)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE
|
||||
&& child.getLocalName().compareToIgnoreCase(setting) == 0)
|
||||
{
|
||||
System.out.println(child.getLocalName() + "=" + child.getTextContent());
|
||||
settingFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingFound == false)
|
||||
System.out.println("Not set");
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified setting in the specified settings file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @param setting`` Name of the setting to be set.
|
||||
* @param value Value to be assigned to the setting.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
public static boolean performSetOperation(String filePath,
|
||||
String setting,
|
||||
String value,
|
||||
IVerifySetting settingVerifier)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Validate specified setting name and value
|
||||
String formalSetting;
|
||||
if ((formalSetting = settingVerifier.validSettingNameAndValue(setting, value)) != null)
|
||||
{
|
||||
// Get settings present in the file
|
||||
Document doc = getSettingsFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Go through the elements of the document until
|
||||
// we find the one specified.
|
||||
Element root = doc.getDocumentElement();
|
||||
Node child;
|
||||
Node next = (Node) root.getFirstChild();
|
||||
boolean settingFound = false;
|
||||
while ((child = next) != null
|
||||
&& settingFound == false)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE
|
||||
&& child.getLocalName().compareToIgnoreCase(setting) == 0)
|
||||
{
|
||||
// Change the value of the setting
|
||||
child.setTextContent(value);
|
||||
settingFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (settingFound == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
Element element = doc.createElement(formalSetting);
|
||||
element.setTextContent(value);
|
||||
root.appendChild(element);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.err.println("Exception caught " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Update the file after removing the text nodes
|
||||
try
|
||||
{
|
||||
// Remove text nodes
|
||||
next = (Node) root.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// Remove the node
|
||||
root.removeChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Update file
|
||||
File f = new File(filePath);
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
OutputFormat format = new OutputFormat(doc);
|
||||
XMLSerializer serializer = new XMLSerializer(out, format);
|
||||
serializer.serialize(doc.getDocumentElement());
|
||||
out.close();
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Error writing to file " + filePath + ", exception: " + e.toString());
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("SecurityException writting to file " + filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove specified setting from the specified settings file.
|
||||
*
|
||||
* @param filePath Path to the settings file.
|
||||
* @param setting Name of the setting to be removed.
|
||||
* @return True if the operation is successfully performed.
|
||||
*/
|
||||
public static boolean performRemoveOperation(String filePath,
|
||||
String setting,
|
||||
IVerifySetting settingVerifier)
|
||||
{
|
||||
boolean opPerformed = false;
|
||||
|
||||
// Validate specified setting name
|
||||
if (settingVerifier.validSetting(setting))
|
||||
{
|
||||
// Get settings present in the file
|
||||
Document doc = getSettingsFileDoc(filePath);
|
||||
if (doc != null)
|
||||
{
|
||||
// Go through the elements of the document until
|
||||
// we find the one specified.
|
||||
Element root = doc.getDocumentElement();
|
||||
Node child;
|
||||
Node next = (Node) root.getFirstChild();
|
||||
boolean settingFound = false;
|
||||
while ((child = next) != null
|
||||
&& settingFound == false)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.ELEMENT_NODE
|
||||
&& child.getLocalName().compareToIgnoreCase(setting) == 0)
|
||||
{
|
||||
// Remove the element from the document
|
||||
root.removeChild(child);
|
||||
settingFound = true;
|
||||
|
||||
// Update the file after removing the text nodes
|
||||
try
|
||||
{
|
||||
// Remove text nodes
|
||||
next = (Node) root.getFirstChild();
|
||||
while ((child = next) != null)
|
||||
{
|
||||
next = child.getNextSibling();
|
||||
if (child.getNodeType() == Node.TEXT_NODE)
|
||||
{
|
||||
// Remove the node
|
||||
root.removeChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Update file
|
||||
File f = new File(filePath);
|
||||
FileOutputStream out = new FileOutputStream(f);
|
||||
OutputFormat format = new OutputFormat(doc);
|
||||
XMLSerializer serializer = new XMLSerializer(out, format);
|
||||
serializer.serialize(doc.getDocumentElement());
|
||||
out.close();
|
||||
|
||||
opPerformed = true;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println("Error writing to file " + filePath + ", exception: " + e.toString());
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("SecurityException writting to file " + filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingFound == false)
|
||||
{
|
||||
// Succeed anyway
|
||||
opPerformed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return opPerformed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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";
|
||||
public final static String SigningKeyAliasName = "SigningKeyAliasName";
|
||||
public final static String SigningKeyPassword = "SigningKeyPassword";
|
||||
|
||||
// Default configuration values
|
||||
public final static String DefaultSessionTokenLifetimeValue = "43200"; // Seconds
|
||||
public final static String DefaultLifetimeShorterValue = "5"; // Seconds
|
||||
public final static String DefaultReconfigureIntervalValue = "60"; // Seconds
|
||||
public final static String DefaultSigningKeyAliasNameValue = "signingKey";
|
||||
public final static String DefaultSigningKeyPasswordValue = "secret";
|
||||
|
||||
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(SigningKeyAliasName) == true)
|
||||
{
|
||||
value = DefaultSigningKeyAliasNameValue;
|
||||
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(SigningKeyAliasName, DefaultSigningKeyAliasNameValue);
|
||||
}
|
||||
else if (settingName.equals(SigningKeyPassword) == true)
|
||||
{
|
||||
value = DefaultSigningKeyPasswordValue;
|
||||
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(SigningKeyPassword, DefaultSigningKeyPasswordValue);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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.File;
|
||||
|
||||
/**
|
||||
*
|
||||
* Class for the creation and editing of svc.settings files.
|
||||
*
|
||||
**/
|
||||
public class SvcSettingsEditor implements IVerifySetting
|
||||
{
|
||||
private static final String usage =
|
||||
"usage: SvcSettingsEditor -op [settingName [settingValue]] -file settingsFilePath\n\n" +
|
||||
" where:\n" +
|
||||
" -op - Corresponds to one of the following operations:\n" +
|
||||
" -create - Create new svc settings file\n" +
|
||||
" -list - List settings\n" +
|
||||
" -get - Get settings, must be followed by settingName parameter\n" +
|
||||
" -set - Set settings, must be followed by settingName and settingValue parameters\n" +
|
||||
" -remove - Remove settings\n" +
|
||||
" -file - Path the the svc settings file\n" +
|
||||
" settingName - Name of the setting being retrieved or set\n" +
|
||||
" settingValue - Value of the setting being set\n\n" +
|
||||
" The following settings are valid:\n" +
|
||||
" SessionTokenLifetime\n" +
|
||||
" LifetimeShorter\n" +
|
||||
" IAConfigFile\n" +
|
||||
" ReconfigureInterval\n" +
|
||||
" SigningKeyAliasName\n" +
|
||||
" SigningKeyPassword\n";
|
||||
|
||||
private static final String settings =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<settings>\n" +
|
||||
" <IAConfigFile>/etc/CASA/authtoken/svc/iaRealms.xml</IAConfigFile>\n" +
|
||||
"</settings>\n";
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @return True if the specified setting is valid.
|
||||
*/
|
||||
public boolean validSetting(String setting)
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
if (setting.compareToIgnoreCase(SvcConfig.SessionTokenLifetime) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.LifetimeShorter) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.IdentityAbstractionConfigFile) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.ReconfigureInterval) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyAliasName) == 0)
|
||||
result = true;
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyPassword) == 0)
|
||||
result = true;
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified setting is valid in conjunction
|
||||
* with the specified value.
|
||||
*
|
||||
* @param setting The name of the setting being checked.
|
||||
* @param value The value of the specified setting.
|
||||
* @return The formal name of the setting if found to be valid.
|
||||
*/
|
||||
public String validSettingNameAndValue(String setting,
|
||||
String value)
|
||||
{
|
||||
String validSetting = null;
|
||||
|
||||
if (setting.compareToIgnoreCase(SvcConfig.SessionTokenLifetime) == 0)
|
||||
{
|
||||
// Verify that we are dealing with a numeric value
|
||||
try
|
||||
{
|
||||
Integer.valueOf(value);
|
||||
|
||||
// Good
|
||||
validSetting = SvcConfig.SessionTokenLifetime;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.println("Invalid setting value specified");
|
||||
}
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.LifetimeShorter) == 0)
|
||||
{
|
||||
// Verify that we are dealing with a numeric value
|
||||
try
|
||||
{
|
||||
Integer.valueOf(value);
|
||||
|
||||
// Good
|
||||
validSetting = SvcConfig.LifetimeShorter;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.println("Invalid setting value specified");
|
||||
}
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.IdentityAbstractionConfigFile) == 0)
|
||||
{
|
||||
// Output a warning if the specified file does not exist
|
||||
try
|
||||
{
|
||||
File f = new File(value);
|
||||
if (f.exists() == false)
|
||||
{
|
||||
System.out.println("Warning: File " + value + " does not exist");
|
||||
}
|
||||
}
|
||||
catch (SecurityException e)
|
||||
{
|
||||
System.out.println("Warning: Not able to access file " + value);
|
||||
}
|
||||
|
||||
// Always succeed
|
||||
validSetting = SvcConfig.IdentityAbstractionConfigFile;
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.ReconfigureInterval) == 0)
|
||||
{
|
||||
// Verify that we are dealing with a numeric value
|
||||
try
|
||||
{
|
||||
Integer.valueOf(value);
|
||||
|
||||
// Good
|
||||
validSetting = SvcConfig.ReconfigureInterval;
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
System.out.println("Invalid setting value specified");
|
||||
}
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyAliasName) == 0)
|
||||
{
|
||||
validSetting = SvcConfig.SigningKeyAliasName;
|
||||
}
|
||||
else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyPassword) == 0)
|
||||
{
|
||||
validSetting = SvcConfig.SigningKeyPassword;
|
||||
}
|
||||
else
|
||||
System.out.println("Invalid setting specified");
|
||||
|
||||
return validSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applications Entry Point
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String op = null;
|
||||
boolean opPerformed = false;
|
||||
boolean argumentsError = false;
|
||||
String filePath = null;
|
||||
String setting = null;
|
||||
String value = null;
|
||||
SvcSettingsEditor editor = new SvcSettingsEditor();
|
||||
|
||||
// Process the command line arguments
|
||||
for (int i = 0; i < args.length; i++)
|
||||
{
|
||||
// Proceed based on the command
|
||||
if (args[i].compareToIgnoreCase("-file") == 0)
|
||||
{
|
||||
// The next argument should contain the filepath
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
filePath = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-list") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "list";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-create") == 0)
|
||||
{
|
||||
// List operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "create";
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-get") == 0)
|
||||
{
|
||||
// Get setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "get";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-set") == 0)
|
||||
{
|
||||
// Set setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "set";
|
||||
|
||||
// The next two arguments should contain the setting name
|
||||
// and the setting value.
|
||||
if (args.length > (i + 2))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
value = args[i + 2];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (args[i].compareToIgnoreCase("-remove") == 0)
|
||||
{
|
||||
// Remove setting operation requested
|
||||
if (op == null)
|
||||
{
|
||||
op = "remove";
|
||||
|
||||
// The next argument should contain the setting name
|
||||
if (args.length > (i + 1))
|
||||
{
|
||||
setting = args[i + 1];
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Proceed based on the specified parameters
|
||||
if (argumentsError == false)
|
||||
{
|
||||
if (filePath != null && op != null)
|
||||
{
|
||||
System.out.println("Dealing with settings file: " + filePath);
|
||||
|
||||
// Proceed based on the operation requested
|
||||
if (op.compareTo("list") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performListOperation(filePath);
|
||||
}
|
||||
else if (op.compareTo("create") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performCreateOperation(filePath, settings);
|
||||
}
|
||||
else if (op.compareTo("get") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performGetOperation(filePath, setting, editor);
|
||||
}
|
||||
else if (op.compareTo("set") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performSetOperation(filePath, setting, value, editor);
|
||||
}
|
||||
else if (op.compareTo("remove") == 0)
|
||||
{
|
||||
opPerformed = SettingsFileUtil.performRemoveOperation(filePath, setting, editor);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Tool error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
argumentsError = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the usage string if we encountered an error with the
|
||||
// command line arguments.
|
||||
if (argumentsError)
|
||||
System.out.print(usage);
|
||||
|
||||
// Set the exit code appropriatedly
|
||||
if (opPerformed)
|
||||
System.exit(0);
|
||||
else
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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.apache.axis.Message;
|
||||
import org.apache.axis.message.SOAPEnvelope;
|
||||
import org.apache.ws.security.*;
|
||||
import org.apache.ws.security.components.crypto.Crypto;
|
||||
import org.apache.ws.security.components.crypto.CryptoFactory;
|
||||
import org.apache.ws.security.message.WSSecHeader;
|
||||
import org.apache.ws.security.message.WSSecSignature;
|
||||
import org.apache.ws.security.message.WSSecTimestamp;
|
||||
import org.apache.xml.security.c14n.Canonicalizer;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.xml.soap.MessageFactory;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
|
||||
/*
|
||||
* WSSecurity Class.
|
||||
*
|
||||
* This class provides static methods for securing and verifying SOAP messages. SOAP messages
|
||||
* are secured by adding a timestamp and signing the appropriate elements using methods and
|
||||
* headers defined by WS* specifications.
|
||||
*
|
||||
*/
|
||||
public class WSSecurity
|
||||
{
|
||||
static final private WSSecurityEngine secEngine = new WSSecurityEngine();
|
||||
static final private Crypto crypto = CryptoFactory.getInstance();
|
||||
|
||||
/**
|
||||
* Creates a SOAP message from a document.
|
||||
*
|
||||
*/
|
||||
private static Message toSOAPMessage(Document doc) throws Exception
|
||||
{
|
||||
Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
|
||||
byte[] canonicalMessage = c14n.canonicalizeSubtree(doc);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(canonicalMessage);
|
||||
MessageFactory factory = MessageFactory.newInstance();
|
||||
return (org.apache.axis.Message) factory.createMessage(null, in);
|
||||
}
|
||||
|
||||
/***
|
||||
* Returns the first element that containes an Id with value
|
||||
* <code>uri</code> and <code>namespace</code>.
|
||||
* <p/>
|
||||
*
|
||||
* Copyright Note: The code for this function was copied from file
|
||||
* WSSecurityUtil.java from package org.apache.ws.security.util.
|
||||
* The Copyright notice on this file is as follows:
|
||||
*
|
||||
* Copyright 2003-2006 The Apache Software Foundation, or their licensors, as
|
||||
* appropriate.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @param startNode Where to start the search
|
||||
* @param value Value of the Id attribute
|
||||
* @param namespace Namespace URI of the Id
|
||||
* @return The found element or <code>null</code>
|
||||
*/
|
||||
private static Element findElementById(Node startNode,
|
||||
String value,
|
||||
String namespace)
|
||||
{
|
||||
// Just return null if startNode is set to null
|
||||
if (startNode == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Node startParent = startNode.getParentNode();
|
||||
Node processedNode;
|
||||
while (startNode != null)
|
||||
{
|
||||
// start node processing at this point
|
||||
if (startNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
Element se = (Element) startNode;
|
||||
if (se.hasAttributeNS(namespace, "Id")
|
||||
&& value.equals(se.getAttributeNS(namespace, "Id")))
|
||||
{
|
||||
return se;
|
||||
}
|
||||
}
|
||||
|
||||
processedNode = startNode;
|
||||
startNode = startNode.getFirstChild();
|
||||
|
||||
// no child, this node is done.
|
||||
if (startNode == null)
|
||||
{
|
||||
// close node processing, get sibling
|
||||
startNode = processedNode.getNextSibling();
|
||||
}
|
||||
|
||||
// no more siblings, get parent, all children
|
||||
// of parent are processed.
|
||||
while (startNode == null)
|
||||
{
|
||||
processedNode = processedNode.getParentNode();
|
||||
if (processedNode == startParent)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// close parent node processing (processed node now)
|
||||
startNode = processedNode.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies SOAP envelope timestamp and signatures.
|
||||
*
|
||||
* @param envelope SOAP envelope with timestamp
|
||||
* @return <code>boolean</code> True if verification succeeds
|
||||
* @throws Exception on error
|
||||
*/
|
||||
public static boolean verifyMessage(SOAPEnvelope envelope) throws Exception
|
||||
{
|
||||
boolean msgVerificationStatus = false;
|
||||
|
||||
try
|
||||
{
|
||||
boolean timeStampProcessed = false;
|
||||
boolean signatureProcessed = false;
|
||||
Vector<WSSecurityEngineResult> results;
|
||||
Document signedDoc = envelope.getAsDocument();
|
||||
results = secEngine.processSecurityHeader(signedDoc, null, null, crypto);
|
||||
if (results != null)
|
||||
{
|
||||
for (WSSecurityEngineResult result : results)
|
||||
{
|
||||
if (result.getAction() == WSConstants.TS)
|
||||
{
|
||||
timeStampProcessed = true;
|
||||
}
|
||||
else if (result.getAction() == WSConstants.SIGN)
|
||||
{
|
||||
// A signature was processed, verify that the signature was over the timestamp
|
||||
// and the body.
|
||||
boolean timeStampSigned = false;
|
||||
boolean bodySigned = false;
|
||||
Set signedElements = result.getSignedElements();
|
||||
for (Object signedElement : signedElements)
|
||||
{
|
||||
String elementId = (String) signedElement;
|
||||
Element element = findElementById(signedDoc.getDocumentElement(), elementId, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
|
||||
if (element != null)
|
||||
{
|
||||
if ("wsu:Timestamp".equalsIgnoreCase(element.getNodeName()))
|
||||
{
|
||||
timeStampSigned = true;
|
||||
}
|
||||
else if ("SOAP-ENV:Body".equalsIgnoreCase(element.getNodeName()))
|
||||
{
|
||||
bodySigned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeStampSigned && bodySigned)
|
||||
{
|
||||
signatureProcessed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timeStampProcessed && signatureProcessed)
|
||||
{
|
||||
System.out.println("WSSecurity.verifyMessage() - Validation succeded");
|
||||
msgVerificationStatus = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("WSSecurity.verifyMessage() - validation failed");
|
||||
}
|
||||
}
|
||||
catch (WSSecurityException e)
|
||||
{
|
||||
System.out.println("WSSecurity.verifyMessage() - Verification failed with error:" + e.getMessage() + " code = " + e.getErrorCode());
|
||||
}
|
||||
|
||||
return msgVerificationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add timestamp and sign SOAP message in compliance with WS-Security.
|
||||
*
|
||||
* @param envelope String containing a SOAP envelope
|
||||
* @param timeToLive Value to set the timestamp timeToLive parameter in seconds
|
||||
* @param svcConfig Service Config object
|
||||
* @param includeCert True if the message should include the Public Certificate
|
||||
* @return <code>Message</code> Signed and timestamped SOAP message
|
||||
* @throws Exception on error
|
||||
*/
|
||||
public static Message secureSOAPEnvelope(SOAPEnvelope envelope,
|
||||
int timeToLive,
|
||||
SvcConfig svcConfig,
|
||||
boolean includeCert) throws Exception
|
||||
{
|
||||
WSSecSignature signer = new WSSecSignature();
|
||||
signer.setUserInfo(svcConfig.getSetting(SvcConfig.SigningKeyAliasName),
|
||||
svcConfig.getSetting(SvcConfig.SigningKeyPassword));
|
||||
if (includeCert)
|
||||
{
|
||||
signer.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER); // Include X509 Cert in message
|
||||
}
|
||||
else
|
||||
{
|
||||
signer.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); // Use X509 Cert Serial Number and issuer info
|
||||
}
|
||||
|
||||
Document doc = envelope.getAsDocument();
|
||||
|
||||
WSSecHeader secHeader = new WSSecHeader();
|
||||
secHeader.insertSecurityHeader(doc);
|
||||
|
||||
WSSecTimestamp timeStamper = new WSSecTimestamp();
|
||||
timeStamper.setTimeToLive(timeToLive);
|
||||
timeStamper.build(doc, secHeader);
|
||||
|
||||
Vector<WSEncryptionPart> parts = new Vector<WSEncryptionPart>();
|
||||
|
||||
String soapNamespace = doc.getDocumentElement().getNamespaceURI();
|
||||
WSEncryptionPart bodyPart = new WSEncryptionPart("Body", soapNamespace, "");
|
||||
parts.add(bodyPart);
|
||||
|
||||
WSEncryptionPart timeStampPart = new WSEncryptionPart(timeStamper.getId());
|
||||
parts.add(timeStampPart);
|
||||
|
||||
signer.setParts(parts);
|
||||
|
||||
Document signedDoc = signer.build(doc, crypto, secHeader);
|
||||
|
||||
// Convert the signed document into a SOAP message and return it.
|
||||
return toSOAPMessage(signedDoc);
|
||||
}
|
||||
}
|
||||
41
CASA-auth-token/server-java/Svc/templates/Makefile.am
Normal file
41
CASA-auth-token/server-java/Svc/templates/Makefile.am
Normal file
@@ -0,0 +1,41 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = auth.policy \
|
||||
authtoken.settings \
|
||||
iaRealms.xml \
|
||||
identoken.settings \
|
||||
svc.settings
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
11
CASA-auth-token/server-java/Svc/templates/auth.policy
Normal file
11
CASA-auth-token/server-java/Svc/templates/auth.policy
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<auth_policy>
|
||||
<auth_source>
|
||||
<realm>REALM</realm>
|
||||
<mechanism>Krb5Authenticate</mechanism>
|
||||
</auth_source>
|
||||
<auth_source>
|
||||
<realm>REALM</realm>
|
||||
<mechanism>PwdAuthenticate</mechanism>
|
||||
</auth_source>
|
||||
</auth_policy>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings>
|
||||
</settings>
|
||||
22
CASA-auth-token/server-java/Svc/templates/iaRealms.xml
Normal file
22
CASA-auth-token/server-java/Svc/templates/iaRealms.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<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="Directory"
|
||||
connectorType="org.bandit.ia.connectors.LDAPConnectorInitialCtxFactory" id="REALM">
|
||||
<bci:env prop="java.naming.ldap.attributes.binary" value="guid"/>
|
||||
<bci:env prop="java.naming.security.authentication" value="simple"/>
|
||||
<bci:env prop="java.naming.security.principal" value="PROXY_USER_NAME"/>
|
||||
<bci:env prop="java.naming.security.credentials" value="PROXY_USER_PW"/>
|
||||
<bci:connection xsi:type="bci:LDAPConnector">
|
||||
<bci:address>ldap://LDAP_HOST_NAME:LDAP_LISTEN_PORT</bci:address>
|
||||
</bci:connection>
|
||||
</bci:realm>
|
||||
<bci:realm desc="Realm Join Definition" id="E263CCC1-8F9D-4551-B786-068AA84E8564">
|
||||
<bci:connection xsi:type="bci:JoinConnector">
|
||||
<bci:realmID>REALM</bci:realmID>
|
||||
</bci:connection>
|
||||
</bci:realm>
|
||||
</bci:realms>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings>
|
||||
<Attributes>sn</Attributes>
|
||||
</settings>
|
||||
|
||||
4
CASA-auth-token/server-java/Svc/templates/svc.settings
Normal file
4
CASA-auth-token/server-java/Svc/templates/svc.settings
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<settings>
|
||||
<IAConfigFile>IAREALMS_FILE_PATH</IAConfigFile>
|
||||
</settings>
|
||||
37
CASA-auth-token/server-java/Svc/tomcat5/Makefile.am
Normal file
37
CASA-auth-token/server-java/Svc/tomcat5/Makefile.am
Normal file
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS = conf
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS = localhost
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS =
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = admin.xml \
|
||||
balancer.xml \
|
||||
manager.xml
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
|
||||
Context configuration file for the Tomcat Administration Web App
|
||||
|
||||
$Id: admin.xml,v 1.3 2004/02/20 17:09:19 remm Exp $
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<Context path="/admin" docBase="${catalina.home}/server/webapps/admin"
|
||||
debug="0" privileged="true">
|
||||
|
||||
<!-- Uncomment this Valve to limit access to the Admin app to localhost
|
||||
for obvious security reasons. Allow may be a comma-separated list of
|
||||
hosts (or even regular expressions).
|
||||
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
|
||||
allow="127.0.0.1"/>
|
||||
-->
|
||||
|
||||
<Logger className="org.apache.catalina.logger.FileLogger"
|
||||
prefix="localhost_admin_log." suffix=".txt"
|
||||
timestamp="true"/>
|
||||
|
||||
<!-- Allow linking since JPackage do not install jar as copies -->
|
||||
|
||||
<Resources className="org.apache.naming.resources.FileDirContext"
|
||||
allowLinking="true"/>
|
||||
|
||||
|
||||
</Context>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!--
|
||||
|
||||
Context configuration file for the Tomcat Balancer Web App
|
||||
This is only needed to keep the distribution small and avoid duplicating
|
||||
commons libraries
|
||||
|
||||
$Id: balancer.xml,v 1.1 2003/11/20 21:43:32 remm Exp $
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<Context path="/balancer" docBase="balancer" debug="0" privileged="true">
|
||||
|
||||
</Context>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!--
|
||||
|
||||
Context configuration file for the Tomcat Manager Web App
|
||||
|
||||
$Id: manager.xml,v 1.2 2004/02/20 17:09:29 remm Exp $
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<Context path="/manager" docBase="${catalina.home}/server/webapps/manager"
|
||||
debug="0" privileged="true">
|
||||
|
||||
<!-- Link to the user database we will get roles from -->
|
||||
<ResourceLink name="users" global="UserDatabase"
|
||||
type="org.apache.catalina.UserDatabase"/>
|
||||
|
||||
</Context>
|
||||
43
CASA-auth-token/server-java/Svc/tomcat5/conf/Makefile.am
Normal file
43
CASA-auth-token/server-java/Svc/tomcat5/conf/Makefile.am
Normal file
@@ -0,0 +1,43 @@
|
||||
#######################################################################
|
||||
#
|
||||
# Copyright (C) 2006 Novell, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
# Author: Juan Carlos Luciani <jluciani@novell.com>
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
SUBDIRS =
|
||||
|
||||
DIST_SUBDIRS = Catalina linux
|
||||
|
||||
CFILES =
|
||||
|
||||
EXTRA_DIST = catalina.policy \
|
||||
catalina.properties \
|
||||
jk2.properties \
|
||||
server.xml \
|
||||
server-minimal.xml \
|
||||
tomcat-users.xml \
|
||||
web.xml
|
||||
|
||||
.PHONY: package package-clean package-install package-uninstall
|
||||
package package-clean package-install package-uninstall:
|
||||
$(MAKE) -C $(TARGET_OS) $@
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile.in
|
||||
|
||||
162
CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.policy
Normal file
162
CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.policy
Normal file
@@ -0,0 +1,162 @@
|
||||
// ============================================================================
|
||||
// catalina.corepolicy - Security Policy Permissions for Tomcat 5
|
||||
//
|
||||
// This file contains a default set of security policies to be enforced (by the
|
||||
// JVM) when Catalina is executed with the "-security" option. In addition
|
||||
// to the permissions granted here, the following additional permissions are
|
||||
// granted to the codebase specific to each web application:
|
||||
//
|
||||
// * Read access to the document root directory
|
||||
//
|
||||
// $Id: catalina.policy,v 1.11 2004/03/02 12:36:22 remm Exp $
|
||||
// ============================================================================
|
||||
|
||||
|
||||
// ========== SYSTEM CODE PERMISSIONS =========================================
|
||||
|
||||
|
||||
// These permissions apply to javac
|
||||
grant codeBase "file:${java.home}/lib/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to all shared system extensions
|
||||
grant codeBase "file:${java.home}/jre/lib/ext/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
|
||||
grant codeBase "file:${java.home}/../lib/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to all shared system extensions when
|
||||
// ${java.home} points at $JAVA_HOME/jre
|
||||
grant codeBase "file:${java.home}/lib/ext/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
|
||||
// ========== CATALINA CODE PERMISSIONS =======================================
|
||||
|
||||
|
||||
// These permissions apply to the launcher code
|
||||
grant codeBase "file:${catalina.home}/bin/commons-launcher.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the daemon code
|
||||
grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the commons-logging API
|
||||
grant codeBase "file:${catalina.home}/bin/commons-logging-api.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the server startup code
|
||||
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the JMX server
|
||||
grant codeBase "file:${catalina.home}/bin/jmx.jar" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the servlet API classes
|
||||
// and those that are shared across all class loaders
|
||||
// located in the "common" directory
|
||||
grant codeBase "file:${catalina.home}/common/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// These permissions apply to the container's core code, plus any additional
|
||||
// libraries installed in the "server" directory
|
||||
grant codeBase "file:${catalina.home}/server/-" {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
// ========== WEB APPLICATION PERMISSIONS =====================================
|
||||
|
||||
|
||||
// These permissions are granted by default to all web applications
|
||||
// In addition, a web application will be given a read FilePermission
|
||||
// and JndiPermission for all files and directories in its document root.
|
||||
grant {
|
||||
// Required for JNDI lookup of named JDBC DataSource's and
|
||||
// javamail named MimePart DataSource used to send mail
|
||||
permission java.util.PropertyPermission "java.home", "read";
|
||||
permission java.util.PropertyPermission "java.naming.*", "read";
|
||||
permission java.util.PropertyPermission "javax.sql.*", "read";
|
||||
|
||||
// OS Specific properties to allow read access
|
||||
permission java.util.PropertyPermission "os.name", "read";
|
||||
permission java.util.PropertyPermission "os.version", "read";
|
||||
permission java.util.PropertyPermission "os.arch", "read";
|
||||
permission java.util.PropertyPermission "file.separator", "read";
|
||||
permission java.util.PropertyPermission "path.separator", "read";
|
||||
permission java.util.PropertyPermission "line.separator", "read";
|
||||
|
||||
// JVM properties to allow read access
|
||||
permission java.util.PropertyPermission "java.version", "read";
|
||||
permission java.util.PropertyPermission "java.vendor", "read";
|
||||
permission java.util.PropertyPermission "java.vendor.url", "read";
|
||||
permission java.util.PropertyPermission "java.class.version", "read";
|
||||
permission java.util.PropertyPermission "java.specification.version", "read";
|
||||
permission java.util.PropertyPermission "java.specification.vendor", "read";
|
||||
permission java.util.PropertyPermission "java.specification.name", "read";
|
||||
|
||||
permission java.util.PropertyPermission "java.vm.specification.version", "read";
|
||||
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
|
||||
permission java.util.PropertyPermission "java.vm.specification.name", "read";
|
||||
permission java.util.PropertyPermission "java.vm.version", "read";
|
||||
permission java.util.PropertyPermission "java.vm.vendor", "read";
|
||||
permission java.util.PropertyPermission "java.vm.name", "read";
|
||||
|
||||
// Required for OpenJMX
|
||||
permission java.lang.RuntimePermission "getAttribute";
|
||||
|
||||
// Allow read of JAXP compliant XML parser debug
|
||||
permission java.util.PropertyPermission "jaxp.debug", "read";
|
||||
|
||||
// Precompiled JSPs need access to this package.
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
|
||||
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";
|
||||
|
||||
};
|
||||
|
||||
|
||||
// You can assign additional permissions to particular web applications by
|
||||
// adding additional "grant" entries here, based on the code base for that
|
||||
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
|
||||
//
|
||||
// Different permissions can be granted to JSP pages, classes loaded from
|
||||
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
|
||||
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
|
||||
//
|
||||
// For instance, assume that the standard "examples" application
|
||||
// included a JDBC driver that needed to establish a network connection to the
|
||||
// corresponding database and used the scrape taglib to get the weather from
|
||||
// the NOAA web server. You might create a "grant" entries like this:
|
||||
//
|
||||
// The permissions granted to the context root directory apply to JSP pages.
|
||||
// grant codeBase "file:${catalina.home}/webapps/examples/-" {
|
||||
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
|
||||
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
|
||||
// };
|
||||
//
|
||||
// The permissions granted to the context WEB-INF/classes directory
|
||||
// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" {
|
||||
// };
|
||||
//
|
||||
// The permission granted to your JDBC driver
|
||||
// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
|
||||
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
|
||||
// };
|
||||
// The permission granted to the scrape taglib
|
||||
// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
|
||||
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
|
||||
// };
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user