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:
Juan Carlos Luciani 2006-11-16 09:20:06 +00:00
parent b00ec15375
commit 9b2e33bfa8
144 changed files with 16047 additions and 0 deletions

View File

@ -0,0 +1,2 @@
Juan Carlos Luciani - jluciani@novell.com

View File

@ -0,0 +1,459 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

View File

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/CasaAuthServer"/>
<classpathentry kind="lib" path="/usr/share/java/xerces-j2.jar"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CasaJaasSupport</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,83 @@
#######################################################################
#
# 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 linux
EXTRA_DIST = $(JAVAFILES) \
make_test.sh \
run_test.sh
ROOT = ../
LIBDIR = $(ROOT)/$(LIB)
JAVAROOT = .
JAVAC= javac
MODULE_NAME = CasaJaasSupport
MODULE_EXT = jar
JAVAFILES = src/com/novell/casa/jaas/CasaLoginModule.java \
src/com/novell/casa/jaas/CasaPrincipal.java
BUILDDIR = build
CLASSES = $(addprefix $(BUILDDIR)/, $(JAVAFILES:%.java=%.class))
LIBS =
CLASSPATH = $(LIBDIR)/java/CasaAuthToken.jar:$(LIBS)
CUR_DIR := $(shell pwd)
all: $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT)
$(BUILDDIR)/%.class: %.java
@echo [======== Compiling $@ ========]
$(JAVAC) -g -sourcepath src -classpath $(CLASSPATH) -d $(BUILDDIR)/classes $<
$(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT): $(BUILDDIR) $(CLASSES)
@echo [======== Jarring $@ ========]
jar cvf $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) -C $(BUILDDIR)/classes .
cp $(BUILDDIR)/$(MODULE_NAME).$(MODULE_EXT) $(LIBDIR)/java/
$(BUILDDIR):
[ -d $(BUILDDIR) ] || mkdir -p $(BUILDDIR)
[ -d $(BUILDDIR)/classes ] || mkdir -p $(BUILDDIR)/classes
[ -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
distclean-local:
maintainer-clean-local:
rm -f Makefile.in
rm -f Makefile

View File

@ -0,0 +1,113 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
/***********************************************************************
*
* README for JaasSupport
*
***********************************************************************/
INTRODUCTION
CasaLoginModule is a JAAS login module which can be configured
to validate credentials consisting of CASA Authentication Tokens.
CONFIGURATION
To configure the CasaLoginModule for your service follow the following
steps:
- Set the java.security.auth.login.config property to point to the JAAS
configuration file for your application.
- Set the org.xml.sax.driver property to point to an appropriate SAX Parser.
The Xerces SAX Parser is a good option (org.apache.xerces.parsers.SAXParser).
- Include the "/etc/CASA/authtoken/keys/client" path in the applications
CLASSPATH. This is the location of the crypto.properties file used by the
module to access the keystore with the ATS's signing certificate.
- Add the "/usr/share/java/CASA/authtoken/CasaJaasSupport.jar" and the
"/usr/share/java/CASA/authtoken/CasaAuthToken.jar" paths to the applications
CLASSPATH.
- Add the jar files in the /usr/share/java/CASA/authtoken/external folder
to the applications CLASSPATH.
The JAAS configuration file should include the following line:
com.novell.casa.jaas.CasaLoginModule Required;
The CasaLoginModule supports the following parameters:
PerformUsernameCheck - This parameter when set to true tells the CasaLoginModule
that it must verify that the username is set to "CasaPrincipal". If the parameter
is not specified the username is not checked.
CLIENT PROGRAMMING NOTES
Clients must specify the same service name when requesting Authentication
Tokens from the CASA Client as the service name specified by the server
when opening a JAAS Context.
SERVER PROGRAMMING NOTES
Server applications validating credentials containing CASA Authentication
tokens can obtain information about the authenticated identity by getting
access to the CasaPrincipal that gets associated with the Subject object
returned from a successful JAAS login. The CasaPrincipal provides the
following information: username, name of the identity data source (realm),
and an URL to the identity data source. The CasaPrincipal also contains
the attributes of the authenticated identity configured as required by the
service in the Authentication Token Service.
EXAMPLE SERVER APPLICATION
See src/com/novell/casa/jaas/sample/SampleApp.java for an example application
using JAAS to authenticate credentials consisting of CASA Authentication Tokens.
Note that to get the application to run you must set the path to the JAAS configuration
file as the JAVA property java.security.auth.login.config. You must also make sure that
the JAVA property org.xml.sax.driver.org is set to a valid SAX parser. The following shows
the JAVA options that you would set to run the test application: -Djava.security.auth.login.
config=/home/user/SampleApp/SampleApp.conf -Dorg.xml.sax.driver=org.apache.xerces.parsers.
SAXParser
The SampleApp.conf file should have the following contents:
SampleApp {
com.novell.casa.jaas.CasaLoginModule Required debug=true;
};
SECURITY CONSIDERATIONS
CASA Authenticatication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using SSL.

View File

@ -0,0 +1,13 @@
/***********************************************************************
*
* TODO for JaasSupport
*
***********************************************************************/
INTRODUCTION
This file contains a list of the items still outstanding for JaasSupport.
OUTSTANDING ITEMS
- Change printfs used for debugging into a suitable mechanism.

View File

@ -0,0 +1,38 @@
#######################################################################
#
# 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 = client_keystore_setup.sh \
crypto.properties
.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

View File

@ -0,0 +1,56 @@
#!/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 Authentication Token Keystore Setup Script for #
# auththentication token validating clients. #
# #
# This script sets up the certificate associated with the #
# keys used by the ATS to sign authentication tokens in the #
# keystore utilized by token validating clients. #
# #
#############################################################
JAVA_HOME=/usr/lib/jvm/java-1.5.0-ibm
# Do not do anything if the client keystore has already been created
if [ -f /etc/CASA/authtoken/keys/client/jks-store ]; then
echo "The client keystore is already setup"
else
if [ -f /etc/CASA/authtoken/keys/casaatsdSigningCert ]; then
echo "Setting up the clients's keystore"
KEYTOOL_PATH=$JAVA_HOME/bin/keytool
# Import the certificate to the client's keystore
$KEYTOOL_PATH -import -noprompt -keystore /etc/CASA/authtoken/keys/client/jks-store -alias signingCert -storepass secret -keypass secret -file /etc/CASA/authtoken/keys/casaatsdSigningCert
# List the content's of the client's keystore
#$KEYTOOL_PATH -list -rfc -keystore client/jks-store -alias signingCert -storepass secret
else
echo "File /etc/CASA/authtoken/keys/casaatsdSigningCert not found"
fi
fi

View 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=signingCert
org.apache.ws.security.crypto.merlin.alias.password=secret
org.apache.ws.security.crypto.merlin.file=/etc/CASA/authtoken/keys/client/jks-store

View File

@ -0,0 +1,14 @@
#!/bin/bash
JAVA_HOME=/usr/lib/jvm/java-1.5.0-ibm
if [ ! -d build-test ]; then
mkdir build-test
mkdir build-test/classes
else
if [ ! -d build-test/classes ]; then
mkdir build-test/classes
fi
fi
echo "*** Compiling the test application ***"
$JAVA_HOME/bin/javac -g -sourcepath src -classpath /usr/share/java/CASA/authtoken/CasaJaasSupport.jar:/usr/share/java/CASA/authtoken/CasaAuthToken.jar -d build-test/classes src/com/novell/casa/jaas/sample/SampleApp.java src/com/novell/casa/jaas/sample/SampleAppCallbackHandler.java
echo "*** Done compiling ***"

View File

@ -0,0 +1,4 @@
echo "*** Starting the test application ***"
JAVA_HOME=/usr/lib/jvm/java-1.5.0-ibm
$JAVA_HOME/bin/java -classpath build-test/classes:/usr/share/java/CASA/authtoken/CasaJaasSupport.jar:/usr/share/java/CASA/authtoken/CasaAuthToken.jar:/usr/share/java/CASA/authtoken/external/axis-ant.jar:/usr/share/java/CASA/authtoken/external/axis.jar:/usr/share/java/CASA/authtoken/external/commons-discovery-0.2.jar:/usr/share/java/CASA/authtoken/external/commons-logging-1.0.4.jar:/usr/share/java/CASA/authtoken/external/commons-logging-api.jar:/usr/share/java/CASA/authtoken/external/jaxrpc.jar:/usr/share/java/CASA/authtoken/external/log4j-1.2.8.jar:/usr/share/java/CASA/authtoken/external/saaj.jar:/usr/share/java/CASA/authtoken/external/wsdl4j-1.5.1.jar:/usr/share/java/CASA/authtoken/external/wss4j-1.5.0.jar:/usr/share/java/CASA/authtoken/external/xalan.jar:/usr/share/java/CASA/authtoken/external/xercesImpl.jar:/usr/share/java/CASA/authtoken/external/xml-apis.jar:/usr/share/java/CASA/authtoken/external/xmlsec-1.2.1.jar:/usr/share/java/xerces-j2.jar:/etc/CASA/authtoken/keys/client -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser -Djava.security.auth.login.config=src/com/novell/casa/jaas/sample/SampleApp.conf -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n com.novell.casa.jaas.sample.SampleApp

View 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

View 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

View 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

View 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 = jaas
DIST_SUBDIRS = jaas
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

View File

@ -0,0 +1,257 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.jaas;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.novell.casa.authtoksvc.AuthToken;
import com.novell.casa.authtoksvc.CasaIdentityToken;
/*
* CasaLoginModule Class.
*
* This class implements a LoginModule which performs
* authentication via the Casa Authentication Token
* infrastructure.
*
*/
public class CasaLoginModule implements LoginModule
{
private final static String casaUsername = "CasaIdentityUser";
private Subject m_subject = null;
private CasaPrincipal m_principal = null;
private CallbackHandler m_callbackHandler = null;
private Map m_sharedState = null;
private Map m_options = null;
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#abort()
*/
public boolean abort() throws LoginException
{
// Clear out all of our state
m_subject = null;
m_principal = null;
m_callbackHandler = null;
m_sharedState = null;
m_options = null;
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#commit()
*/
public boolean commit() throws LoginException
{
// Check if we instantiated a principal to associate
// with the subject.
if (m_principal != null)
{
try
{
// Add our principal to the set associated with
// the subject.
m_subject.getPrincipals().add(m_principal);
return true;
}
catch (Exception e)
{
System.err.println("CasaLoginModule.commit()- Exception caught associating principal, msg: " + e.getMessage());
throw new LoginException("Error encountered");
}
}
else
{
// Allways return since authentication failed or was not
// performed by us.
return false;
}
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#login()
*/
public boolean login() throws LoginException
{
// Verify that a CallbackHandler was specified
if (m_callbackHandler == null)
{
System.err.println("CasaLoginModule.login()- Null CallbackHandler");
throw new LoginException("Null CallbackHandler");
}
// Do not perform the username check unless configured to do it.
boolean performUsernameCheck = false;
if (m_options != null
&& m_options.containsKey((String) "PerformUsernameCheck") == true)
{
String keyVal = (String) m_options.get("PerformUsernameCheck");
if (keyVal != null && keyVal.equals("true"))
performUsernameCheck = true;
}
if (performUsernameCheck)
{
// Verify that the username is CasaIdentityUser, for this
// we first need to obtain it.
//
// Try to obtain the user name from the shared state
String username = (String) m_sharedState.get("javax.security.auth.login.name");
if (username == null)
{
// The usename was not stored in the shared state, request it.
try
{
NameCallback nameCallback = new NameCallback("Enter username:");
Callback[] callbacks = new Callback[1];
callbacks[0] = nameCallback;
m_callbackHandler.handle(callbacks);
username = nameCallback.getName();
}
catch (Exception e)
{
System.err.println("CasaLoginModule.login()- Exception caught during nameCallback, msg: " + e.getMessage());
}
// Check the username
if (username == null)
return false;
else
{
// Save the retrieved username in the shared state and then check it.
m_sharedState.put("javax.security.auth.login.name", username);
if (username.equals(casaUsername) == false)
return false;
}
}
else
{
// Check the username
if (username.equals(casaUsername) == false)
return false;
}
}
// Obtain the CasaAuthenticationToken
char[] authTokenChars = null;
try
{
PasswordCallback passwordCallback = new PasswordCallback("Enter CasaAuthenticationToken:", false);
Callback[] callbacks = new Callback[1];
callbacks[0] = passwordCallback;
m_callbackHandler.handle(callbacks);
authTokenChars = passwordCallback.getPassword();
}
catch (Exception e)
{
System.err.println("CasaLoginModule.login()- Exception caught during passwordCallback, msg: " + e.getMessage());
}
// Check the CasaAuthenticationToken
if (authTokenChars != null)
{
// Instantiate the AuthToken, this validates the token itself.
try
{
AuthToken authToken = new AuthToken(new String(authTokenChars), true);
// Instantiate the appropriate IdentityToken based on the IdentityTokenProvider type
// tbd - For now use the CasaIdentityToken
CasaIdentityToken identityToken = new CasaIdentityToken();
identityToken.initialize(authToken.getIdentityToken());
// Now instantiate the CasaPrincipal
m_principal = new CasaPrincipal(identityToken);
}
catch (Exception e)
{
// The validation of one of the tokens failed
// tbd - Log
System.err.println("CasaLoginModule.login()- Exception caught during token processing, msg: " + e.getMessage());
throw new FailedLoginException("Token validation failed");
}
}
else
{
// Token not provided
// tbd - Log
System.err.println("CasaLoginModule.login()- Token not provided");
throw new FailedLoginException("CasaAuthenticationToken not obtained");
}
// User validated
// tbd - Log
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#logout()
*/
public boolean logout() throws LoginException
{
// Check if we must try to remove our principal
// from the associated subject.
if (m_principal != null
&& m_subject.isReadOnly() == false)
{
Set principalSet = m_subject.getPrincipals();
principalSet.remove(m_principal);
}
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
*/
public void initialize(
Subject subject,
CallbackHandler callbackHandler,
Map sharedState,
Map options)
{
// Save the input parameters for later use
m_subject = subject;
m_callbackHandler = callbackHandler;
m_sharedState = sharedState;
m_options = options;
}
}

View File

@ -0,0 +1,87 @@
/***********************************************************************
*
* 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.
*
***********************************************************************/
package com.novell.casa.jaas;
import java.security.Principal;
import com.novell.casa.authtoksvc.IdentityToken;
/*
* CasaPrincipal class.
*
* This class implements the principal class for
* identities authenticated by Casa.
*
*/
public class CasaPrincipal implements Principal
{
private String m_name;
private String m_realm;
private String m_identStoreUrl;
private javax.naming.directory.Attributes m_attributes;
/*
* Constructor
*/
public CasaPrincipal(IdentityToken identityToken) throws Exception
{
// Get the necessary information from the identity token
m_name = identityToken.getIdentityId();
m_realm = identityToken.getSourceName();
m_identStoreUrl = identityToken.getSourceUrl();
m_attributes = identityToken.getAttributes();
}
/*
* (non-Javadoc)
* @see java.security.Principal#getName()
*/
public String getName()
{
return m_name;
}
/*
* Returns the name associated with the source of the identity data.
*/
public String getRealm()
{
return m_realm;
}
/*
* Returns the url associated with the source of the identity data.
*/
public String getIdentStoreUrl()
{
return m_identStoreUrl;
}
/*
* Returns the identity attributes.
*/
public javax.naming.directory.Attributes getAttributes()
{
return m_attributes;
}
}

View File

@ -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 = sample
DIST_SUBDIRS = sample
JAVAFILES = CasaLoginModule.java \
CasaPrincipal.java
EXTRA_DIST = $(JAVAFILES)
.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

View 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 =
JAVAFILES = SampleAppCallbackHandler.java \
SampleApp.java
EXTRA_DIST = $(JAVAFILES) \
SampleApp.conf
.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

View File

@ -0,0 +1,3 @@
testService {
com.novell.casa.jaas.CasaLoginModule Required debug=true;
};

View File

@ -0,0 +1,193 @@
/***********************************************************************
*
* 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.jaas.sample;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Set;
import javax.naming.NamingEnumeration;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import com.novell.casa.jaas.CasaPrincipal;
/*
* This is a sample application which demonstrates the use of
* JAAS and Casa to authenticate a connection.
*/
public class SampleApp
{
/**
* @param args
*/
public static void main(String[] args)
{
Socket sock = null;
ServerSocket listenSock = null;
try
{
// Create a socket to listen for connections
int port = 4444;
int queueLen = 6;
System.out.println("Listen port = " + port);
listenSock = new ServerSocket(port, queueLen);
// Service connections
while (true)
{
BufferedReader in = null;
try
{
// Wait for the next connection
System.out.println("Waiting for connection");
sock = listenSock.accept();
System.out.println();
System.out.println("********Connection received*********");
// Get socket I/O streams
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
//PrintStream out = new PrintStream(sock.getOutputStream());
// Get the authentication token from the client
String authToken = in.readLine();
//System.out.println("Token received from client, length = " + authToken.length());
// Authenticate the token and print out the information available to our service
// about the authenticated identity.
LoginContext lc = new LoginContext("testService", new SampleAppCallbackHandler(authToken));
try
{
System.out.println("Authenticating the user");
lc.login();
System.out.println(" Authentication succeeded");
// Now get the subject associated with the context
Subject subject = lc.getSubject();
// Now get the CasaPrincipals that represent the authenticated
// identity or identities.
Set principalSet = subject.getPrincipals(CasaPrincipal.class);
//System.out.println("The number of CasaPrincipals is: " + principalSet.size());
Iterator principalIter = principalSet.iterator();
System.out.println();
System.out.println("Authenticated Identity Information");
System.out.println();
while (principalIter.hasNext() == true)
{
CasaPrincipal principal = (CasaPrincipal) principalIter.next();
// Print out information about the principal
System.out.println(" Source of the identity information: " + principal.getIdentStoreUrl());
System.out.println(" Realm name associated with identity source: " + principal.getRealm());
System.out.println(" Principal name (unique within identity source realm): " + principal.getName());
System.out.println();
System.out.println("Authenticated Identity Attributes");
System.out.println();
javax.naming.directory.Attributes attrs = principal.getAttributes();
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())
{
System.out.print(" Attribute Name: " + attr.getID());
Object attrValue = enumeration.next();
if (attrValue instanceof byte[])
{
// The attribute value is binary data
StringBuffer buf = new StringBuffer();
char[] hex = "0123456789ABCDEF".toCharArray();
for (int i = 0; i < ((byte[]) attrValue).length; i++)
{
buf.append(hex[(((byte[]) attrValue)[i] >> 4) & 0xF]);
buf.append(hex[((byte[]) attrValue)[i] & 0xF]);
}
System.out.println(" :: Attribute Value: " + buf.toString());
}
else
{
// The attribute value is contained in a string
System.out.println(" :: Attribute Value: " + (String) attrValue);
}
}
}
}
System.out.println();
}
catch (LoginException e)
{
System.out.println(" Authentication failed, LoginException: " + e.getMessage());
}
}
finally
{
if (sock != null)
{
sock.close();
sock = null;
}
if (in != null)
in.close();
}
}
}
catch (IOException e)
{
System.out.println("IOException: " + e.getMessage());
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage());
}
finally
{
try
{
if (sock != null)
{
sock.close();
}
if (listenSock != null)
{
listenSock.close();
}
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage());
}
}
}
}

View File

@ -0,0 +1,71 @@
/***********************************************************************
*
* 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.jaas.sample;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
public class SampleAppCallbackHandler implements CallbackHandler
{
private String m_authToken;
/*
* Constructor
*
*/
public SampleAppCallbackHandler(String authToken)
{
m_authToken = authToken;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
nc.setName("CasaIdentityUser");
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
//System.out.println("SampleAppCallbackHandler.handle()- Token length = " + m_authToken.length());
char[] allChars = m_authToken.toCharArray();
// Remove the null terminator
char[] tokenChars = new char[allChars.length - 1];
for (int ii = 0; ii < tokenChars.length; ii++)
tokenChars[ii] = allChars[ii];
pc.setPassword(tokenChars);
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}

View File

@ -0,0 +1,38 @@
#######################################################################
#
# 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 = Svc Jaas package
DIST_SUBDIRS = Svc Jaas package
EXTRA_DIST = autogen.sh
.PHONY: package package-clean package-install package-uninstall
package package-clean package-install package-uninstall:
$(MAKE) -C package $@
clean-local:
if [ -d lib ]; then rm -rf lib; fi
maintainer-clean-local:
rm -f Makefile.in

View File

View File

@ -0,0 +1,113 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
/***********************************************************************
*
* README for auth_token
*
***********************************************************************/
INTRODUCTION
CASA-auth-token is an authentication token infrastructure with support for multiple
authentication mechanisms with an emphasis on providing a scalable single
sign-on solution.
A key feature of auth_token is that its authentication tokens contain identity
information about the entity being authenticated. This information is made available
to the consuming services. The amount of information contained in the tokens is
configured on a per-service basis. Because of this feature, we say that CASA-auth-token
projects an "Authenticated Identity".
ARCHITECTURE COMPONENTS
The infrastructure provided by auth_token consists of client and server components.
The client components of auth_token consists of a Client Engine, Get Authentication
Token API, Authentication Token Cache, and Authentication Mechanism plug-ins.
The server components of auth_token consists of an Authentication Token Service, a
Verify Authentication Token API, a JAAS module, a PAM module, and an Apache Authentication
Provider module. The Authentication Token Service makes use of Authentication Mechanism
plug-ins, an Identity Data Store Abstraction Layer, and of Identity Token Providers.
SECURITY FEATURES AND DATA FLOW
Communications between the Client Engine and the Authentication Token Service (ATS)
occur over HTTPS. When a client desires to obtain an Authentication Token to access
a particular service it contacts an ATS which then proceeds to inform the client about
the Authentication Policy configured for the service. The policy contains information
about authentication mechanisms supported as well as information about the types of
credentials that the client can utilize to authenticate to the ATS. Once the client
receives the Authentication Policy, it then decides what authentication mechanism to
utilize to authenticate to the ATS based on the available authentication mechanisms
plug-ins as well as the available credentials. During the authentication process, the
ATS associates an identity with the entity being authenticated. The result of this
resolution is saved in a Session Token which is then sent to the client where it is
cached. Once the client is authenticated to the ATS, it then requests Authentication
Tokens from it using the obtained Session Token. When an ATS receives a request for
an Authentication Token, it then verifies the validity of the received Session Token
and then it creates the appropriate Identity Token for the target service which it then
embeds within the Authentication Token. The identity information contained in the
Identity Token as well as the type of Identity Token utilized depends on what is
configured for the tatget service.
Session Tokens and Authentication Tokens are signed by the issuing ATS using Signing
Certificates. Session Tokens and Authentication Tokens have a Lifetime Value associated
with them. Token verification involves verifying the token signatures, verifying that
the tokens where signed by a trusted entity, and verifying that the token lifetime has
not been exceeeded.
The auth_token client/service protocol allows for the authentication of the client entity.
auth_token relies in the server authentication mechanisms of SSL to verify the identity
of the ATS.
IMPLEMENTATION STRATEGY AND CURRENT STATUS
auth_token is currently under development and is not ready to be used in production.
The implementation strategy has been to first complete the framework with all of its
modules, APIs, and packaging to allow application writters to start developing to it.
Once this is done, then the implementation focus will switch to completing the plumbing.
As of this time, a lot of the framework has been completed and there are sample
applications that can be utilized to exercise it. For a more complete picture of where
we are, look at the various TODO lists present in the child folders.
The schedule for completing auth_token is agressive.
SECURITY CONSIDERATIONS
CASA Authentication Tokens when compromised can be used to either impersonate
a user or to obtain identity information about the user. Because of this it is
important that the tokens be secured by applications making use of them. It is
recommended that the tokens be transmitted using SSL.

View File

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

View File

@ -0,0 +1,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

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

View 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.

View 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

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

View 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 $*

View 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 $*

View 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

View 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

View 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 $*

View 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 $*

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,2 @@
Main-Class: com.novell.casa.authtoksvc.AuthPolicyEditor

View File

@ -0,0 +1,2 @@
Main-Class: com.novell.casa.authtoksvc.AuthTokenSettingsEditor

View File

@ -0,0 +1,2 @@
Main-Class: com.novell.casa.authtoksvc.IdenTokenSettingsEditor

View 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

View File

@ -0,0 +1,2 @@
Main-Class: com.novell.casa.authtoksvc.SvcSettingsEditor

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,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

View 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

View 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

View 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 = 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

View File

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

View File

@ -0,0 +1,53 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
/*
* AuthMechanism Interface.
*
* This is the interface implemented by Authentication Mechanisms.
*
* Please note that Authentication Machanisms must also implement the
* Serializable interface.
*
*/
public interface AuthMechanism
{
/*
* Initialize the authentication mechanism.
*/
void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception;
/*
* Process authenticate request. If successful, return the Id of the
* authenticated identity.
*/
String invoke(AuthReqMsg authReqMsg) throws Exception;
/*
* Return the mechanism id.
*/
String getId();
}

View File

@ -0,0 +1,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);
}
}

View File

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

View File

@ -0,0 +1,113 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
/**
* AuthRespMsg Class.
*
* This class deals with the message sent to the CASA Client as a
* response to an authentication request. The format of the message is
* as follows when the response includes a session token:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_resp>
* <status><description>OK</description>200</status>
* <session_token><lifetime>lifetime value</lifetime>session token data</session_token>
* </auth_resp>
*
* The format of the message is as follows when the response does not
* include a session token.
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <auth_resp>
* <status><description>status description</description>status code</status>
* </auth_resp>
*
* Plase note that the protocol utilizes the status codes defined
* in the HTTP 1.1 Specification.
*
*/
public class AuthRespMsg
{
String m_msg;
/*
* Constructor for a msg that does not include the session token.
*/
public AuthRespMsg (
String statusDescription,
String statusCode) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Constructor for a msg that includes the session token.
*/
public AuthRespMsg (
String statusDescription,
String statusCode,
String sessionToken,
String sessionTokenLifetime) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.authResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.sessionTokenElementName + ">"
+ "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
+ sessionToken + "</" + ProtoDefs.sessionTokenElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.authResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Returns a string containing the AuthRespMsg.
*/
public String toString()
{
return m_msg;
}
}

View File

@ -0,0 +1,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;
}
}
}

View File

@ -0,0 +1,298 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
import java.io.*;
import java.util.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* AuthTokenConfig Class.
*
* This class obtains and maintains authentication token configuration.
*
*/
public class AuthTokenConfig
{
// Well known authentication token configuration settings
public final static String TokenLifetime = "TokenLifetime";
public final static String LifetimeShorter = "LifetimeShorter";
public final static String IdentityTokenType = "IdentityTokenType";
// Default configuration values
private String m_defaultTokenLifetimeValue = "3600"; // Seconds
private String m_defaultLifetimeShorterValue = "5"; // Seconds
private String m_defaultIdentityTokenTypeValue = "CasaIdentityToken";
private Map m_tokenSettingsMap;
/*
* Class for handling parsing events.
*/
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
{
private final static int AWAITING_ROOT_ELEMENT_START = 0;
private final static int AWAITING_SETTING_ELEMENT_START = 1;
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
private final static int AWAITING_SETTING_ELEMENT_END = 3;
private final static int DONE_PARSING = 4;
private final static String m_rootElementName = "settings";
private Map m_keyMap;
private int m_state;
private String m_currentKey;
/*
* Constructor
*/
public SAXHandler(Map keyMap)
{
super();
// Initialize our members
m_keyMap = keyMap;
m_state = AWAITING_ROOT_ELEMENT_START;
}
/*
* endDocument() implementation.
*/
public void endDocument () throws SAXException
{
// Verify that we are not in an invalid state
if (m_state != DONE_PARSING)
{
System.err.println("AuthTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
throw new SAXException("Invalid state at endDocument");
}
}
/*
* startElement() implementation.
*/
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
{
// Proceed based on our state
switch (m_state)
{
case AWAITING_ROOT_ELEMENT_START:
// Verify that we are processing the expected tag
if (m_rootElementName.equals(qName))
{
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_START;
}
else
{
System.err.println("AuthTokenConfig SAXHandler.startElement()- Un-expected element");
throw new SAXException("Un-expected element");
}
break;
case AWAITING_SETTING_ELEMENT_START:
// Keep track of the key name
m_currentKey = qName;
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_DATA;
break;
default:
System.err.println("AuthTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
throw new SAXException("Invalid state at startElement");
}
}
/*
* endElement() immplementation.
*/
public void endElement (String uri, String name, String qName) throws SAXException
{
// Proceed based on our state
switch (m_state)
{
case AWAITING_SETTING_ELEMENT_DATA:
case AWAITING_SETTING_ELEMENT_END:
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_START;
break;
case AWAITING_SETTING_ELEMENT_START:
// Verify that we are processing the expected tag
if (m_rootElementName.equals(qName))
{
// Advance to the next state
m_state = DONE_PARSING;
}
else
{
System.err.println("AuthTokenConfig SAXHandler.endElement()- Un-expected element");
throw new SAXException("Un-expected element");
}
break;
default:
System.err.println("AuthTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
throw new SAXException("Invalid state at endElement");
}
}
/*
* character() implementation.
*/
public void characters (char ch[], int start, int length) throws SAXException
{
// Consume the data if in the right state
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
{
// Consume the data and add the key to map
m_keyMap.put(m_currentKey, new String(ch, start, length));
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_END;
}
}
}
/*
* Constructor which sets default configuration values.
*/
public AuthTokenConfig() throws Exception
{
System.err.println("AuthTokenConfig()- Default");
// Create a map to keep track of the token settings
m_tokenSettingsMap = new HashMap();
// Set the default settings in our map
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
}
/*
* Constructor.
*/
public AuthTokenConfig(String authTokenSettingsFileName) throws Exception
{
System.err.println("AuthTokenConfig()-");
// Create a map to keep track of the token settings
m_tokenSettingsMap = new HashMap();
try
{
// Get an input stream to read from the token settings file
File f = new File(authTokenSettingsFileName);
FileInputStream inStream = new FileInputStream(f);
// Parse the file
XMLReader xr = XMLReaderFactory.createXMLReader();
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
xr.setContentHandler(handler);
xr.setErrorHandler(handler);
InputSource source = new InputSource(inStream);
xr.parse(source);
inStream.close();
}
catch (SAXException e)
{
System.err.println("AuthTokenConfig()- " + authTokenSettingsFileName + " format error, exception: " + e.toString());
throw new Exception("AuthTokenConfig()- authtoken.settings format error");
}
catch (SecurityException e)
{
System.err.println("AuthTokenConfig()- SecurityException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
throw new Exception("AuthTokenConfig()- Not able to access file");
}
catch (FileNotFoundException e)
{
System.err.println("AuthTokenConfig()- File " + authTokenSettingsFileName + " not found");
throw new Exception("AuthTokenConfig()- File not found");
}
catch (IOException e)
{
System.err.println("AuthTokenConfig()- IOException accessing " + authTokenSettingsFileName + " Exception=" + e.toString());
throw new Exception("AuthTokenConfig()- Read error");
}
}
/*
* Returns the value associated with the specified setting.
*/
public String getSetting(String settingName) throws Exception
{
// Try to find the setting in our map
String value = (String) m_tokenSettingsMap.get(settingName);
if (value == null)
{
System.err.println("AuthTokenConfig.getSetting()- Did not find setting " + settingName);
// The setting is not in our map, check if it is one to
// which we have defaults.
if (settingName.equals(TokenLifetime) == true)
{
value = m_defaultTokenLifetimeValue;
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
// Add the key to the map so that it can be found quicker next time
m_tokenSettingsMap.put(TokenLifetime, m_defaultTokenLifetimeValue);
}
else if (settingName.equals(LifetimeShorter) == true)
{
value = m_defaultLifetimeShorterValue;
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
// Add the key to the map so that it can be found quicker next time
m_tokenSettingsMap.put(LifetimeShorter, m_defaultLifetimeShorterValue);
}
else if (settingName.equals(IdentityTokenType) == true)
{
value = m_defaultLifetimeShorterValue;
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
// Add the key to the map so that it can be found quicker next time
m_tokenSettingsMap.put(IdentityTokenType, m_defaultIdentityTokenTypeValue);
}
}
else
{
System.err.println("AuthTokenConfig.getSetting()- Found setting " + settingName);
System.err.println("AuthTokenConfig.getSetting()- Setting value = " + value);
// Do some sanity checking
// tbd - Make sure that the token lifetime values are greater than the LifetimeShorter
}
return value;
}
}

View File

@ -0,0 +1,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);
}
}

View File

@ -0,0 +1,341 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
import java.util.*;
import java.io.*;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLClassLoader;
/**
* Authenticate Class.
*
* This class processes authentication requests.
*
*/
public class Authenticate implements RpcMethod
{
private static final String m_mechanismSettingsFileName = "mechanism.settings";
private Map m_authMechanismMap;
private SvcConfig m_svcConfig;
private EnabledSvcsConfig m_enabledSvcsConfig;
/*
* Constructor
*/
public Authenticate() throws Exception
{
// Create a map to keep track of the authentication mechanisms
m_authMechanismMap = new HashMap();
}
/*
* Initialize the Rpc method.
*/
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
{
m_svcConfig = svcConfig;
m_enabledSvcsConfig = enabledSvcsConfig;
// Now go through the configured authentication mechanisms, as we do so, instantiate
// the mechanisms and place them in our map. Note that the mechanisms config folder
// contains folders for each installed authentication mechanism. The name of these
// folders usually match the name of the Authentication mechanisms.
String svcConfigPath = svcConfig.getSetting(SvcConfig.ConfigFolderPath);
File mechanismsConfigFolder = new File(svcConfigPath, "auth_mechanisms");
try
{
String[] mechanismsConfigFolderObjs = mechanismsConfigFolder.list();
if (mechanismsConfigFolderObjs != null)
{
for (int i = 0; i < mechanismsConfigFolderObjs.length; i++)
{
// Check if we are dealing with a file or a folder
File mechanismFolder = new File(mechanismsConfigFolder, mechanismsConfigFolderObjs[i]);
try
{
if (mechanismFolder.isDirectory() == true)
{
System.err.println("Authenticate.init()- Mechanism folder " + mechanismFolder + " is directory");
// Try to obtain the mechanism settings
try
{
AuthMechConfig mechConfig = new AuthMechConfig(mechanismFolder + File.separator + m_mechanismSettingsFileName);
// Mechanism settings obtained, now instantiate it and place it in our map.
//
String mechClassName = mechConfig.getSetting(AuthMechConfig.ClassName);
if (mechClassName != null)
{
// We now know the name of the class implementing the mechanism, now lets
// get the relative path to the class file. Note that the path is relative
// to the root folder of our application.
String relativePath = mechConfig.getSetting(AuthMechConfig.RelativeClassPath);
if (relativePath != null)
{
// Create a file object to the folder containing the class file. Note that we need to
// ultimately instantiate objects from a class loaded by the same class loader that
// loads the AuthMechanism class to avoid ClassCastExceptions.
File mechClassPathFile = new File(svcConfig.getSetting(SvcConfig.AppRootPath) + relativePath);
System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile);
try
{
URL methClassPathUrl = mechClassPathFile.toURL();
URL[] urls = new URL[]{methClassPathUrl};
// Create a class loader for the folder
ClassLoader customClassLoader = new URLClassLoader(urls);
// Load the mech class using our custom loader
Class mechClass = customClassLoader.loadClass(mechClassName);
FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(mechClass);
oos.close();
fos.close();
FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
mechClass = (Class) ois.readObject();
ois.close();
fis.close();
// Now reload the class using the class loader for our AuthMechanism class
AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance();
mechanism.init(svcConfig, mechConfig);
m_authMechanismMap.put(mechanism.getId(), mechanism);
}
catch (MalformedURLException e)
{
System.err.println("Authenticate.init()- MalformedURLException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (ClassNotFoundException e)
{
System.err.println("Authenticate.init()- ClassNotFoundException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (InstantiationException e)
{
System.err.println("Authenticate.init()- InstantiationException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (IllegalAccessException e)
{
System.err.println("Authenticate.init()- IllegalAccessException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
}
else
{
// A relative path was not configured, check if instead a full path was configured.
String classPath = mechConfig.getSetting(AuthMechConfig.ClassPath);
if (classPath != null)
{
// Create a file object to the folder containing the class file. Note that we need to
// ultimately instantiate objects from a class loaded by the same class loader that
// loads the AuthMechanism class to avoid ClassCastExceptions.
File mechClassPathFile = new File(classPath);
System.err.println("Authenticate.init()- Mechanism path = " + mechClassPathFile);
try
{
URL methClassPathUrl = mechClassPathFile.toURL();
URL[] urls = new URL[]{methClassPathUrl};
// Create a class loader for the folder
ClassLoader customClassLoader = new URLClassLoader(urls);
// Load the mech class using our custom loader
Class mechClass = customClassLoader.loadClass(mechClassName);
FileOutputStream fos = new FileOutputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(mechClass);
oos.close();
fos.close();
FileInputStream fis = new FileInputStream(svcConfig.getSetting(SvcConfig.AppRootPath) + "tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
mechClass = (Class) ois.readObject();
ois.close();
fis.close();
// Now reload the class using the class loader for our AuthMechanism class
AuthMechanism mechanism = (AuthMechanism) mechClass.newInstance();
mechanism.init(svcConfig, mechConfig);
m_authMechanismMap.put(mechanism.getId(), mechanism);
}
catch (MalformedURLException e)
{
System.err.println("Authenticate.init()- MalformedURLException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (ClassNotFoundException e)
{
System.err.println("Authenticate.init()- ClassNotFoundException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (InstantiationException e)
{
System.err.println("Authenticate.init()- InstantiationException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (IllegalAccessException e)
{
System.err.println("Authenticate.init()- IllegalAccessException for " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
}
else
{
System.err.println("Authenticate.init()- No configuration to find class path to load " + mechanismFolder + File.separator + m_mechanismSettingsFileName);
}
}
}
else
{
System.err.println("Authenticate.init()- No configured mechanism class name for " + mechanismFolder + File.separator + m_mechanismSettingsFileName);
}
}
catch (SecurityException e)
{
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (FileNotFoundException e)
{
System.err.println("Authenticate.init()- No authentication policy file for " + mechanismFolder);
}
catch (IOException e)
{
System.err.println("Authenticate.init()- IOException reading " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
catch (Exception e)
{
System.err.println("Authenticate.init()- Exception instantiating mechConfig or mechanism " + mechanismFolder + File.separator + m_mechanismSettingsFileName + " Exception=" + e.toString());
}
}
}
catch (SecurityException e)
{
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismFolder + " Exception=" + e.toString());
}
}
}
else
{
System.err.println("Authenticate.init()- Unable to obtain mechanisms folder " + mechanismsConfigFolder + " objects");
}
}
catch (SecurityException e)
{
System.err.println("Authenticate.init()- SecurityException accessing " + mechanismsConfigFolder + " Exception=" + e.toString());
}
}
/*
* Process Rpc.
*/
public void invoke(InputStream inStream, PrintWriter out) throws IOException
{
try
{
System.err.println("Authenticate.invoke()");
// Parse the AuthReqMsg sent from the client
AuthReqMsg authReqMsg = new AuthReqMsg(inStream);
// Get the necessary authentication mechanism
AuthMechanism authMechanism = (AuthMechanism) m_authMechanismMap.get(authReqMsg.getMechanismId());
if (authMechanism != null)
{
// Invoke the mechanism to authenticate the entity
String identId = authMechanism.invoke(authReqMsg);
// Create response based on the identity resolution results
if (identId != null && identId.length() != 0)
{
System.err.println("Authenticate.invoke()- identId resolved, " + identId);
// An identity was resolved, get a SessionToken for it.
SessionToken sessionToken = new SessionToken(identId,
authReqMsg.getRealm(),
m_svcConfig.getSetting(SvcConfig.SessionTokenLifetime),
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";
}
}

View File

@ -0,0 +1,121 @@
/**************************************************************************
*
* A Base64 Encoder/Decoder.
*
* This class is used to encode and decode data in Base64 format
* as described in RFC 1521.
*
* <p>
* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br>
* License: This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license.
* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.<br>
* Home page: <a href="http://www.source-code.biz" target="_top">www.source-code.biz</a><br>
*
* <p>
* Version history:<br>
* 2003-07-22 Christian d'Heureuse (chdh): Module created.<br>
* 2005-08-11 chdh: Lincense changed from GPL to LGPL.
*
**************************************************************************/
package com.novell.casa.authtoksvc;
public class Base64Coder {
// Mapping table from 6-bit nibbles to Base64 characters.
private static char[] map1 = new char[64];
static {
int i=0;
for (char c='A'; c<='Z'; c++) map1[i++] = c;
for (char c='a'; c<='z'; c++) map1[i++] = c;
for (char c='0'; c<='9'; c++) map1[i++] = c;
map1[i++] = '+'; map1[i++] = '/'; }
// Mapping table from Base64 characters to 6-bit nibbles.
private static byte[] map2 = new byte[128];
static {
for (int i=0; i<map2.length; i++) map2[i] = -1;
for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
/**
* Encodes a string into Base64 format.
* No blanks or line breaks are inserted.
* @param s a String to be encoded.
* @return A String with the Base64 encoded data.
*/
public static String encode (String s) {
return new String(encode(s.getBytes())); }
/**
* Encodes a byte array into Base64 format.
* No blanks or line breaks are inserted.
* @param in an array containing the data bytes to be encoded.
* @return A character array with the Base64 encoded data.
*/
public static char[] encode (byte[] in) {
int iLen = in.length;
int oDataLen = (iLen*4+2)/3; // output length without padding
int oLen = ((iLen+2)/3)*4; // output length including padding
char[] out = new char[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++] & 0xff;
int i1 = ip < iLen ? in[ip++] & 0xff : 0;
int i2 = ip < iLen ? in[ip++] & 0xff : 0;
int o0 = i0 >>> 2;
int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
int o3 = i2 & 0x3F;
out[op++] = map1[o0];
out[op++] = map1[o1];
out[op] = op < oDataLen ? map1[o2] : '='; op++;
out[op] = op < oDataLen ? map1[o3] : '='; op++; }
return out; }
/**
* Decodes a Base64 string.
* @param s a Base64 String to be decoded.
* @return A String containing the decoded data.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static String decode (String s) {
return new String(decode(s.toCharArray())); }
/**
* Decodes Base64 data.
* No blanks or line breaks are allowed within the Base64 encoded data.
* @param in a character array containing the Base64 encoded data.
* @return An array containing the decoded data bytes.
* @throws IllegalArgumentException if the input is not valid Base64 encoded data.
*/
public static byte[] decode (char[] in) {
int iLen = in.length;
if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iLen-1] == '=') iLen--;
int oLen = (iLen*3) / 4;
byte[] out = new byte[oLen];
int ip = 0;
int op = 0;
while (ip < iLen) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iLen ? in[ip++] : 'A';
int i3 = ip < iLen ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
int o0 = ( b0 <<2) | (b1>>>4);
int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
int o2 = ((b2 & 3)<<6) | b3;
out[op++] = (byte)o0;
if (op<oLen) out[op++] = (byte)o1;
if (op<oLen) out[op++] = (byte)o2; }
return out; }
}

View File

@ -0,0 +1,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");
}
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,111 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
/**
* GetAuthPolicyRespMsg Class.
*
* This class deals with the message sent to the Casa Client as a
* response to a get authentication token request. The format of
* the message is as follows when the response includes an
* authentication token:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_policy_resp>
* <status><description>OK</description>200</status>
* <auth_policy>authentication policy data</auth_policy>
* </get_auth_policy_resp>
*
* The format of the message is as follows when the response does not
* include an authentication token.
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_policy_resp>
* <status><description>status description</description>status code</status>
* </get_auth_policy_resp>
*
* Plase note that the protocol utilizes the status codes defined
* in the HTTP 1.1 Specification.
*
*/
public class GetAuthPolicyRespMsg
{
String m_msg;
/*
* Constructor for a msg that does not include the authentication policy.
*/
public GetAuthPolicyRespMsg (
String statusDescription,
String statusCode) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Constructor for a msg that includes the authentication policy.
*/
public GetAuthPolicyRespMsg (
String statusDescription,
String statusCode,
String authPolicy) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "</" + ProtoDefs.authPolicyElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.getAuthPolicyResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Returns a string containing the GetAuthPolicyRespMsg.
*/
public String toString()
{
return m_msg;
}
}

View File

@ -0,0 +1,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;
}
}

View File

@ -0,0 +1,115 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
/**
* GetAuthTokRespMsg Class.
*
* This class deals with the message sent to the Casa Client as a
* response to a get authentication token request. The format of
* the message is as follows when the response includes an
* authentication token:
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_tok_resp>
* <status><description>OK</description>200</status>
* <auth_token><lifetime>lifetime value</lifetime>authentication token data</auth_token>
* </get_auth_tok_resp>
*
* The format of the message is as follows when the response does not
* include an authentication token.
*
* <?xml version="1.0" encoding="ISO-8859-1"?>
* <get_auth_tok_resp>
* <status><description>status description</description>status code</status>
* </get_auth_tok_resp>
*
* Plase note that the protocol utilizes the status codes defined
* in the HTTP 1.1 Specification.
*
*/
public class GetAuthTokRespMsg
{
String m_msg;
/*
* Constructor for a msg that does not include the authentication token.
*/
public GetAuthTokRespMsg (
String statusDescription,
String statusCode) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + statusDescription + "</" + ProtoDefs.descriptionElementName + ">"
+ statusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Constructor for a msg that includes the authentication token.
*/
public GetAuthTokRespMsg (
String statusDescription,
String statusCode,
String authToken,
String authTokenLifetime) throws Exception
{
// Get a StringBuffer to help us with the construction of the message
StringBuffer sb = new StringBuffer();
// Start building the message
sb.append(ProtoDefs.xmlDeclaration + "\r\n");
sb.append("<" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.statusElementName + ">"
+ "<" + ProtoDefs.descriptionElementName + ">" + ProtoDefs.httpOkStatusMsg + "</" + ProtoDefs.descriptionElementName + ">"
+ ProtoDefs.httpOkStatusCode + "</" + ProtoDefs.statusElementName + ">" + "\r\n");
sb.append("<" + ProtoDefs.authTokenElementName + ">"
+ "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "</" + ProtoDefs.lifetimeElementName + ">"
+ authToken + "</" + ProtoDefs.authTokenElementName + ">" + "\r\n");
sb.append("</" + ProtoDefs.getAuthTokResponseElementName + ">" + "\r\n");
// The message has now been built, save it.
m_msg = sb.toString();
}
/*
* Returns a string containing the GetAuthTokRespMsg.
*/
public String toString()
{
return m_msg;
}
}

View File

@ -0,0 +1,146 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
/**
* GetAuthToken Class.
*
* This class processes requests for tokens to authenticate an entity
* to a particular service.
*
*/
public class GetAuthToken implements RpcMethod
{
private SvcConfig m_svcConfig;
private EnabledSvcsConfig m_enabledSvcsConfig;
/*
* Constructor.
*/
public GetAuthToken() throws Exception
{
// Nothing to do at this time
}
/*
* Initialize the Rpc method.
*/
public void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception
{
m_svcConfig = svcConfig;
m_enabledSvcsConfig = enabledSvcsConfig;
}
/*
* Process Rpc.
*/
public void invoke(InputStream inStream, PrintWriter out) throws IOException
{
try
{
System.err.println("GetAuthToken.invoke()");
// Parse the GetAuthTokReqMsg sent from the client
GetAuthTokReqMsg getAuthTokReqMsg = new GetAuthTokReqMsg(inStream);
// Verify that the service is enabled
if (m_enabledSvcsConfig.svcEnabled(getAuthTokReqMsg.getHostName(),
getAuthTokReqMsg.getServiceName()))
{
// Now create a session token (This validates the session token provided).
SessionToken sessionToken = new SessionToken(getAuthTokReqMsg.getSessionToken());
try
{
// Create the Authentication Token
AuthToken authToken = new AuthToken(sessionToken.getIdentId(),
sessionToken.getRealm(),
getAuthTokReqMsg.getServiceName(),
getAuthTokReqMsg.getHostName(),
m_svcConfig,
m_enabledSvcsConfig);
// Write out the response
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpOkStatusMsg,
ProtoDefs.httpOkStatusCode,
authToken.toString(),
authToken.getLifetime());
out.println(getAuthTokRespMsg.toString());
}
catch (Exception e)
{
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
// Write out the response
try
{
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpUnauthorizedStatusMsg,
ProtoDefs.httpUnauthorizedStatusCode);
out.println(getAuthTokRespMsg.toString());
}
catch (Exception e2)
{
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
}
}
}
else
{
// The service has not been enabled to utilize our authentication tokens
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpNotFoundStatusMsg,
ProtoDefs.httpNotFoundStatusCode);
out.println(getAuthTokRespMsg.toString());
}
}
catch (Exception e)
{
System.err.println("GetAuthToken.invoke()- Exception: " + e.toString());
// Write out the response
try
{
GetAuthTokRespMsg getAuthTokRespMsg = new GetAuthTokRespMsg(ProtoDefs.httpServerErrorStatusMsg,
ProtoDefs.httpServerErrorStatusCode);
out.println(getAuthTokRespMsg.toString());
}
catch (Exception e2)
{
System.err.println("GetAuthToken.invoke()- Exception trying to construct response msg: " + e2.toString());
}
}
}
/*
* Return the method id.
*/
public String getId()
{
return "GetAuthToken";
}
}

View File

@ -0,0 +1,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);
}

View File

@ -0,0 +1,294 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
import java.io.*;
import java.util.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* IdenTokenConfig Class.
*
* This class obtains and maintains identity token configuration.
*
*/
public class IdenTokenConfig
{
// Well known identity token configuration settings
public final static String EncryptAttributes = "EncryptAttributes";
public final static String Attributes = "Attributes";
// Default configuration values
private String m_defaultEncryptAttributesValue = "false";
private String m_defaultAttributesValue = "sn";
private Map m_tokenSettingsMap;
private String[] m_identityAttributes;
/*
* Class for handling parsing events.
*/
private class SAXHandler extends org.xml.sax.helpers.DefaultHandler
{
private final static int AWAITING_ROOT_ELEMENT_START = 0;
private final static int AWAITING_SETTING_ELEMENT_START = 1;
private final static int AWAITING_SETTING_ELEMENT_DATA = 2;
private final static int AWAITING_SETTING_ELEMENT_END = 3;
private final static int DONE_PARSING = 4;
private final static String m_rootElementName = "settings";
private Map m_keyMap;
private int m_state;
private String m_currentKey;
/*
* Constructor
*/
public SAXHandler(Map keyMap)
{
super();
// Initialize our members
m_keyMap = keyMap;
m_state = AWAITING_ROOT_ELEMENT_START;
}
/*
* endDocument() implementation.
*/
public void endDocument () throws SAXException
{
// Verify that we are not in an invalid state
if (m_state != DONE_PARSING)
{
System.err.println("IdenTokenConfig SAXHandler.endDocument()- Invalid state" + m_state);
throw new SAXException("Invalid state at endDocument");
}
}
/*
* startElement() implementation.
*/
public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException
{
// Proceed based on our state
switch (m_state)
{
case AWAITING_ROOT_ELEMENT_START:
// Verify that we are processing the expected tag
if (m_rootElementName.equals(qName))
{
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_START;
}
else
{
System.err.println("IdenTokenConfig SAXHandler.startElement()- Un-expected element");
throw new SAXException("Un-expected element");
}
break;
case AWAITING_SETTING_ELEMENT_START:
// Keep track of the key name
m_currentKey = qName;
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_DATA;
break;
default:
System.err.println("IdenTokenConfig SAXHandler.startElement()- Invalid state " + m_state);
throw new SAXException("Invalid state at startElement");
}
}
/*
* endElement() immplementation.
*/
public void endElement (String uri, String name, String qName) throws SAXException
{
// Proceed based on our state
switch (m_state)
{
case AWAITING_SETTING_ELEMENT_DATA:
case AWAITING_SETTING_ELEMENT_END:
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_START;
break;
case AWAITING_SETTING_ELEMENT_START:
// Verify that we are processing the expected tag
if (m_rootElementName.equals(qName))
{
// Advance to the next state
m_state = DONE_PARSING;
}
else
{
System.err.println("IdenTokenConfig SAXHandler.endElement()- Un-expected element");
throw new SAXException("Un-expected element");
}
break;
default:
System.err.println("IdenTokenConfig SAXHandler.endElement()- Invalid state " + m_state);
throw new SAXException("Invalid state at endElement");
}
}
/*
* character() implementation.
*/
public void characters (char ch[], int start, int length) throws SAXException
{
// Consume the data if in the right state
if (m_state == AWAITING_SETTING_ELEMENT_DATA)
{
// Consume the data and add the key to map
// tbd - Add code to aggregate attributes specified as multiple elements
m_keyMap.put(m_currentKey, new String(ch, start, length));
// Advance to the next state
m_state = AWAITING_SETTING_ELEMENT_END;
}
}
}
/*
* Constructor which sets default configuration values.
*/
public IdenTokenConfig() throws Exception
{
System.err.println("IdenTokenConfig()- Default");
// Create a map to keep track of the token settings
m_tokenSettingsMap = new HashMap();
// Set the default settings in our map
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
}
/*
* Constructor.
*/
public IdenTokenConfig(String idenTokenSettingsFileName) throws Exception
{
System.err.println("IdenTokenConfig()-");
// Create a map to keep track of the token settings
m_tokenSettingsMap = new HashMap();
try
{
// Get an input stream to read from the token settings file
File f = new File(idenTokenSettingsFileName);
FileInputStream inStream = new FileInputStream(f);
// Parse the file
XMLReader xr = XMLReaderFactory.createXMLReader();
SAXHandler handler = new SAXHandler(m_tokenSettingsMap);
xr.setContentHandler(handler);
xr.setErrorHandler(handler);
InputSource source = new InputSource(inStream);
xr.parse(source);
inStream.close();
// Process the specified attributes
if (m_tokenSettingsMap.containsKey(Attributes) == false)
{
System.err.println("IdenTokenConfig()- Attributes not configured, defaulting them.");
m_tokenSettingsMap.put(Attributes, m_defaultAttributesValue);
}
String attributes = (String) m_tokenSettingsMap.get(Attributes);
m_identityAttributes = attributes.split(",");
}
catch (SAXException e)
{
System.err.println("IdenTokenConfig()- " + idenTokenSettingsFileName + " format error, exception: " + e.toString());
throw new Exception("IdenTokenConfig()- authtoken.settings format error");
}
catch (SecurityException e)
{
System.err.println("IdenTokenConfig()- SecurityException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
throw new Exception("IdenTokenConfig()- Not able to access file");
}
catch (FileNotFoundException e)
{
System.err.println("IdenTokenConfig()- File " + idenTokenSettingsFileName + " not found");
throw new Exception("IdenTokenConfig()- File not found");
}
catch (IOException e)
{
System.err.println("IdenTokenConfig()- IOException accessing " + idenTokenSettingsFileName + " Exception=" + e.toString());
throw new Exception("IdenTokenConfig()- Read error");
}
}
/*
* Returns the value associated with the specified setting.
*/
public String getSetting(String settingName) throws Exception
{
// Try to find the setting in our map
String value = (String) m_tokenSettingsMap.get(settingName);
if (value == null)
{
System.err.println("IdenTokenConfig.getSetting()- Did not find setting " + settingName);
// The setting is not in our map, check if it is one to
// which we have defaults.
if (settingName.equals(EncryptAttributes) == true)
{
value = m_defaultEncryptAttributesValue;
System.err.println("AuthTokenConfig.getSetting()- Assigning default value " + value);
// Add the key to the map so that it can be found quicker next time
m_tokenSettingsMap.put(EncryptAttributes, m_defaultEncryptAttributesValue);
}
}
else
{
System.err.println("IdenTokenConfig.getSetting()- Found setting " + settingName);
System.err.println("IdenTokenConfig.getSetting()- Setting value = " + value);
}
return value;
}
/*
* Returns the identity attributes that must be included in the token.
*/
public String[] getAttributes() throws Exception
{
return m_identityAttributes;
}
}

View File

@ -0,0 +1,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);
}
}

View File

@ -0,0 +1,93 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.authtoksvc;
/*
* IdentityToken Interface.
*
* This is the interface implemented by Identity Token Providers.
*/
public interface IdentityToken
{
/*
* Initialize the token with parameters.
*/
void initialize(String identityId,
String sourceName,
String targetService,
String targetHost,
SvcConfig svcConfig) throws Exception;
/*
* Initialize the token object with encoded token string.
*/
void initialize(String encodedToken) throws Exception;
/*
* Returns encoded token string.
*
* IMPORTANT: The token string can not contain the substring "]]>"
* within it.
*/
String getEncodedToken() throws Exception;
/*
* Returns a string containing the identity token provider type.
*/
String getProviderType() throws Exception;
/*
* Returns a string containing the identity id.
*/
String getIdentityId() throws Exception;
/*
* Returns a string containing the name associated with the
* identity source.
*/
String getSourceName() throws Exception;
/*
* Returns a string containing the url associated with the
* identity source.
*/
String getSourceUrl() throws Exception;
/*
* Returns a string containing the name of the targeted service.
*/
String getTargetService() throws Exception;
/*
* Returns a string containig the name of the host where the
* targeted service resides.
*/
String getTargetHost() throws Exception;
/*
* Returns the attributes of the identity.
*/
javax.naming.directory.Attributes getAttributes() throws Exception;
}

Some files were not shown because too many files have changed in this diff Show More