diff --git a/CASA-auth-token/server-java/AUTHORS b/CASA-auth-token/server-java/AUTHORS new file mode 100644 index 00000000..ba13017c --- /dev/null +++ b/CASA-auth-token/server-java/AUTHORS @@ -0,0 +1,2 @@ +Juan Carlos Luciani - jluciani@novell.com + diff --git a/CASA-auth-token/server-java/COPYING b/CASA-auth-token/server-java/COPYING new file mode 100644 index 00000000..b0ab9a23 --- /dev/null +++ b/CASA-auth-token/server-java/COPYING @@ -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 + diff --git a/CASA-auth-token/server-java/ChangeLog b/CASA-auth-token/server-java/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/CASA-auth-token/server-java/Jaas/.classpath b/CASA-auth-token/server-java/Jaas/.classpath new file mode 100644 index 00000000..e487b600 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/CASA-auth-token/server-java/Jaas/.project b/CASA-auth-token/server-java/Jaas/.project new file mode 100644 index 00000000..cdeff8ac --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/.project @@ -0,0 +1,17 @@ + + + CasaJaasSupport + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/CASA-auth-token/server-java/Jaas/Makefile.am b/CASA-auth-token/server-java/Jaas/Makefile.am new file mode 100644 index 00000000..990f2cdf --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/Makefile.am @@ -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 + diff --git a/CASA-auth-token/server-java/Jaas/README b/CASA-auth-token/server-java/Jaas/README new file mode 100644 index 00000000..78127335 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/README @@ -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 + * + ***********************************************************************/ +/*********************************************************************** + * + * 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. + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Jaas/TODO b/CASA-auth-token/server-java/Jaas/TODO new file mode 100644 index 00000000..87b7c803 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/TODO @@ -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. diff --git a/CASA-auth-token/server-java/Jaas/linux/Makefile.am b/CASA-auth-token/server-java/Jaas/linux/Makefile.am new file mode 100644 index 00000000..aa089734 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/linux/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/linux/client_keystore_setup.sh b/CASA-auth-token/server-java/Jaas/linux/client_keystore_setup.sh new file mode 100755 index 00000000..e1bf28f2 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/linux/client_keystore_setup.sh @@ -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 +# +######################################################################## + +############################################################# +# # +# 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 diff --git a/CASA-auth-token/server-java/Jaas/linux/crypto.properties b/CASA-auth-token/server-java/Jaas/linux/crypto.properties new file mode 100644 index 00000000..a491feb3 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/linux/crypto.properties @@ -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 diff --git a/CASA-auth-token/server-java/Jaas/make_test.sh b/CASA-auth-token/server-java/Jaas/make_test.sh new file mode 100755 index 00000000..f04aef0a --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/make_test.sh @@ -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 ***" + diff --git a/CASA-auth-token/server-java/Jaas/run_test.sh b/CASA-auth-token/server-java/Jaas/run_test.sh new file mode 100755 index 00000000..669f5210 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/run_test.sh @@ -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 + diff --git a/CASA-auth-token/server-java/Jaas/src/Makefile.am b/CASA-auth-token/server-java/Jaas/src/Makefile.am new file mode 100644 index 00000000..00e1ef35 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/Makefile.am b/CASA-auth-token/server-java/Jaas/src/com/Makefile.am new file mode 100644 index 00000000..34a83b0d --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/Makefile.am b/CASA-auth-token/server-java/Jaas/src/com/novell/Makefile.am new file mode 100644 index 00000000..2fb64053 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/Makefile.am b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/Makefile.am new file mode 100644 index 00000000..0c89b23b --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaLoginModule.java b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaLoginModule.java new file mode 100644 index 00000000..8b3c5377 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaLoginModule.java @@ -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 + * + ***********************************************************************/ + +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; + } +} diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaPrincipal.java b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaPrincipal.java new file mode 100644 index 00000000..ef97808e --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/CasaPrincipal.java @@ -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; + } +} diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/Makefile.am b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/Makefile.am new file mode 100644 index 00000000..d5618add --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/Makefile.am b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/Makefile.am new file mode 100644 index 00000000..3ec9cd6d --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.conf b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.conf new file mode 100644 index 00000000..c2fb8fc9 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.conf @@ -0,0 +1,3 @@ +testService { + com.novell.casa.jaas.CasaLoginModule Required debug=true; +}; \ No newline at end of file diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.java b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.java new file mode 100644 index 00000000..0cd43c85 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleApp.java @@ -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 + * + ***********************************************************************/ + +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()); + } + } + } +} diff --git a/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleAppCallbackHandler.java b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleAppCallbackHandler.java new file mode 100644 index 00000000..990ec5b2 --- /dev/null +++ b/CASA-auth-token/server-java/Jaas/src/com/novell/casa/jaas/sample/SampleAppCallbackHandler.java @@ -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 + * + ***********************************************************************/ + +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"); + } + } + } +} diff --git a/CASA-auth-token/server-java/Makefile.am b/CASA-auth-token/server-java/Makefile.am new file mode 100644 index 00000000..8865a701 --- /dev/null +++ b/CASA-auth-token/server-java/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/NEWS b/CASA-auth-token/server-java/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/CASA-auth-token/server-java/README b/CASA-auth-token/server-java/README new file mode 100644 index 00000000..616da5a3 --- /dev/null +++ b/CASA-auth-token/server-java/README @@ -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 + * + ***********************************************************************/ +/*********************************************************************** + * + * 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. + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/.project b/CASA-auth-token/server-java/Svc/.project new file mode 100644 index 00000000..a5fb4a20 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/.project @@ -0,0 +1,42 @@ + + + CasaAuthServer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.jst.j2ee.ejb.annotations.xdoclet.xdocletbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jem.workbench.JavaEMFNature + + + + identity-abstraction.jar + 1 + /home/jluciani/dev-local/bandit/trunk/IdentityAbstraction/build/identity-abstraction.jar + + + diff --git a/CASA-auth-token/server-java/Svc/Makefile.am b/CASA-auth-token/server-java/Svc/Makefile.am new file mode 100644 index 00000000..94bc32b5 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/Makefile.am @@ -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 + diff --git a/CASA-auth-token/server-java/Svc/README b/CASA-auth-token/server-java/Svc/README new file mode 100644 index 00000000..9d2a74fb --- /dev/null +++ b/CASA-auth-token/server-java/Svc/README @@ -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 + * + ***********************************************************************/ +/*********************************************************************** + * + * 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: + + + + 43200 + 10 + /etc/CASA/authtoken/svc/iaRealms.xml + 60 + signingKey + secret + + +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: + + + + + CorpTree + Krb5Authenticate + host/tokenserver.company.novell.com@KRB_REALM + + + CorpTree + PwdAuthenticate + + + + +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: + + + + 3600 + 10 + CasaIdentityToken + + +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: + + + + sn,groupMembership,guid + false + + +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: + + + + com.novell.casa.authtoksvc.Krb5Authenticate + WEB-INF/classes + host + + +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 + + + +SECURITY CONSIDERATIONS + +- TBD - + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/TODO b/CASA-auth-token/server-java/Svc/TODO new file mode 100644 index 00000000..7b79a6c6 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/TODO @@ -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. + diff --git a/CASA-auth-token/server-java/Svc/external/Makefile.am b/CASA-auth-token/server-java/Svc/external/Makefile.am new file mode 100644 index 00000000..0c3e2c8f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/external/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/external/README b/CASA-auth-token/server-java/Svc/external/README new file mode 100644 index 00000000..459f8a25 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/external/README @@ -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 + + diff --git a/CASA-auth-token/server-java/Svc/external/axis-ant.jar b/CASA-auth-token/server-java/Svc/external/axis-ant.jar new file mode 100644 index 00000000..17527ffd Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/axis-ant.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/axis.jar b/CASA-auth-token/server-java/Svc/external/axis.jar new file mode 100644 index 00000000..20b09a59 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/axis.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/commons-discovery-0.2.jar b/CASA-auth-token/server-java/Svc/external/commons-discovery-0.2.jar new file mode 100644 index 00000000..b8855484 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/commons-discovery-0.2.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/commons-logging-1.0.4.jar b/CASA-auth-token/server-java/Svc/external/commons-logging-1.0.4.jar new file mode 100644 index 00000000..b73a80fa Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/commons-logging-1.0.4.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/commons-logging-api.jar b/CASA-auth-token/server-java/Svc/external/commons-logging-api.jar new file mode 100644 index 00000000..209bcdfd Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/commons-logging-api.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/jaxrpc.jar b/CASA-auth-token/server-java/Svc/external/jaxrpc.jar new file mode 100644 index 00000000..a2c13d9a Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/jaxrpc.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/log4j-1.2.8.jar b/CASA-auth-token/server-java/Svc/external/log4j-1.2.8.jar new file mode 100644 index 00000000..493a3ccc Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/log4j-1.2.8.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/log4j.properties b/CASA-auth-token/server-java/Svc/external/log4j.properties new file mode 100644 index 00000000..3ca86f40 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/external/log4j.properties @@ -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 diff --git a/CASA-auth-token/server-java/Svc/external/saaj.jar b/CASA-auth-token/server-java/Svc/external/saaj.jar new file mode 100644 index 00000000..4ea696e7 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/saaj.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/wsdl4j-1.5.1.jar b/CASA-auth-token/server-java/Svc/external/wsdl4j-1.5.1.jar new file mode 100644 index 00000000..c6254ee6 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/wsdl4j-1.5.1.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/wss4j-1.5.0.jar b/CASA-auth-token/server-java/Svc/external/wss4j-1.5.0.jar new file mode 100644 index 00000000..90ae8826 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/wss4j-1.5.0.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/xalan.jar b/CASA-auth-token/server-java/Svc/external/xalan.jar new file mode 100644 index 00000000..73cf175f Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/xalan.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/xercesImpl.jar b/CASA-auth-token/server-java/Svc/external/xercesImpl.jar new file mode 100644 index 00000000..14c3162c Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/xercesImpl.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/xml-apis.jar b/CASA-auth-token/server-java/Svc/external/xml-apis.jar new file mode 100644 index 00000000..2dd83771 Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/xml-apis.jar differ diff --git a/CASA-auth-token/server-java/Svc/external/xmlsec-1.2.1.jar b/CASA-auth-token/server-java/Svc/external/xmlsec-1.2.1.jar new file mode 100644 index 00000000..512f93fd Binary files /dev/null and b/CASA-auth-token/server-java/Svc/external/xmlsec-1.2.1.jar differ diff --git a/CASA-auth-token/server-java/Svc/jaas.conf b/CASA-auth-token/server-java/Svc/jaas.conf new file mode 100644 index 00000000..1abeb22d --- /dev/null +++ b/CASA-auth-token/server-java/Svc/jaas.conf @@ -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; +}; diff --git a/CASA-auth-token/server-java/Svc/linux/CasaAuthPolicyEditor.sh b/CASA-auth-token/server-java/Svc/linux/CasaAuthPolicyEditor.sh new file mode 100755 index 00000000..bd859201 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaAuthPolicyEditor.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 $* + diff --git a/CASA-auth-token/server-java/Svc/linux/CasaAuthTokenSettingsEditor.sh b/CASA-auth-token/server-java/Svc/linux/CasaAuthTokenSettingsEditor.sh new file mode 100755 index 00000000..8a8261c4 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaAuthTokenSettingsEditor.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 $* + diff --git a/CASA-auth-token/server-java/Svc/linux/CasaAuthtokenSvcD b/CASA-auth-token/server-java/Svc/linux/CasaAuthtokenSvcD new file mode 100644 index 00000000..46847daf --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaAuthtokenSvcD @@ -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 + diff --git a/CASA-auth-token/server-java/Svc/linux/CasaBasicATSSetup.sh b/CASA-auth-token/server-java/Svc/linux/CasaBasicATSSetup.sh new file mode 100755 index 00000000..8271428f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaBasicATSSetup.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 + + + diff --git a/CASA-auth-token/server-java/Svc/linux/CasaIdenTokenSettingsEditor.sh b/CASA-auth-token/server-java/Svc/linux/CasaIdenTokenSettingsEditor.sh new file mode 100755 index 00000000..14c4e7c2 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaIdenTokenSettingsEditor.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 $* + diff --git a/CASA-auth-token/server-java/Svc/linux/CasaSvcSettingsEditor.sh b/CASA-auth-token/server-java/Svc/linux/CasaSvcSettingsEditor.sh new file mode 100755 index 00000000..adce8082 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/CasaSvcSettingsEditor.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 $* + diff --git a/CASA-auth-token/server-java/Svc/linux/Makefile.am b/CASA-auth-token/server-java/Svc/linux/Makefile.am new file mode 100644 index 00000000..90bbf431 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/linux/crypto.properties b/CASA-auth-token/server-java/Svc/linux/crypto.properties new file mode 100644 index 00000000..2f2e46ce --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/crypto.properties @@ -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 diff --git a/CASA-auth-token/server-java/Svc/linux/envvars b/CASA-auth-token/server-java/Svc/linux/envvars new file mode 100644 index 00000000..9991ed24 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/envvars @@ -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 + diff --git a/CASA-auth-token/server-java/Svc/linux/server_keystore_setup.sh b/CASA-auth-token/server-java/Svc/linux/server_keystore_setup.sh new file mode 100755 index 00000000..9c32988c --- /dev/null +++ b/CASA-auth-token/server-java/Svc/linux/server_keystore_setup.sh @@ -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 +# +######################################################################## + +######################################################################## +# +# 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 + diff --git a/CASA-auth-token/server-java/Svc/manifest/AuthPolicyEditor.txt b/CASA-auth-token/server-java/Svc/manifest/AuthPolicyEditor.txt new file mode 100644 index 00000000..861c25c1 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/manifest/AuthPolicyEditor.txt @@ -0,0 +1,2 @@ +Main-Class: com.novell.casa.authtoksvc.AuthPolicyEditor + diff --git a/CASA-auth-token/server-java/Svc/manifest/AuthTokenSettingsEditor.txt b/CASA-auth-token/server-java/Svc/manifest/AuthTokenSettingsEditor.txt new file mode 100644 index 00000000..7b9e5571 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/manifest/AuthTokenSettingsEditor.txt @@ -0,0 +1,2 @@ +Main-Class: com.novell.casa.authtoksvc.AuthTokenSettingsEditor + diff --git a/CASA-auth-token/server-java/Svc/manifest/IdenTokenSettingsEditor.txt b/CASA-auth-token/server-java/Svc/manifest/IdenTokenSettingsEditor.txt new file mode 100644 index 00000000..4cd099b9 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/manifest/IdenTokenSettingsEditor.txt @@ -0,0 +1,2 @@ +Main-Class: com.novell.casa.authtoksvc.IdenTokenSettingsEditor + diff --git a/CASA-auth-token/server-java/Svc/manifest/Makefile.am b/CASA-auth-token/server-java/Svc/manifest/Makefile.am new file mode 100644 index 00000000..dd9e5a55 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/manifest/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/manifest/SvcSettingsEditor.txt b/CASA-auth-token/server-java/Svc/manifest/SvcSettingsEditor.txt new file mode 100644 index 00000000..5423118f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/manifest/SvcSettingsEditor.txt @@ -0,0 +1,2 @@ +Main-Class: com.novell.casa.authtoksvc.SvcSettingsEditor + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/auth.policy b/CASA-auth-token/server-java/Svc/sampleConf/auth.policy new file mode 100644 index 00000000..d688b944 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/auth.policy @@ -0,0 +1,13 @@ + + + + CorpTree + Krb5Authenticate + host@authtokenserver.company.com + + + CorpTree + PwdAuthenticate + + + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/Krb5Authenticate/mechanism.settings b/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/Krb5Authenticate/mechanism.settings new file mode 100644 index 00000000..56110b52 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/Krb5Authenticate/mechanism.settings @@ -0,0 +1,6 @@ + + + com.novell.casa.authtoksvc.Krb5Authenticate + WEB-INF/classes + host@tokenserver.company.novell.com + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/PwdAuthenticate/mechanism.settings b/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/PwdAuthenticate/mechanism.settings new file mode 100644 index 00000000..2a5f60f0 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/auth_mechanisms/PwdAuthenticate/mechanism.settings @@ -0,0 +1,5 @@ + + + com.novell.casa.authtoksvc.PwdAuthenticate + WEB-INF/classes + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/authtoken.settings b/CASA-auth-token/server-java/Svc/sampleConf/authtoken.settings new file mode 100644 index 00000000..75f4b75c --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/authtoken.settings @@ -0,0 +1,4 @@ + + + 3600 + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/auth.policy b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/auth.policy new file mode 100644 index 00000000..0f7de72b --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/auth.policy @@ -0,0 +1,13 @@ + + + + CorpTree + Krb5Authenticate + host@tokenserver.company.novell.com + + + CorpTree + PwdAuthenticate + + + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/authtoken.settings b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/authtoken.settings new file mode 100644 index 00000000..75f4b75c --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/authtoken.settings @@ -0,0 +1,4 @@ + + + 3600 + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/identoken.settings b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/identoken.settings new file mode 100644 index 00000000..b1d40db3 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/enabled_services/appserver.companyname.com/testService/identoken.settings @@ -0,0 +1,6 @@ + + + false + sn,groupMembership + + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/iaRealms.xml b/CASA-auth-token/server-java/Svc/sampleConf/iaRealms.xml new file mode 100644 index 00000000..bc49eb2b --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/iaRealms.xml @@ -0,0 +1,25 @@ + + + + ldap://dirserver.companyname.com:389 + + simple + cn=admin,o=companyname + password + + + + + + CorpTree + + + + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/identoken.settings b/CASA-auth-token/server-java/Svc/sampleConf/identoken.settings new file mode 100644 index 00000000..ac54afb5 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/identoken.settings @@ -0,0 +1,6 @@ + + + false + sn + + diff --git a/CASA-auth-token/server-java/Svc/sampleConf/svc.settings b/CASA-auth-token/server-java/Svc/sampleConf/svc.settings new file mode 100644 index 00000000..c1465cc0 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/sampleConf/svc.settings @@ -0,0 +1,5 @@ + + + /home/jluciani/jakarta-tomcat-5.0.28/webapps/CasaAuthTokenSvc/WEB-INF/conf/iaRealms.xml + 43200 + diff --git a/CASA-auth-token/server-java/Svc/src/Makefile.am b/CASA-auth-token/server-java/Svc/src/Makefile.am new file mode 100644 index 00000000..00e1ef35 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/src/com/Makefile.am b/CASA-auth-token/server-java/Svc/src/com/Makefile.am new file mode 100644 index 00000000..34a83b0d --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/Makefile.am b/CASA-auth-token/server-java/Svc/src/com/novell/Makefile.am new file mode 100644 index 00000000..2fb64053 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/Makefile.am b/CASA-auth-token/server-java/Svc/src/com/novell/casa/Makefile.am new file mode 100644 index 00000000..2ebc7e01 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/Makefile.am @@ -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 +# +####################################################################### + +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 + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechConfig.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechConfig.java new file mode 100644 index 00000000..678f0fb0 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechConfig.java @@ -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 + * + ***********************************************************************/ + +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; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechanism.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechanism.java new file mode 100644 index 00000000..a03dc277 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthMechanism.java @@ -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 + * + ***********************************************************************/ + +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(); +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthPolicyEditor.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthPolicyEditor.java new file mode 100644 index 00000000..de3a471f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthPolicyEditor.java @@ -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 + * + ***********************************************************************/ + +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 = + "\n" + + "\n" + + "\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); + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthReqMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthReqMsg.java new file mode 100644 index 00000000..7b9a55ab --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * realm value + * mechanism id + * mechanism token data + * + * + */ +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; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthRespMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthRespMsg.java new file mode 100644 index 00000000..6e1bc49f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * lifetime valuesession token data + * + * + * The format of the message is as follows when the response does not + * include a session token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.sessionTokenElementName + ">" + + "<" + ProtoDefs.lifetimeElementName + ">" + sessionTokenLifetime + "" + + sessionToken + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthToken.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthToken.java new file mode 100644 index 00000000..6cce42ca --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthToken.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * Identity Token typeidentity token data + * + * + */ +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 = + "" + + "" + + " " + + " " + + " " + + ""; + + 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 Message 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; + } + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenConfig.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenConfig.java new file mode 100644 index 00000000..27d40aa3 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenConfig.java @@ -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 + * + ***********************************************************************/ + +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; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenSettingsEditor.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenSettingsEditor.java new file mode 100644 index 00000000..e682b958 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/AuthTokenSettingsEditor.java @@ -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 + * + ***********************************************************************/ + +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 = + "\n" + + "\n" + + "\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); + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Authenticate.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Authenticate.java new file mode 100644 index 00000000..4e5115a3 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Authenticate.java @@ -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 + * + ***********************************************************************/ + +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"; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Base64Coder.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Base64Coder.java new file mode 100644 index 00000000..5584b692 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Base64Coder.java @@ -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. +* +*

+* Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
+* License: This is "Open Source" software and released under the GNU/LGPL license. +* It is provided "as is" without warranty of any kind. Please contact the author for other licensing arrangements.
+* Home page: www.source-code.biz
+* +*

+* Version history:
+* 2003-07-22 Christian d'Heureuse (chdh): Module created.
+* 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>> 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 + * + ***********************************************************************/ + +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: + * + * + * + * identity id + * identity data source name + * identity data source url + * target service name + * target host name + * + * attribute value + * attribute2 value + * ... + * + * + * + * + * 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 + "\r\n"); + sb.append("<" + sourceNameElementName + ">" + sourceName + "\r\n"); + sb.append("<" + sourceUrlElementName + ">" + m_sourceUrl + "\r\n"); + sb.append("<" + targetServiceElementName + ">" + m_service + "\r\n"); + sb.append("<" + targetHostElementName + ">" + m_host + "\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)) + "" + "\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 + "" + "\r\n"); + } + } + } + } + sb.append("" + "\r\n"); + sb.append("" + "\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"); + } + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/EnabledSvcsConfig.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/EnabledSvcsConfig.java new file mode 100644 index 00000000..5dc76489 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/EnabledSvcsConfig.java @@ -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 + * + ***********************************************************************/ + +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; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicy.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicy.java new file mode 100644 index 00000000..3517727f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicy.java @@ -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 + * + ***********************************************************************/ + +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"; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyReqMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyReqMsg.java new file mode 100644 index 00000000..b19a3d47 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * service name + * host name + * + * + */ +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; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyRespMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyRespMsg.java new file mode 100644 index 00000000..7b122473 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthPolicyRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * authentication policy data + * + * + * The format of the message is as follows when the response does not + * include an authentication token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.authPolicyElementName + ">" + authPolicy + "" + "\r\n"); + sb.append("" + "\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; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokReqMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokReqMsg.java new file mode 100644 index 00000000..9a98dbd8 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokReqMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * service name + * host name + * session token data + * + * + */ +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; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokRespMsg.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokRespMsg.java new file mode 100644 index 00000000..01dd193d --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthTokRespMsg.java @@ -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 + * + ***********************************************************************/ + +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: + * + * + * + * OK200 + * lifetime valueauthentication token data + * + * + * The format of the message is as follows when the response does not + * include an authentication token. + * + * + * + * status descriptionstatus code + * + * + * 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 + "" + + statusCode + "" + "\r\n"); + sb.append("" + "\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.httpOkStatusCode + "" + "\r\n"); + sb.append("<" + ProtoDefs.authTokenElementName + ">" + + "<" + ProtoDefs.lifetimeElementName + ">" + authTokenLifetime + "" + + authToken + "" + "\r\n"); + sb.append("" + "\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; + } +} + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthToken.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthToken.java new file mode 100644 index 00000000..9f6a1a56 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/GetAuthToken.java @@ -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 + * + ***********************************************************************/ + +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"; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IVerifySetting.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IVerifySetting.java new file mode 100644 index 00000000..17aefad2 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IVerifySetting.java @@ -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 + * + ***********************************************************************/ + +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); +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenConfig.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenConfig.java new file mode 100644 index 00000000..d1b77f29 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenConfig.java @@ -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 + * + ***********************************************************************/ + +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; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenSettingsEditor.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenSettingsEditor.java new file mode 100644 index 00000000..17e8631f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdenTokenSettingsEditor.java @@ -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 + * + ***********************************************************************/ + +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 = + "\n" + + "\n" + + "\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); + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdentityToken.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdentityToken.java new file mode 100644 index 00000000..721157e7 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/IdentityToken.java @@ -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 + * + ***********************************************************************/ + +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; +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5Authenticate.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5Authenticate.java new file mode 100644 index 00000000..03d887e2 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5Authenticate.java @@ -0,0 +1,263 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.Serializable; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchResult; +import javax.naming.directory.SearchControls; + +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; + +import org.bandit.ia.IAContext; + +/** + * Krb5Authenticate Class. + * + * This class implementes an authentication mechanism for + * the processing of authentication requests utilizing a + * Kerberos5 token. + * + */ +public class Krb5Authenticate implements AuthMechanism, Serializable +{ + private SvcConfig m_svcConfig; + private AuthMechConfig m_mechConfig; + + /* + * GSS Long Lived variables + */ + protected GSSManager m_manager; + protected Oid m_krb5; + protected GSSName m_svcName; + protected GSSCredential m_credential; + + /* + * Krb5 Token Class. + */ + private class Krb5Token + { + private String m_principalName = ""; + + /* + * The format of the Krb5 token is as follows: + * + * Base64.encode(GSS-API Token data)); + */ + public Krb5Token(String encodedToken, Krb5Authenticate parent) throws Exception + { + // Decode the token + char[] tokenChars = new char[encodedToken.length()]; + encodedToken.getChars(0, tokenChars.length, tokenChars, 0); + byte[] tokenBytes = Base64Coder.decode(tokenChars); + + try + { + // Create a context and validate the token + GSSContext context = parent.m_manager.createContext(parent.m_credential); + System.err.println("tokenLength = " + tokenBytes.length); + context.acceptSecContext(tokenBytes, 0, tokenBytes.length); + + // Save the principal name of the authenticated entity + GSSName principalName = context.getSrcName(); + m_principalName = principalName.toString(); + + // Clean up + context.dispose(); + } + catch (GSSException e) + { + System.err.println("Krb5Authenticate Krb5Token()- GSS Exception caught: " + e.getLocalizedMessage()); + throw new Exception("Authentication Failure"); + } + } + + /* + * Returns the name of the authenticated principal + */ + public String getPrincipalName() + { + return m_principalName; + } + } + + /* + * Constructor + */ + public Krb5Authenticate() throws Exception + { + // Nothing to do at this time + } + + /* + * Initialize the mechanism. + */ + public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception + { + m_svcConfig = svcConfig; + m_mechConfig = mechConfig; + + String servicePrincipal = mechConfig.getSetting(AuthMechConfig.Krb5ServicePrincipalName); + if (servicePrincipal != null) + { + try + { + // Make sure that the system property "javax.security.auth.useSubjectCredsOnly" + // is set to "false" to avoid having to utilize JAAS (at least if using IBM's JVM) + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + // Initalize our GSS variables + // + // Get an instance of the default GSSManager + m_manager = GSSManager.getInstance(); + + // Create an OID specifying the Krb5 mechanism + m_krb5 = new Oid("1.2.840.113554.1.2.2"); + + // Create our host based service name + m_svcName = m_manager.createName(servicePrincipal, + GSSName.NT_HOSTBASED_SERVICE, + m_krb5); + + // Now acquire our credentials + m_credential = m_manager.createCredential(m_svcName, + GSSCredential.INDEFINITE_LIFETIME, + m_krb5, + GSSCredential.ACCEPT_ONLY); + } + catch (GSSException e) + { + System.err.println("Krb5Authenticate()- GSS Exception caught: " + e.getLocalizedMessage()); + throw new Exception("Failed to instantiate needed GSS objects"); + } + } + else + { + System.err.println("Krb5Authenticate()- Service Principal Name not configured"); + throw new Exception("Service Principal Name not configured"); + } + } + + /* + * invoke() implementation. + */ + public String invoke(AuthReqMsg authReqMsg) throws Exception + { + String identId = null; + + try + { + System.err.println("Krb5Authenticate.invoke()"); + + // Now parse the Kerberos Token + Krb5Token krb5Token = new Krb5Token(authReqMsg.getAuthMechToken(), this); + + // Open a directory context and use it to identify the users + // associated with the specified surname. + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); + env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); + env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm()); + + DirContext ctx = new InitialDirContext(env); + + // Now search for a user with a matching kerberos principal name. + // + // Set up a search control so that the search is scoped to the sub-tree + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit + String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext); + if (searchContext == null) + { + // A start search context was not configured, start from the root. + searchContext = ""; + } + + // Perform the search + NamingEnumeration answer = ctx.search(searchContext, + "(krbPrincipalName={0})", + new String[] {krb5Token.getPrincipalName()}, + controls); + + // Proceed based on the result of the search + if (answer.hasMore()) + { + // The search succeeded, set the identity id. + SearchResult sr = (SearchResult)answer.next(); + if (searchContext.equals("")) + { + identId = sr.getNameInNamespace(); + } + else + { + identId = sr.getName() + "," + searchContext; + } + } + else + { + System.err.println("Krb5Authenticate.invoke()- No matching identity entities found"); + } + } + catch (NamingException e) + { + // Log the error + System.err.println("Krb5Authenticate.invoke()- NamingException: " + e.getExplanation()); + } + catch (Exception e) + { + System.err.println("Krb5Authenticate.invoke()- Exception: " + e.toString()); + } + + // Return the authentication result + return identId; + } + + /* + * Return the mechanism id. + */ + public String getId() + { + return "Krb5Authenticate"; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5_mechanism.settings b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5_mechanism.settings new file mode 100644 index 00000000..9c37571c --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Krb5_mechanism.settings @@ -0,0 +1,6 @@ + + + This is the authentication mechanism for the Krb5Authenticate scheme. The Krb5Authenticate scheme authenticates entities using Kerberos-V tokens. + com.novell.casa.authtoksvc.Krb5Authenticate + WEB-INF/classes + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Makefile.am b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Makefile.am new file mode 100644 index 00000000..f92118b9 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Makefile.am @@ -0,0 +1,70 @@ +####################################################################### +# +# Copyright (C) 2006 Novell, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Author: Juan Carlos Luciani +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +JAVAFILES = ProtoDefs.java \ + AuthMechConfig.java \ + SvcConfig.java \ + IdenTokenConfig.java \ + AuthTokenConfig.java \ + EnabledSvcsConfig.java \ + AuthMechanism.java \ + Authenticate.java \ + RpcMethod.java \ + Rpc.java \ + GetAuthPolicy.java \ + Base64Coder.java \ + AuthReqMsg.java \ + AuthRespMsg.java \ + IdentityToken.java \ + CasaIdentityToken.java \ + AuthToken.java \ + GetAuthPolicyReqMsg.java \ + GetAuthPolicyRespMsg.java \ + GetAuthToken.java \ + GetAuthTokReqMsg.java \ + GetAuthTokRespMsg.java \ + Krb5Authenticate.java \ + PwdAuthenticate.java \ + SessionToken.java \ + WSSecurity.java \ + AuthPolicyEditor.java \ + AuthTokenSettingsEditor.java \ + IdenTokenSettingsEditor.java \ + IVerifySetting.java \ + SettingsFileUtil.java \ + SvcSettingsEditor.java + +EXTRA_DIST = $(JAVAFILES) \ + Krb5_mechanism.settings \ + Pwd_mechanism.settings + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/ProtoDefs.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/ProtoDefs.java new file mode 100644 index 00000000..e878a02d --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/ProtoDefs.java @@ -0,0 +1,86 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +/* + * ProDefs Class. + * + * This class contains constants utilized in the Casa Client/Server + * protocol. + * + */ +public class ProtoDefs +{ + + /* + * XML Declaration used in the Casa Client/Server protocol + */ + public final static String xmlDeclaration = ""; + + /* + * XML Element Name Constants for the documents exchanged between the + * Casa Client and the Casa Server. + */ + public final static String authRequestElementName = "auth_req"; + public final static String authResponseElementName = "auth_resp"; + public final static String getAuthPolicyRequestElementName = "get_auth_policy_req"; + public final static String getAuthPolicyResponseElementName = "get_auth_policy_resp"; + public final static String getAuthTokRequestElementName = "get_auth_tok_req"; + public final static String getAuthTokResponseElementName = "get_auth_tok_resp"; + public final static String authMechTokenElementName = "auth_mech_token"; + public final static String statusElementName = "status"; + public final static String sessionTokenElementName = "session_token"; + public final static String authTokenElementName = "auth_token"; + public final static String authPolicyElementName = "auth_policy"; + public final static String identTokenElementName = "ident_token"; + public final static String lifetimeElementName = "lifetime"; + public final static String signatureElementName = "signature"; + public final static String typeElementName = "type"; + public final static String descriptionElementName = "description"; + public final static String serviceElementName = "service"; + public final static String hostElementName = "host"; + public final static String identIdElementName = "ident_id"; + public final static String realmElementName = "realm"; + public final static String authSourceElementName = "auth_source"; + public final static String mechanismElementName = "mechanism"; + public final static String mechanismInfoElementName = "mechanism_info"; + + /* + * Configurable operating parameters + */ + public String sessionTokenLifetime = "360"; + + /* + * HTTP Status Codes and Messages + */ + public final static String httpOkStatusCode = "200"; + public final static String httpOkStatusMsg = "OK"; + public final static String httpUnauthorizedStatusCode = "401"; + public final static String httpUnauthorizedStatusMsg = "Unauthorized"; + public final static String httpNotFoundStatusCode = "404"; + public final static String httpNotFoundStatusMsg = "Not Found"; + public final static String httpServerErrorStatusCode = "500"; + public final static String httpServerErrorStatusMsg = "Internal Server Error"; +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/PwdAuthenticate.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/PwdAuthenticate.java new file mode 100644 index 00000000..9e8b612f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/PwdAuthenticate.java @@ -0,0 +1,233 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.Serializable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringReader; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.DirContext; +import javax.naming.directory.Attributes; +import javax.naming.directory.SearchResult; +import javax.naming.directory.SearchControls; +import javax.naming.NamingException; + +import org.bandit.ia.IAContext; + + +/** + * PwdAuthenticate Class. + * + * This class implementes an authentication mechanism for + * the processing of authentication requests utilizing a + * username/password token. + * + */ +public class PwdAuthenticate implements AuthMechanism, Serializable +{ + private SvcConfig m_svcConfig; + private AuthMechConfig m_mechConfig; + + /* + * Password Token Class. + */ + private class PwToken + { + private String m_username = ""; + private String m_password = ""; + + /* + * The format of the Pw token is as follows: + * + * Base64.encode(new String("username\r\n" + "password\r\n")); + */ + public PwToken(String encodedToken) throws IOException + { + // Decode the token + String token = Base64Coder.decode(encodedToken); + + BufferedReader tokenReader = new BufferedReader(new StringReader(token)); + + // The second line contains the "username" + m_username = tokenReader.readLine(); + + // The third line contains the "password" + m_password = tokenReader.readLine(); + } + + /* + * Returns the username + */ + public String getUsername() + { + return m_username; + } + + /* + * Returns the password + */ + public String getPassword() + { + return m_password; + } + } + + /* + * Constructor + */ + public PwdAuthenticate() throws Exception + { + // Nothing to do at this time + } + + /* + * Initialize the mechanism. + */ + public void init(SvcConfig svcConfig, AuthMechConfig mechConfig) throws Exception + { + m_svcConfig = svcConfig; + m_mechConfig = mechConfig; + } + + /* + * invoke() implementation. + */ + public String invoke(AuthReqMsg authReqMsg) throws Exception + { + String identId = null; + + try + { + System.err.println("PwdAuthenticate.invoke()"); + + // Now parse the PW Token + PwToken pwToken = new PwToken(authReqMsg.getAuthMechToken()); + + // Open a directory context and use it to identify the users + // associated with the specified surname. + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); + env.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); + env.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm()); + + DirContext ctx = new InitialDirContext(env); + + // Now search for a user with a matching surname. + // + // Set up a search control so that the search is scoped to the sub-tree + SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + // Obtain the start search context - tbd - this will be removed once the functionality flows into Bandit + String searchContext = m_svcConfig.getSetting(SvcConfig.StartSearchContext); + if (searchContext == null) + { + // A start search context was not configured, start from the root. + searchContext = ""; + } + + // Perform the search + NamingEnumeration answer = ctx.search(searchContext, + "(cn={0})", + new String[] {pwToken.getUsername()}, + controls); + if (!answer.hasMore()) + { + System.err.println("PwdAuthenticate.invoke()- No matching identity entities found"); + } + + // Enumerate through the users returned checking the password + while (answer.hasMore()) + { + SearchResult sr = (SearchResult)answer.next(); + + // Open a directory context for the user as a way of verifying its password + try + { + Hashtable env2 = new Hashtable(); + env2.put(Context.INITIAL_CONTEXT_FACTORY, "org.bandit.ia.IAInitialCtxFactory"); + env2.put(IAContext.IA_REALM_CONFIG_LOCATION, m_svcConfig.getSetting(SvcConfig.IdentityAbstractionConfigFile)); + env2.put(IAContext.IA_REALM_SELECTOR, authReqMsg.getRealm()); + env2.put(Context.SECURITY_AUTHENTICATION, "simple"); + env2.put(Context.SECURITY_PRINCIPAL, sr.getNameInNamespace()); + env2.put(Context.SECURITY_CREDENTIALS, pwToken.getPassword()); + + if ((new InitialDirContext(env2)) != null) + { + // The password must be valid, set the identity Id. + if (searchContext.equals("")) + { + identId = sr.getName(); + } + else + { + identId = sr.getName() + "," + searchContext; + } + break; + } + } + catch (NamingException e) + { + System.err.println("PwdAuthenticate.invoke()- NamingException: " + e.getExplanation()); + } + } + + // Check if we did not resolve the identity + if (identId == null) + { + System.err.println("PwdAuthenticate.invoke()- Failed to resolve identity for entity " + pwToken.getUsername()); + } + } + catch (NamingException e) + { + // Log the error + System.err.println("PwdAuthenticate.invoke()- NamingException on Proxy User: " + e.getExplanation()); + } + catch (Exception e) + { + System.err.println("PwdAuthenticate.invoke()- Exception: " + e.toString()); + } + + // Return the authentication result + return identId; + } + + /* + * Return the mechanism id. + */ + public String getId() + { + return "PwdAuthenticate"; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Pwd_mechanism.settings b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Pwd_mechanism.settings new file mode 100644 index 00000000..5532e361 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Pwd_mechanism.settings @@ -0,0 +1,6 @@ + + + This is the authentication mechanism for the PwdAuthenticate scheme. The PwdAuthenticate scheme authenticates entities using username/password tokens. + com.novell.casa.authtoksvc.PwdAuthenticate + WEB-INF/classes + diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Rpc.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Rpc.java new file mode 100644 index 00000000..18a9f439 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/Rpc.java @@ -0,0 +1,299 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.util.*; + +import java.io.*; +import java.io.PrintWriter; + +import javax.servlet.*; +import javax.servlet.ServletException; +import javax.servlet.http.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + + +/** + * Rpc Servlet Class. + * + * This class processes Rpcs to the Authentication Token Service. + * + */ +public class Rpc extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet +{ + private static final long serialVersionUID = -8264027868130334613L; + + private String m_appFolderPath = null; + private String m_configFolderPath = null; + + private boolean m_enabledSvcsOnly; + + protected ReconfigureThread m_reconfigureThread = null; + protected int m_reconfigureInterval; // seconds + + private Map m_methodsMap; + + /* + * Reconfigure Thread Class. + * + * This class implements a runnable thread that reconfigures an Rpc Servlet instance. + * + */ + private class ReconfigureThread implements Runnable + { + private Rpc m_rpc; + private Thread m_thread; + + /* + * Constructor. + */ + public ReconfigureThread (Rpc rpc) + { + m_rpc = rpc; + m_thread = new Thread(this); + m_thread.start(); + } + + /* + * run() implementation. + */ + public void run () + { + System.err.println("ReconfigureThread.run()- Running"); + + while (true) + { + // Sleep an ammount equal the reconfigure interval for the Rpc + try + { + m_thread.sleep(m_rpc.m_reconfigureInterval * 1000); + } + catch (InterruptedException e) { /* nothing to do */ } + + // Re-configure the Rpc servlet. + try + { + m_rpc.configureServlet(); + + // Check if it is no longer necessary to re-configure the servlet + if (m_rpc.m_reconfigureInterval == 0) + { + System.err.println("ReconfigureTask.run()- Configuration changed to no longer perform timed re-configuration"); + break; + } + } + catch (Exception e) + { + System.err.println("ReconfigureTask.run()- Exception caught during re-configure process, " + e.toString()); + } + } + } + + /* + * stop() implementation. + */ + public void stop () + { + m_thread.stop(); + } + } + + /* + * Constructor. + */ + public Rpc () + { + super(); + } + + /* + * configureServlet() implementation. + */ + protected void configureServlet () throws Exception + { + // Read service configuration + SvcConfig svcConfig = new SvcConfig(m_appFolderPath, m_configFolderPath); + + // Get the reconfigure interval + try + { + m_reconfigureInterval = Integer.parseInt(svcConfig.getSetting(SvcConfig.ReconfigureInterval)); + } + catch (NumberFormatException e) + { + System.err.println("Rpc.configureServlet()- Invalid reconfigure interval value format"); + m_reconfigureInterval = Integer.parseInt(SvcConfig.DefaultReconfigureIntervalValue); + } + + // Read enabled services configuration + EnabledSvcsConfig enabledSvcsConfig = new EnabledSvcsConfig(m_configFolderPath, m_enabledSvcsOnly); + + // Create a map to keep track of the Rpc methods + Map methodsMap = new HashMap(); + + // Instantiate the Rpc Methods + RpcMethod getAuthPolicy = new GetAuthPolicy(); + getAuthPolicy.init(svcConfig, enabledSvcsConfig); + methodsMap.put(getAuthPolicy.getId(), getAuthPolicy); + + RpcMethod authenticate = new Authenticate(); + authenticate.init(svcConfig, enabledSvcsConfig); + methodsMap.put(authenticate.getId(), authenticate); + + RpcMethod getAuthToken = new GetAuthToken(); + getAuthToken.init(svcConfig, enabledSvcsConfig); + methodsMap.put(getAuthToken.getId(), getAuthToken); + + // Set the map as the methods map used by the servlet + m_methodsMap = methodsMap; + } + + /* + * init() implementation. + */ + public void init (ServletConfig config) throws ServletException + { + super.init(config); + + System.err.println("Rpc.init()"); + + try + { + // Get the path to our configuration folder + // + // First check if it has been specified via a system property + ServletContext context = config.getServletContext(); + m_appFolderPath = context.getRealPath(File.separator); + m_configFolderPath = System.getProperty("com.novell.casa.authtoksvc.config"); + if (m_configFolderPath == null) + { + // The path to the svc config folder was not specified via a system + // property, assume that it's location is off the WEB-INF folder for + // our web application. + m_configFolderPath = m_appFolderPath + "WEB-INF/conf"; + } + + // Check if we support services that are not explicitedly enabled + String enabledSvcsOnly = System.getProperty("com.novell.casa.authtoksvc.enabled_svcs_only"); + if (enabledSvcsOnly != null + && enabledSvcsOnly.compareToIgnoreCase("true") == 0) + { + m_enabledSvcsOnly = true; + } + else + { + m_enabledSvcsOnly = false; + } + + // Configure ourselves + configureServlet(); + + // Check if we must start a thread to periodically reconfigure ourselves + if (m_reconfigureInterval != 0) + { + m_reconfigureThread = new ReconfigureThread(this); + } + } + catch (Exception e) + { + System.err.println("Rpc.init()- Exception caught: " + e.toString()); + throw new ServletException("Exception caught while instantiating Rpc methods"); + } + } + + /* + * destroy() implementation. + */ + public void destroy () + { + super.destroy(); + + System.err.println("Rpc.destroy()"); + + // Stop our re-configure thread + if (m_reconfigureThread != null) + { + m_reconfigureThread.stop(); + } + } + + /* + * doGet() implementation. + */ + protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + doPost(request, response); + } + + /* + * doPost() implementation. + */ + protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException + { + // Get ready to send back a reply + response.setContentType("text/html"); + PrintWriter out = response.getWriter(); + + try + { + // Obtain the input stream and execute the requested method + InputStream inStream = request.getInputStream(); + + String requestedMethod = request.getParameter("method"); + if (requestedMethod != null) + { + // Get the necessary method + RpcMethod method = (RpcMethod) m_methodsMap.get(requestedMethod); + if (method != null) + { + // Invoke the method to process the Rpc + method.invoke(inStream, out); + } + else + { + // Unsupported method + System.err.println("Rpc.doPost()- Unsupported method"); + response.sendError(response.SC_BAD_REQUEST); + } + } + else + { + // Missing method parameter + System.err.println("Rpc.doPost()- Missing method parameter"); + response.sendError(response.SC_BAD_REQUEST); + } + } + catch (Exception e) + { + // tbd + System.err.println("Rpc.doPost()- Exception caught: " + e.toString()); + response.sendError(response.SC_INTERNAL_SERVER_ERROR); + } + + // Done sending out the reply + out.close(); + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/RpcMethod.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/RpcMethod.java new file mode 100644 index 00000000..3e23a49b --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/RpcMethod.java @@ -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 + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.*; +import java.io.PrintWriter; +import java.util.*; + + +/* + * RpcMethod Interface. + * + * This is the interface implemented by Rpc Methods. + */ +public interface RpcMethod +{ + /* + * Initialize the Rpc method. + */ + void init(SvcConfig svcConfig, EnabledSvcsConfig enabledSvcsConfig) throws Exception; + + /* + * Process Rpc. + */ + void invoke(InputStream inStream, PrintWriter out) throws IOException; + + /* + * Return the method id. + */ + String getId(); +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SessionToken.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SessionToken.java new file mode 100644 index 00000000..081b2915 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SessionToken.java @@ -0,0 +1,232 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.ByteArrayInputStream; + +import org.apache.axis.Message; +import org.apache.axis.MessageContext; +import org.apache.axis.client.AxisClient; +import org.apache.axis.configuration.NullProvider; +import org.apache.axis.message.SOAPEnvelope; +import org.apache.axis.message.SOAPBody; +import org.apache.axis.message.MessageElement; + +import javax.xml.namespace.QName; +import java.io.*; + +/* +* SessionToken class. +* +* This class constructs sessions tokens that clients can present to an ATS +* to prove that an entity has been authenticated to a particular realm. +* The session token consists of a SOAP message secured with WSSecurity +* with the appropriate elements signed and with a timestamp. The body of +* the SOAP message is as follows: +* +* +* realm value +* identity id value +* +* +*/ +public class SessionToken +{ + + private String m_id = null; + private String m_realm = null; + private String m_token; + + static final String sessionTokenSoapMsg = + "" + + "" + + " " + + " " + + " " + + ""; + + static final private MessageContext axisMsgContext = new MessageContext(new AxisClient(new NullProvider())); + + + /* + * Constructor + */ + public SessionToken(String id, + String realm, + String lifetime, + SvcConfig svcConfig) throws Exception + { + // Save copies of the input parameters + m_id = id; + m_realm = realm; + + // Create SessionTokenMessage + Message sessionTokenMessage = getMessage(realm, + id, + Integer.valueOf(lifetime).intValue(), + svcConfig); + + // Now save the message as a string + OutputStream outStream = new ByteArrayOutputStream(); + sessionTokenMessage.writeTo(outStream); + m_token = outStream.toString(); + outStream.close(); + } + + /* + * Constructor given a session token string. The constructor + * validates the token as part of its processing. + */ + public SessionToken(String token) throws Exception + { + // Decode the token string + m_token = Base64Coder.decode(token); + + // Now instantiate a SOAP message with the string + InputStream inStream = new ByteArrayInputStream(m_token.getBytes()); + Message message = new Message(inStream); + + // Get access to the SOAP Envelope + SOAPEnvelope envelope = message.getSOAPEnvelope(); + + // Verify the message + if (WSSecurity.verifyMessage(envelope)) + { + // Message verification succeded, now obtain the realm and identity id + // from the message body. + SOAPBody body = (SOAPBody) envelope.getBody(); + QName sessionTokenElementName = new QName("session_token"); + MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName); + QName realmElementName = new QName("realm"); + MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName); + if (realmElement != null) + { + m_realm = realmElement.getChildNodes().item(0).getNodeValue(); + } + QName identIdElementName = new QName("ident_id"); + MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName); + if (identIdElement != null) + { + m_id = identIdElement.getChildNodes().item(0).getNodeValue(); + } + + if (m_realm == null || m_id == null) + { + System.out.println("SessionToken()- Required data missing from session token"); + throw new Exception("Error: Required data missing from session Token"); + } + } + else + { + // Message verification failed + System.err.println("SessionToken()- Invalid Session Token"); + throw new Exception("Invalid Session Token"); + } + } + + /** + * Get SessionToken SOAP Message + * + * @param realm String containing the identity token that should be part of the message + * @param identityId String containing the identity token type + * @param lifetime Lifetime that should be specified in the message timestamp (seconds) + * @param svcConfig Service Config object + * @return Message SessionToken message, null if the method fails. + */ + private Message getMessage(String realm, + String identityId, + int lifetime, + SvcConfig svcConfig) + { + Message secureMessage; + + try + { + // Build SOAP Message with an identity token in the body + // + // First create a message and obtain its body + InputStream inStream = new ByteArrayInputStream(sessionTokenSoapMsg.getBytes()); + Message message = new Message(inStream); + message.setMessageContext(axisMsgContext); + SOAPBody body = (SOAPBody) message.getSOAPBody(); + + // Get access to the session_token element + QName sessionTokenElementName = new QName("session_token"); + MessageElement sessionTokenElement = body.getChildElement(sessionTokenElementName); + + // Get access to the realm element and set its value + QName realmElementName = new QName("realm"); + MessageElement realmElement = sessionTokenElement.getChildElement(realmElementName); + realmElement.addTextNode(realm); + + // Get access to the ident_id element and set its value + QName identIdElementName = new QName("ident_id"); + MessageElement identIdElement = sessionTokenElement.getChildElement(identIdElementName); + identIdElement.addTextNode(identityId); + + // Now we need to secure the SOAP message that we created, we are doing to + // do so by adding a timestamp and signing the timestamp as well as the body. + // To do this we are going to leverage WS-Security. + secureMessage = WSSecurity.secureSOAPEnvelope(message.getSOAPEnvelope(), + lifetime, + svcConfig, + false); + } + catch (Exception e) + { + System.out.println("SessionToken.getMessage() - Exception caught building message, error: " + e.getMessage()); + secureMessage = null; + } + + return secureMessage; + } + + /* + * Returns a string containing the session token. + */ + public String toString() + { + return Base64Coder.encode(m_token); + } + + /* + * Method to get the Identity Id + */ + public String getIdentId() throws Exception + { + return m_id; + } + + /* + * Method to get the Identity Repository Reference (Realm). + */ + public String getRealm() throws Exception + { + return m_realm; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SettingsFileUtil.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SettingsFileUtil.java new file mode 100644 index 00000000..a5f4fca0 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SettingsFileUtil.java @@ -0,0 +1,429 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import org.apache.xerces.parsers.DOMParser; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.Element; + +import java.io.*; +import java.io.File; +import java.io.FileInputStream; + +/** + * + * Class for the creation and editing of settings files. + * + **/ +public class SettingsFileUtil +{ + /** + * Gets document for the specified settings file. + * + * @param filePath Path to the settings file. + * @return Document representation of the settings file. + */ + private static Document getSettingsFileDoc(String filePath) + { + Document doc = null; + + try + { + // Get an input stream to read from settings file + File f = new File(filePath); + FileInputStream inStream = new FileInputStream(f); + InputSource source = new InputSource(inStream); + + DOMParser parser = new DOMParser(); + parser.parse(source); + doc = parser.getDocument(); + + inStream.close(); + } + catch (FileNotFoundException e) + { + System.err.println("Settings file " + filePath + " not found"); + doc = null; + } + catch (SecurityException e) + { + System.err.println("SecurityException accessing " + filePath); + doc = null; + } + catch (IOException e) + { + System.err.println("IOException accessing " + filePath + " Exception=" + e.toString()); + doc = null; + } + catch (SAXException e) + { + System.err.println("Settings file " + filePath + " format error"); + doc = null; + } + + return doc; + } + + /** + * Gets a starting settings document + * + * @param settings String with starting settings document. + * @return Starting settings document. + */ + private static Document getSettingsDoc(String settings) + { + Document doc = null; + + try + { + StringReader reader = new StringReader(settings); + InputSource source = new InputSource(reader); + + DOMParser parser = new DOMParser(); + parser.parse(source); + doc = parser.getDocument(); + reader.close(); + } + catch (Exception e) + { + System.err.println("Program error, exception: " + e.toString()); + } + + return doc; + } + + /** + * List all of the settings present in the specified file. + * + * @param filePath` Path to the settings file. + * @return True if the operation is successfully performed. + */ + public static boolean performListOperation(String filePath) + { + boolean opPerformed = false; + + // List the settings present in the file + Document doc = getSettingsFileDoc(filePath); + if (doc != null) + { + // Go through the elements of the document + Element root = doc.getDocumentElement(); + Node child; + Node next = root.getFirstChild(); + while ((child = next) != null) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.ELEMENT_NODE) + { + System.out.println(child.getLocalName() + "=" + child.getTextContent()); + } + } + + opPerformed = true; + } + + return opPerformed; + } + + /** + * Create settings file. + * + * @param filePath Path to the settings file. + * @param settings String containing an settings document. + * @return True if the operation is successfully performed. + */ + public static boolean performCreateOperation(String filePath, + String settings) + { + boolean opPerformed = false; + + // create a settings file + Document doc = getSettingsDoc(settings); + if (doc != null) + { + try + { + File f = new File(filePath); + boolean createStatus = f.createNewFile(); + if (createStatus == true) + { + FileOutputStream out = new FileOutputStream(f); + OutputFormat format = new OutputFormat(doc); + XMLSerializer serializer = new XMLSerializer(out, format); + serializer.serialize(doc.getDocumentElement()); + out.close(); + + opPerformed = true; + } + else + { + System.out.println("File " + filePath + " already exists"); + } + } + catch (IOException e) + { + System.out.println("Error creating file " + filePath + ", exception: " + e.toString()); + } + catch (SecurityException e) + { + System.out.println("SecurityException creating " + filePath); + } + } + + return opPerformed; + } + + /** + * Gets value of the specified setting in the specified settings file. + * + * @param filePath Path to the settings file. + * @param setting Name of the setting being queried. + * @return True if the operation is successfully performed. + */ + public static boolean performGetOperation(String filePath, + String setting, + IVerifySetting settingVerifier) + { + boolean opPerformed = false; + + // Validate the setting name specified + if (settingVerifier.validSetting(setting)) + { + // Get settings present in the file + Document doc = getSettingsFileDoc(filePath); + if (doc != null) + { + // Go through the elements of the document until + // we find the one specified. + Element root = doc.getDocumentElement(); + Node child; + Node next = root.getFirstChild(); + boolean settingFound = false; + while ((child = next) != null + && settingFound == false) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.ELEMENT_NODE + && child.getLocalName().compareToIgnoreCase(setting) == 0) + { + System.out.println(child.getLocalName() + "=" + child.getTextContent()); + settingFound = true; + } + } + + if (settingFound == false) + System.out.println("Not set"); + + opPerformed = true; + } + } + + return opPerformed; + } + + /** + * Sets the specified setting in the specified settings file. + * + * @param filePath Path to the settings file. + * @param setting`` Name of the setting to be set. + * @param value Value to be assigned to the setting. + * @return True if the operation is successfully performed. + */ + public static boolean performSetOperation(String filePath, + String setting, + String value, + IVerifySetting settingVerifier) + { + boolean opPerformed = false; + + // Validate specified setting name and value + String formalSetting; + if ((formalSetting = settingVerifier.validSettingNameAndValue(setting, value)) != null) + { + // Get settings present in the file + Document doc = getSettingsFileDoc(filePath); + if (doc != null) + { + // Go through the elements of the document until + // we find the one specified. + Element root = doc.getDocumentElement(); + Node child; + Node next = (Node) root.getFirstChild(); + boolean settingFound = false; + while ((child = next) != null + && settingFound == false) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.ELEMENT_NODE + && child.getLocalName().compareToIgnoreCase(setting) == 0) + { + // Change the value of the setting + child.setTextContent(value); + settingFound = true; + } + } + + if (settingFound == false) + { + try + { + Element element = doc.createElement(formalSetting); + element.setTextContent(value); + root.appendChild(element); + } + catch (Exception e) + { + System.err.println("Exception caught " + e.toString()); + } + } + + // Update the file after removing the text nodes + try + { + // Remove text nodes + next = (Node) root.getFirstChild(); + while ((child = next) != null) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.TEXT_NODE) + { + // Remove the node + root.removeChild(child); + } + } + + // Update file + File f = new File(filePath); + FileOutputStream out = new FileOutputStream(f); + OutputFormat format = new OutputFormat(doc); + XMLSerializer serializer = new XMLSerializer(out, format); + serializer.serialize(doc.getDocumentElement()); + out.close(); + + opPerformed = true; + } + catch (IOException e) + { + System.out.println("Error writing to file " + filePath + ", exception: " + e.toString()); + } + catch (SecurityException e) + { + System.out.println("SecurityException writting to file " + filePath); + } + } + } + + return opPerformed; + } + + /** + * Remove specified setting from the specified settings file. + * + * @param filePath Path to the settings file. + * @param setting Name of the setting to be removed. + * @return True if the operation is successfully performed. + */ + public static boolean performRemoveOperation(String filePath, + String setting, + IVerifySetting settingVerifier) + { + boolean opPerformed = false; + + // Validate specified setting name + if (settingVerifier.validSetting(setting)) + { + // Get settings present in the file + Document doc = getSettingsFileDoc(filePath); + if (doc != null) + { + // Go through the elements of the document until + // we find the one specified. + Element root = doc.getDocumentElement(); + Node child; + Node next = (Node) root.getFirstChild(); + boolean settingFound = false; + while ((child = next) != null + && settingFound == false) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.ELEMENT_NODE + && child.getLocalName().compareToIgnoreCase(setting) == 0) + { + // Remove the element from the document + root.removeChild(child); + settingFound = true; + + // Update the file after removing the text nodes + try + { + // Remove text nodes + next = (Node) root.getFirstChild(); + while ((child = next) != null) + { + next = child.getNextSibling(); + if (child.getNodeType() == Node.TEXT_NODE) + { + // Remove the node + root.removeChild(child); + } + } + + // Update file + File f = new File(filePath); + FileOutputStream out = new FileOutputStream(f); + OutputFormat format = new OutputFormat(doc); + XMLSerializer serializer = new XMLSerializer(out, format); + serializer.serialize(doc.getDocumentElement()); + out.close(); + + opPerformed = true; + } + catch (IOException e) + { + System.out.println("Error writing to file " + filePath + ", exception: " + e.toString()); + } + catch (SecurityException e) + { + System.out.println("SecurityException writting to file " + filePath); + } + } + } + + if (settingFound == false) + { + // Succeed anyway + opPerformed = true; + } + } + } + + return opPerformed; + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcConfig.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcConfig.java new file mode 100644 index 00000000..4a1b44af --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcConfig.java @@ -0,0 +1,319 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.*; +import java.util.*; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/** + * SvcConfig Class. + * + * This class obtains and maintains the service configuration. + * + */ +public class SvcConfig +{ + // Well known service configuration settings + // + // The LifetimeShorter value is the value by which token lifetime + // values are shorten when specified to clients to make sure that + // the clients detect token expirations before issuing the tokens + // to a service for authentication purposes. + public final static String SessionTokenLifetime = "SessionTokenLifetime"; + public final static String LifetimeShorter = "LifetimeShorter"; + public final static String IdentityAbstractionConfigFile = "IAConfigFile"; + public final static String StartSearchContext = "startSearchContext"; + public final static String ConfigFolderPath = "ConfigFolderPath"; + public final static String AppRootPath = "AppRootPath"; + public final static String ReconfigureInterval = "ReconfigureInterval"; + public final static String SigningKeyAliasName = "SigningKeyAliasName"; + public final static String SigningKeyPassword = "SigningKeyPassword"; + + // Default configuration values + public final static String DefaultSessionTokenLifetimeValue = "43200"; // Seconds + public final static String DefaultLifetimeShorterValue = "5"; // Seconds + public final static String DefaultReconfigureIntervalValue = "60"; // Seconds + public final static String DefaultSigningKeyAliasNameValue = "signingKey"; + public final static String DefaultSigningKeyPasswordValue = "secret"; + + private static final String m_svcSettingsFileName = "svc.settings"; + private Map m_svcSettingsMap; + + /* + * Class for handling Authentication Request parsing events. + */ + private class SAXHandler extends org.xml.sax.helpers.DefaultHandler + { + private final static int AWAITING_ROOT_ELEMENT_START = 0; + private final static int AWAITING_SETTING_ELEMENT_START = 1; + private final static int AWAITING_SETTING_ELEMENT_DATA = 2; + private final static int AWAITING_SETTING_ELEMENT_END = 3; + private final static int DONE_PARSING = 4; + + private final static String m_rootElementName = "settings"; + + private Map m_keyMap; + private int m_state; + private String m_currentKey; + + /* + * Constructor + */ + public SAXHandler(Map keyMap) + { + super(); + + // Initialize our members + m_keyMap = keyMap; + m_state = AWAITING_ROOT_ELEMENT_START; + } + + /* + * endDocument() implementation. + */ + public void endDocument () throws SAXException + { + // Verify that we are not in an invalid state + if (m_state != DONE_PARSING) + { + System.err.println("SvcConfig SAXHandler.endDocument()- Invalid state" + m_state); + throw new SAXException("Invalid state at endDocument"); + } + } + + /* + * startElement() implementation. + */ + public void startElement (String uri, String name, String qName, org.xml.sax.Attributes atts) throws SAXException + { + // Proceed based on our state + switch (m_state) + { + case AWAITING_ROOT_ELEMENT_START: + // Verify that we are processing the expected tag + if (m_rootElementName.equals(qName)) + { + // Advance to the next state + m_state = AWAITING_SETTING_ELEMENT_START; + } + else + { + System.err.println("SvcConfig SAXHandler.startElement()- Un-expected element"); + throw new SAXException("Un-expected element"); + } + break; + + case AWAITING_SETTING_ELEMENT_START: + // Keep track of the key name + m_currentKey = qName; + + // Advance to the next state + m_state = AWAITING_SETTING_ELEMENT_DATA; + break; + + default: + System.err.println("SvcConfig SAXHandler.startElement()- Invalid state " + m_state); + throw new SAXException("Invalid state at startElement"); + } + } + + /* + * endElement() immplementation. + */ + public void endElement (String uri, String name, String qName) throws SAXException + { + // Proceed based on our state + switch (m_state) + { + case AWAITING_SETTING_ELEMENT_DATA: + case AWAITING_SETTING_ELEMENT_END: + // Advance to the next state + m_state = AWAITING_SETTING_ELEMENT_START; + break; + + case AWAITING_SETTING_ELEMENT_START: + // Verify that we are processing the expected tag + if (m_rootElementName.equals(qName)) + { + // Advance to the next state + m_state = DONE_PARSING; + } + else + { + System.err.println("SvcConfig SAXHandler.endElement()- Un-expected element"); + throw new SAXException("Un-expected element"); + } + break; + + default: + System.err.println("SvcConfig SAXHandler.endElement()- Invalid state " + m_state); + throw new SAXException("Invalid state at endElement"); + } + } + + /* + * character() implementation. + */ + public void characters (char ch[], int start, int length) throws SAXException + { + // Consume the data if in the right state + if (m_state == AWAITING_SETTING_ELEMENT_DATA) + { + // Consume the data and add the key to map + m_keyMap.put(m_currentKey, new String(ch, start, length)); + + // Advance to the next state + m_state = AWAITING_SETTING_ELEMENT_END; + } + } + } + + /* + * Constructor. + */ + public SvcConfig(String appRootPath, String svcConfigPath) throws Exception + { + System.err.println("SvcConfig()-"); + + System.err.println("SvcConfig()- SvcConfigPath = " + svcConfigPath); + + // Create a map to keep track of the service settings + m_svcSettingsMap = new HashMap(); + + try + { + // Get an input stream to services settings file + File settingsFile = new File(svcConfigPath, m_svcSettingsFileName); + FileInputStream inStream = new FileInputStream(settingsFile); + + // Parse the file + XMLReader xr = XMLReaderFactory.createXMLReader(); + SAXHandler handler = new SAXHandler(m_svcSettingsMap); + xr.setContentHandler(handler); + xr.setErrorHandler(handler); + + InputSource source = new InputSource(inStream); + xr.parse(source); + inStream.close(); + + // Add the application and config folder path settings to our map + m_svcSettingsMap.put(AppRootPath, appRootPath); + m_svcSettingsMap.put(ConfigFolderPath, svcConfigPath); + } + catch (SAXException e) + { + System.err.println("SvcConfig()- Parse exception: " + e.toString()); + throw new Exception("SvcConfig()- svc.settings format error"); + } + catch (SecurityException e) + { + System.err.println("SvcConfig()- SecurityException caught while accessing " + svcConfigPath + File.separator + m_svcSettingsFileName + " Exception=" + e.toString()); + } + catch (FileNotFoundException e) + { + System.err.println("SvcConfig()- File " + svcConfigPath + File.separator + m_svcSettingsFileName + " not found"); + } + catch (IOException e) + { + System.err.println("SvcConfig()- IOException caught while trying to read " + svcConfigPath + File.separator + m_svcSettingsFileName + " Exception=" + e.toString()); + } + } + + /* + * Returns the value associated with the specified setting. + */ + public String getSetting(String settingName) throws Exception + { + // Try to find the setting in our map + String value = (String) m_svcSettingsMap.get(settingName); + if (value == null) + { + System.err.println("SvcConfig.getSetting()- Did not find setting " + settingName); + + // The setting is not in our map, check if it is one to + // which we have defaults. + if (settingName.equals(SessionTokenLifetime) == true) + { + value = DefaultSessionTokenLifetimeValue; + System.err.println("SvcConfig.getSetting()- Assigning default value " + value); + + // Add the key to the map so that it can be found quicker next time + m_svcSettingsMap.put(SessionTokenLifetime, DefaultSessionTokenLifetimeValue); + } + else if (settingName.equals(LifetimeShorter) == true) + { + value = DefaultLifetimeShorterValue; + System.err.println("SvcConfig.getSetting()- Assigning default value " + value); + + // Add the key to the map so that it can be found quicker next time + m_svcSettingsMap.put(LifetimeShorter, DefaultLifetimeShorterValue); + } + else if (settingName.equals(ReconfigureInterval) == true) + { + value = DefaultReconfigureIntervalValue; + System.err.println("SvcConfig.getSetting()- Assigning default value " + value); + + // Add the key to the map so that it can be found quicker next time + m_svcSettingsMap.put(ReconfigureInterval, DefaultReconfigureIntervalValue); + } + else if (settingName.equals(SigningKeyAliasName) == true) + { + value = DefaultSigningKeyAliasNameValue; + System.err.println("SvcConfig.getSetting()- Assigning default value " + value); + + // Add the key to the map so that it can be found quicker next time + m_svcSettingsMap.put(SigningKeyAliasName, DefaultSigningKeyAliasNameValue); + } + else if (settingName.equals(SigningKeyPassword) == true) + { + value = DefaultSigningKeyPasswordValue; + System.err.println("SvcConfig.getSetting()- Assigning default value " + value); + + // Add the key to the map so that it can be found quicker next time + m_svcSettingsMap.put(SigningKeyPassword, DefaultSigningKeyPasswordValue); + } + else if (settingName.equals(IdentityAbstractionConfigFile) == true) + { + System.err.println("SvcConfig.getSetting()- Mandatory setting " + IdentityAbstractionConfigFile + " not set"); + throw new Exception("Missing mandatory configuration setting"); + } + } + else + { + System.err.println("SvcConfig.getSetting()- Found setting " + settingName); + System.err.println("SvcConfig.getSetting()- Setting value = " + value); + + // Do some sanity checking + // tbd - Make sure that the token lifetime values are greater than the LifetimeShorter + } + + return value; + } +} \ No newline at end of file diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcSettingsEditor.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcSettingsEditor.java new file mode 100644 index 00000000..9b9cf175 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/SvcSettingsEditor.java @@ -0,0 +1,374 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.File; + +/** + * + * Class for the creation and editing of svc.settings files. + * + **/ +public class SvcSettingsEditor implements IVerifySetting +{ + private static final String usage = + "usage: SvcSettingsEditor -op [settingName [settingValue]] -file settingsFilePath\n\n" + + " where:\n" + + " -op - Corresponds to one of the following operations:\n" + + " -create - Create new svc settings file\n" + + " -list - List settings\n" + + " -get - Get settings, must be followed by settingName parameter\n" + + " -set - Set settings, must be followed by settingName and settingValue parameters\n" + + " -remove - Remove settings\n" + + " -file - Path the the svc settings file\n" + + " settingName - Name of the setting being retrieved or set\n" + + " settingValue - Value of the setting being set\n\n" + + " The following settings are valid:\n" + + " SessionTokenLifetime\n" + + " LifetimeShorter\n" + + " IAConfigFile\n" + + " ReconfigureInterval\n" + + " SigningKeyAliasName\n" + + " SigningKeyPassword\n"; + + private static final String settings = + "\n" + + "\n" + + " /etc/CASA/authtoken/svc/iaRealms.xml\n" + + "\n"; + + + /** + * Checks if the specified setting is valid. + * + * @param setting The name of the setting being checked. + * @return True if the specified setting is valid. + */ + public boolean validSetting(String setting) + { + boolean result = false; + + if (setting.compareToIgnoreCase(SvcConfig.SessionTokenLifetime) == 0) + result = true; + else if (setting.compareToIgnoreCase(SvcConfig.LifetimeShorter) == 0) + result = true; + else if (setting.compareToIgnoreCase(SvcConfig.IdentityAbstractionConfigFile) == 0) + result = true; + else if (setting.compareToIgnoreCase(SvcConfig.ReconfigureInterval) == 0) + result = true; + else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyAliasName) == 0) + result = true; + else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyPassword) == 0) + result = true; + else + System.out.println("Invalid setting specified"); + + return result; + } + + /** + * Checks if the specified setting is valid in conjunction + * with the specified value. + * + * @param setting The name of the setting being checked. + * @param value The value of the specified setting. + * @return The formal name of the setting if found to be valid. + */ + public String validSettingNameAndValue(String setting, + String value) + { + String validSetting = null; + + if (setting.compareToIgnoreCase(SvcConfig.SessionTokenLifetime) == 0) + { + // Verify that we are dealing with a numeric value + try + { + Integer.valueOf(value); + + // Good + validSetting = SvcConfig.SessionTokenLifetime; + } + catch (NumberFormatException e) + { + System.out.println("Invalid setting value specified"); + } + } + else if (setting.compareToIgnoreCase(SvcConfig.LifetimeShorter) == 0) + { + // Verify that we are dealing with a numeric value + try + { + Integer.valueOf(value); + + // Good + validSetting = SvcConfig.LifetimeShorter; + } + catch (NumberFormatException e) + { + System.out.println("Invalid setting value specified"); + } + } + else if (setting.compareToIgnoreCase(SvcConfig.IdentityAbstractionConfigFile) == 0) + { + // Output a warning if the specified file does not exist + try + { + File f = new File(value); + if (f.exists() == false) + { + System.out.println("Warning: File " + value + " does not exist"); + } + } + catch (SecurityException e) + { + System.out.println("Warning: Not able to access file " + value); + } + + // Always succeed + validSetting = SvcConfig.IdentityAbstractionConfigFile; + } + else if (setting.compareToIgnoreCase(SvcConfig.ReconfigureInterval) == 0) + { + // Verify that we are dealing with a numeric value + try + { + Integer.valueOf(value); + + // Good + validSetting = SvcConfig.ReconfigureInterval; + } + catch (NumberFormatException e) + { + System.out.println("Invalid setting value specified"); + } + } + else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyAliasName) == 0) + { + validSetting = SvcConfig.SigningKeyAliasName; + } + else if (setting.compareToIgnoreCase(SvcConfig.SigningKeyPassword) == 0) + { + validSetting = SvcConfig.SigningKeyPassword; + } + else + System.out.println("Invalid setting specified"); + + return validSetting; + } + + /** + * Applications Entry Point + * + * @param args + */ + public static void main(String[] args) + { + String op = null; + boolean opPerformed = false; + boolean argumentsError = false; + String filePath = null; + String setting = null; + String value = null; + SvcSettingsEditor editor = new SvcSettingsEditor(); + + // Process the command line arguments + for (int i = 0; i < args.length; i++) + { + // Proceed based on the command + if (args[i].compareToIgnoreCase("-file") == 0) + { + // The next argument should contain the filepath + if (args.length > (i + 1)) + { + filePath = args[i + 1]; + i++; + } + else + { + argumentsError = true; + break; + } + } + else if (args[i].compareToIgnoreCase("-list") == 0) + { + // List operation requested + if (op == null) + { + op = "list"; + } + else + { + argumentsError = true; + break; + } + } + else if (args[i].compareToIgnoreCase("-create") == 0) + { + // List operation requested + if (op == null) + { + op = "create"; + } + else + { + argumentsError = true; + break; + } + } + else if (args[i].compareToIgnoreCase("-get") == 0) + { + // Get setting operation requested + if (op == null) + { + op = "get"; + + // The next argument should contain the setting name + if (args.length > (i + 1)) + { + setting = args[i + 1]; + i++; + } + else + { + argumentsError = true; + break; + } + } + else + { + argumentsError = true; + break; + } + } + else if (args[i].compareToIgnoreCase("-set") == 0) + { + // Set setting operation requested + if (op == null) + { + op = "set"; + + // The next two arguments should contain the setting name + // and the setting value. + if (args.length > (i + 2)) + { + setting = args[i + 1]; + value = args[i + 2]; + i += 2; + } + else + { + argumentsError = true; + break; + } + } + else + { + argumentsError = true; + break; + } + } + else if (args[i].compareToIgnoreCase("-remove") == 0) + { + // Remove setting operation requested + if (op == null) + { + op = "remove"; + + // The next argument should contain the setting name + if (args.length > (i + 1)) + { + setting = args[i + 1]; + i++; + } + else + { + argumentsError = true; + break; + } + } + else + { + argumentsError = true; + break; + } + } + else + { + argumentsError = true; + } + } + + // Proceed based on the specified parameters + if (argumentsError == false) + { + if (filePath != null && op != null) + { + System.out.println("Dealing with settings file: " + filePath); + + // Proceed based on the operation requested + if (op.compareTo("list") == 0) + { + opPerformed = SettingsFileUtil.performListOperation(filePath); + } + else if (op.compareTo("create") == 0) + { + opPerformed = SettingsFileUtil.performCreateOperation(filePath, settings); + } + else if (op.compareTo("get") == 0) + { + opPerformed = SettingsFileUtil.performGetOperation(filePath, setting, editor); + } + else if (op.compareTo("set") == 0) + { + opPerformed = SettingsFileUtil.performSetOperation(filePath, setting, value, editor); + } + else if (op.compareTo("remove") == 0) + { + opPerformed = SettingsFileUtil.performRemoveOperation(filePath, setting, editor); + } + else + { + System.err.println("Tool error"); + } + } + else + { + argumentsError = true; + } + } + + // Display the usage string if we encountered an error with the + // command line arguments. + if (argumentsError) + System.out.print(usage); + + // Set the exit code appropriatedly + if (opPerformed) + System.exit(0); + else + System.exit(1); + } +} diff --git a/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/WSSecurity.java b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/WSSecurity.java new file mode 100644 index 00000000..e00133d0 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/src/com/novell/casa/authtoksvc/WSSecurity.java @@ -0,0 +1,283 @@ +/*********************************************************************** + * + * Copyright (C) 2006 Novell, Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, + * you may find current contact information at www.novell.com. + * + * Author: Juan Carlos Luciani + * + ***********************************************************************/ + +package com.novell.casa.authtoksvc; + +import java.io.ByteArrayInputStream; + +import org.apache.axis.Message; +import org.apache.axis.message.SOAPEnvelope; +import org.apache.ws.security.*; +import org.apache.ws.security.components.crypto.Crypto; +import org.apache.ws.security.components.crypto.CryptoFactory; +import org.apache.ws.security.message.WSSecHeader; +import org.apache.ws.security.message.WSSecSignature; +import org.apache.ws.security.message.WSSecTimestamp; +import org.apache.xml.security.c14n.Canonicalizer; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import javax.xml.soap.MessageFactory; +import java.util.Set; +import java.util.Vector; + + +/* + * WSSecurity Class. + * + * This class provides static methods for securing and verifying SOAP messages. SOAP messages + * are secured by adding a timestamp and signing the appropriate elements using methods and + * headers defined by WS* specifications. + * + */ +public class WSSecurity +{ + static final private WSSecurityEngine secEngine = new WSSecurityEngine(); + static final private Crypto crypto = CryptoFactory.getInstance(); + + /** + * Creates a SOAP message from a document. + * + */ + private static Message toSOAPMessage(Document doc) throws Exception + { + Canonicalizer c14n = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS); + byte[] canonicalMessage = c14n.canonicalizeSubtree(doc); + ByteArrayInputStream in = new ByteArrayInputStream(canonicalMessage); + MessageFactory factory = MessageFactory.newInstance(); + return (org.apache.axis.Message) factory.createMessage(null, in); + } + + /*** + * Returns the first element that containes an Id with value + * uri and namespace. + *

+ * + * Copyright Note: The code for this function was copied from file + * WSSecurityUtil.java from package org.apache.ws.security.util. + * The Copyright notice on this file is as follows: + * + * Copyright 2003-2006 The Apache Software Foundation, or their licensors, as + * appropriate. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @param startNode Where to start the search + * @param value Value of the Id attribute + * @param namespace Namespace URI of the Id + * @return The found element or null + */ + private static Element findElementById(Node startNode, + String value, + String namespace) + { + // Just return null if startNode is set to null + if (startNode == null) + { + return null; + } + + Node startParent = startNode.getParentNode(); + Node processedNode; + while (startNode != null) + { + // start node processing at this point + if (startNode.getNodeType() == Node.ELEMENT_NODE) + { + Element se = (Element) startNode; + if (se.hasAttributeNS(namespace, "Id") + && value.equals(se.getAttributeNS(namespace, "Id"))) + { + return se; + } + } + + processedNode = startNode; + startNode = startNode.getFirstChild(); + + // no child, this node is done. + if (startNode == null) + { + // close node processing, get sibling + startNode = processedNode.getNextSibling(); + } + + // no more siblings, get parent, all children + // of parent are processed. + while (startNode == null) + { + processedNode = processedNode.getParentNode(); + if (processedNode == startParent) + { + return null; + } + + // close parent node processing (processed node now) + startNode = processedNode.getNextSibling(); + } + } + + return null; + } + + /** + * Verifies SOAP envelope timestamp and signatures. + * + * @param envelope SOAP envelope with timestamp + * @return boolean True if verification succeeds + * @throws Exception on error + */ + public static boolean verifyMessage(SOAPEnvelope envelope) throws Exception + { + boolean msgVerificationStatus = false; + + try + { + boolean timeStampProcessed = false; + boolean signatureProcessed = false; + Vector results; + Document signedDoc = envelope.getAsDocument(); + results = secEngine.processSecurityHeader(signedDoc, null, null, crypto); + if (results != null) + { + for (WSSecurityEngineResult result : results) + { + if (result.getAction() == WSConstants.TS) + { + timeStampProcessed = true; + } + else if (result.getAction() == WSConstants.SIGN) + { + // A signature was processed, verify that the signature was over the timestamp + // and the body. + boolean timeStampSigned = false; + boolean bodySigned = false; + Set signedElements = result.getSignedElements(); + for (Object signedElement : signedElements) + { + String elementId = (String) signedElement; + Element element = findElementById(signedDoc.getDocumentElement(), elementId, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); + if (element != null) + { + if ("wsu:Timestamp".equalsIgnoreCase(element.getNodeName())) + { + timeStampSigned = true; + } + else if ("SOAP-ENV:Body".equalsIgnoreCase(element.getNodeName())) + { + bodySigned = true; + } + } + } + + if (timeStampSigned && bodySigned) + { + signatureProcessed = true; + } + } + } + } + + if (timeStampProcessed && signatureProcessed) + { + System.out.println("WSSecurity.verifyMessage() - Validation succeded"); + msgVerificationStatus = true; + } + else + { + System.out.println("WSSecurity.verifyMessage() - validation failed"); + } + } + catch (WSSecurityException e) + { + System.out.println("WSSecurity.verifyMessage() - Verification failed with error:" + e.getMessage() + " code = " + e.getErrorCode()); + } + + return msgVerificationStatus; + } + + /** + * Add timestamp and sign SOAP message in compliance with WS-Security. + * + * @param envelope String containing a SOAP envelope + * @param timeToLive Value to set the timestamp timeToLive parameter in seconds + * @param svcConfig Service Config object + * @param includeCert True if the message should include the Public Certificate + * @return Message Signed and timestamped SOAP message + * @throws Exception on error + */ + public static Message secureSOAPEnvelope(SOAPEnvelope envelope, + int timeToLive, + SvcConfig svcConfig, + boolean includeCert) throws Exception + { + WSSecSignature signer = new WSSecSignature(); + signer.setUserInfo(svcConfig.getSetting(SvcConfig.SigningKeyAliasName), + svcConfig.getSetting(SvcConfig.SigningKeyPassword)); + if (includeCert) + { + signer.setKeyIdentifierType(WSConstants.X509_KEY_IDENTIFIER); // Include X509 Cert in message + } + else + { + signer.setKeyIdentifierType(WSConstants.ISSUER_SERIAL); // Use X509 Cert Serial Number and issuer info + } + + Document doc = envelope.getAsDocument(); + + WSSecHeader secHeader = new WSSecHeader(); + secHeader.insertSecurityHeader(doc); + + WSSecTimestamp timeStamper = new WSSecTimestamp(); + timeStamper.setTimeToLive(timeToLive); + timeStamper.build(doc, secHeader); + + Vector parts = new Vector(); + + String soapNamespace = doc.getDocumentElement().getNamespaceURI(); + WSEncryptionPart bodyPart = new WSEncryptionPart("Body", soapNamespace, ""); + parts.add(bodyPart); + + WSEncryptionPart timeStampPart = new WSEncryptionPart(timeStamper.getId()); + parts.add(timeStampPart); + + signer.setParts(parts); + + Document signedDoc = signer.build(doc, crypto, secHeader); + + // Convert the signed document into a SOAP message and return it. + return toSOAPMessage(signedDoc); + } +} diff --git a/CASA-auth-token/server-java/Svc/templates/Makefile.am b/CASA-auth-token/server-java/Svc/templates/Makefile.am new file mode 100644 index 00000000..128fa83b --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/Makefile.am @@ -0,0 +1,41 @@ +####################################################################### +# +# Copyright (C) 2006 Novell, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Author: Juan Carlos Luciani +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +CFILES = + +EXTRA_DIST = auth.policy \ + authtoken.settings \ + iaRealms.xml \ + identoken.settings \ + svc.settings + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/templates/auth.policy b/CASA-auth-token/server-java/Svc/templates/auth.policy new file mode 100644 index 00000000..d9cf2413 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/auth.policy @@ -0,0 +1,11 @@ + + + +REALM +Krb5Authenticate + + +REALM +PwdAuthenticate + + diff --git a/CASA-auth-token/server-java/Svc/templates/authtoken.settings b/CASA-auth-token/server-java/Svc/templates/authtoken.settings new file mode 100644 index 00000000..b703427e --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/authtoken.settings @@ -0,0 +1,3 @@ + + + diff --git a/CASA-auth-token/server-java/Svc/templates/iaRealms.xml b/CASA-auth-token/server-java/Svc/templates/iaRealms.xml new file mode 100644 index 00000000..928c379b --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/iaRealms.xml @@ -0,0 +1,22 @@ + + + + + + + + ldap://LDAP_HOST_NAME:LDAP_LISTEN_PORT + + + + + REALM + + + diff --git a/CASA-auth-token/server-java/Svc/templates/identoken.settings b/CASA-auth-token/server-java/Svc/templates/identoken.settings new file mode 100644 index 00000000..cbbf8cf8 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/identoken.settings @@ -0,0 +1,5 @@ + + + sn + + diff --git a/CASA-auth-token/server-java/Svc/templates/svc.settings b/CASA-auth-token/server-java/Svc/templates/svc.settings new file mode 100644 index 00000000..64501cd7 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/templates/svc.settings @@ -0,0 +1,4 @@ + + + IAREALMS_FILE_PATH + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/Makefile.am b/CASA-auth-token/server-java/Svc/tomcat5/Makefile.am new file mode 100644 index 00000000..ce690393 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/Makefile.am @@ -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 +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = conf + +CFILES = + +EXTRA_DIST = + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/Makefile.am b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/Makefile.am new file mode 100644 index 00000000..5c99e1ce --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/Makefile.am @@ -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 +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = localhost + +CFILES = + +EXTRA_DIST = + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/Makefile.am b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/Makefile.am new file mode 100644 index 00000000..9130190a --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/Makefile.am @@ -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 +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +CFILES = + +EXTRA_DIST = admin.xml \ + balancer.xml \ + manager.xml + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/admin.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/admin.xml new file mode 100644 index 00000000..1b1ac779 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/admin.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/balancer.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/balancer.xml new file mode 100644 index 00000000..cd046464 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/balancer.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/manager.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/manager.xml new file mode 100644 index 00000000..78620c58 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Catalina/localhost/manager.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/Makefile.am b/CASA-auth-token/server-java/Svc/tomcat5/conf/Makefile.am new file mode 100644 index 00000000..433e194f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/Makefile.am @@ -0,0 +1,43 @@ +####################################################################### +# +# Copyright (C) 2006 Novell, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +# Author: Juan Carlos Luciani +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = Catalina linux + +CFILES = + +EXTRA_DIST = catalina.policy \ + catalina.properties \ + jk2.properties \ + server.xml \ + server-minimal.xml \ + tomcat-users.xml \ + web.xml + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.policy b/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.policy new file mode 100644 index 00000000..345fe7a4 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.policy @@ -0,0 +1,162 @@ +// ============================================================================ +// catalina.corepolicy - Security Policy Permissions for Tomcat 5 +// +// This file contains a default set of security policies to be enforced (by the +// JVM) when Catalina is executed with the "-security" option. In addition +// to the permissions granted here, the following additional permissions are +// granted to the codebase specific to each web application: +// +// * Read access to the document root directory +// +// $Id: catalina.policy,v 1.11 2004/03/02 12:36:22 remm Exp $ +// ============================================================================ + + +// ========== SYSTEM CODE PERMISSIONS ========================================= + + +// These permissions apply to javac +grant codeBase "file:${java.home}/lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions +grant codeBase "file:${java.home}/jre/lib/ext/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/../lib/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to all shared system extensions when +// ${java.home} points at $JAVA_HOME/jre +grant codeBase "file:${java.home}/lib/ext/-" { + permission java.security.AllPermission; +}; + + +// ========== CATALINA CODE PERMISSIONS ======================================= + + +// These permissions apply to the launcher code +grant codeBase "file:${catalina.home}/bin/commons-launcher.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the daemon code +grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the commons-logging API +grant codeBase "file:${catalina.home}/bin/commons-logging-api.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the server startup code +grant codeBase "file:${catalina.home}/bin/bootstrap.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the JMX server +grant codeBase "file:${catalina.home}/bin/jmx.jar" { + permission java.security.AllPermission; +}; + +// These permissions apply to the servlet API classes +// and those that are shared across all class loaders +// located in the "common" directory +grant codeBase "file:${catalina.home}/common/-" { + permission java.security.AllPermission; +}; + +// These permissions apply to the container's core code, plus any additional +// libraries installed in the "server" directory +grant codeBase "file:${catalina.home}/server/-" { + permission java.security.AllPermission; +}; + +// ========== WEB APPLICATION PERMISSIONS ===================================== + + +// These permissions are granted by default to all web applications +// In addition, a web application will be given a read FilePermission +// and JndiPermission for all files and directories in its document root. +grant { + // Required for JNDI lookup of named JDBC DataSource's and + // javamail named MimePart DataSource used to send mail + permission java.util.PropertyPermission "java.home", "read"; + permission java.util.PropertyPermission "java.naming.*", "read"; + permission java.util.PropertyPermission "javax.sql.*", "read"; + + // OS Specific properties to allow read access + permission java.util.PropertyPermission "os.name", "read"; + permission java.util.PropertyPermission "os.version", "read"; + permission java.util.PropertyPermission "os.arch", "read"; + permission java.util.PropertyPermission "file.separator", "read"; + permission java.util.PropertyPermission "path.separator", "read"; + permission java.util.PropertyPermission "line.separator", "read"; + + // JVM properties to allow read access + permission java.util.PropertyPermission "java.version", "read"; + permission java.util.PropertyPermission "java.vendor", "read"; + permission java.util.PropertyPermission "java.vendor.url", "read"; + permission java.util.PropertyPermission "java.class.version", "read"; + permission java.util.PropertyPermission "java.specification.version", "read"; + permission java.util.PropertyPermission "java.specification.vendor", "read"; + permission java.util.PropertyPermission "java.specification.name", "read"; + + permission java.util.PropertyPermission "java.vm.specification.version", "read"; + permission java.util.PropertyPermission "java.vm.specification.vendor", "read"; + permission java.util.PropertyPermission "java.vm.specification.name", "read"; + permission java.util.PropertyPermission "java.vm.version", "read"; + permission java.util.PropertyPermission "java.vm.vendor", "read"; + permission java.util.PropertyPermission "java.vm.name", "read"; + + // Required for OpenJMX + permission java.lang.RuntimePermission "getAttribute"; + + // Allow read of JAXP compliant XML parser debug + permission java.util.PropertyPermission "jaxp.debug", "read"; + + // Precompiled JSPs need access to this package. + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime"; + permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*"; + +}; + + +// You can assign additional permissions to particular web applications by +// adding additional "grant" entries here, based on the code base for that +// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files. +// +// Different permissions can be granted to JSP pages, classes loaded from +// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/ +// directory, or even to individual jar files in the /WEB-INF/lib/ directory. +// +// For instance, assume that the standard "examples" application +// included a JDBC driver that needed to establish a network connection to the +// corresponding database and used the scrape taglib to get the weather from +// the NOAA web server. You might create a "grant" entries like this: +// +// The permissions granted to the context root directory apply to JSP pages. +// grant codeBase "file:${catalina.home}/webapps/examples/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; +// +// The permissions granted to the context WEB-INF/classes directory +// grant codeBase "file:${catalina.home}/webapps/examples/WEB-INF/classes/-" { +// }; +// +// The permission granted to your JDBC driver +// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/driver.jar!/-" { +// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect"; +// }; +// The permission granted to the scrape taglib +// grant codeBase "jar:file:${catalina.home}/webapps/examples/WEB-INF/lib/scrape.jar!/-" { +// permission java.net.SocketPermission "*.noaa.gov:80", "connect"; +// }; + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.properties b/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.properties new file mode 100644 index 00000000..d8402676 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/catalina.properties @@ -0,0 +1,57 @@ +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageAccess unless the +# corresponding RuntimePermission ("accessClassInPackage."+package) has +# been granted. +package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.,sun.beans. +# +# List of comma-separated packages that start with or equal this string +# will cause a security exception to be thrown when +# passed to checkPackageDefinition unless the +# corresponding RuntimePermission ("defineClassInPackage."+package) has +# been granted. +# +# by default, no packages are restricted for definition, and none of +# the class loaders supplied with the JDK call checkPackageDefinition. +# +package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper. + +# +# +# List of comma-separated paths defining the contents of the "common" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank,the JVM system loader will be used as Catalina's "common" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +common.loader=${catalina.home}/common/classes,${catalina.home}/common/endorsed/*.jar,${catalina.home}/common/lib/*.jar + +# +# List of comma-separated paths defining the contents of the "server" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute. +# If left as blank, the "common" loader will be used as Catalina's "server" +# loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +server.loader=${catalina.home}/server/classes,${catalina.home}/server/lib/*.jar + +# +# List of comma-separated paths defining the contents of the "shared" +# classloader. Prefixes should be used to define what is the repository type. +# Path may be relative to the CATALINA_BASE path or absolute. If left as blank, +# the "common" loader will be used as Catalina's "shared" loader. +# Examples: +# "foo": Add this folder as a class repository +# "foo/*.jar": Add all the JARs of the specified folder as class +# repositories +# "foo/bar.jar": Add bar.jar as a class repository +shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar,/usr/share/java/identity-abstraction/*.jar diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/jk2.properties b/CASA-auth-token/server-java/Svc/tomcat5/conf/jk2.properties new file mode 100644 index 00000000..093bae80 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/jk2.properties @@ -0,0 +1,26 @@ +## THIS FILE MAY BE OVERRIDEN AT RUNTIME. MAKE SURE TOMCAT IS STOPED +## WHEN YOU EDIT THE FILE. + +## COMMENTS WILL BE _LOST_ + +## DOCUMENTATION OF THE FORMAT IN JkMain javadoc. + +# Set the desired handler list +# handler.list=apr,request,channelJni +# +# Override the default port for the socketChannel +# channelSocket.port=8019 +# Default: +# channelUnix.file=${jkHome}/work/jk2.socket +# Just to check if the the config is working +# shm.file=${jkHome}/work/jk2.shm + +# In order to enable jni use any channelJni directive +# channelJni.disabled = 0 +# And one of the following directives: + +# apr.jniModeSo=/opt/apache2/modules/mod_jk2.so + +# If set to inprocess the mod_jk2 will Register natives itself +# This will enable the starting of the Tomcat from mod_jk2 +# apr.jniModeSo=inprocess diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/Makefile.am b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/Makefile.am new file mode 100644 index 00000000..5898e9e8 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/Makefile.am @@ -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 +# +####################################################################### + +SUBDIRS = + +DIST_SUBDIRS = + +CFILES = + +EXTRA_DIST = server-ibm.xml \ + server-sun.xml + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-ibm.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-ibm.xml new file mode 100644 index 00000000..9f73800f --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-ibm.xml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + factory + org.apache.catalina.users.MemoryUserDatabaseFactory + + + pathname + conf/tomcat-users.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-sun.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-sun.xml new file mode 100644 index 00000000..47519d12 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/linux/server-sun.xml @@ -0,0 +1,385 @@ + + + + + + + + + + + + + + + + + + + + + + + + + factory + org.apache.catalina.users.MemoryUserDatabaseFactory + + + pathname + conf/tomcat-users.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/server-minimal.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/server-minimal.xml new file mode 100644 index 00000000..5d1cd3b9 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/server-minimal.xml @@ -0,0 +1,35 @@ + + + + + + + + factory + org.apache.catalina.users.MemoryUserDatabaseFactory + + + pathname + conf/tomcat-users.xml + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/server.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/server.xml new file mode 100644 index 00000000..1fe20c7a --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/server.xml @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + factory + org.apache.catalina.users.MemoryUserDatabaseFactory + + + pathname + conf/tomcat-users.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/tomcat-users.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/tomcat-users.xml new file mode 100644 index 00000000..6c9f2173 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/tomcat-users.xml @@ -0,0 +1,3 @@ + + + diff --git a/CASA-auth-token/server-java/Svc/tomcat5/conf/web.xml b/CASA-auth-token/server-java/Svc/tomcat5/conf/web.xml new file mode 100644 index 00000000..c41fb027 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/tomcat5/conf/web.xml @@ -0,0 +1,964 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + + org.apache.catalina.servlets.DefaultServlet + + + debug + 0 + + + listings + true + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + fork + false + + + xpoweredBy + false + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + default + / + + + + + + + + jsp + *.jsp + + + + jsp + *.jspx + + + + + + + + + + + + + + + + 30 + + + + + + + + + + + + abs + audio/x-mpeg + + + ai + application/postscript + + + aif + audio/x-aiff + + + aifc + audio/x-aiff + + + aiff + audio/x-aiff + + + aim + application/x-aim + + + art + image/x-jg + + + asf + video/x-ms-asf + + + asx + video/x-ms-asf + + + au + audio/basic + + + avi + video/x-msvideo + + + avx + video/x-rad-screenplay + + + bcpio + application/x-bcpio + + + bin + application/octet-stream + + + bmp + image/bmp + + + body + text/html + + + cdf + application/x-cdf + + + cer + application/x-x509-ca-cert + + + class + application/java + + + cpio + application/x-cpio + + + csh + application/x-csh + + + css + text/css + + + dib + image/bmp + + + doc + application/msword + + + dtd + application/xml-dtd + + + dv + video/x-dv + + + dvi + application/x-dvi + + + eps + application/postscript + + + etx + text/x-setext + + + exe + application/octet-stream + + + gif + image/gif + + + gtar + application/x-gtar + + + gz + application/x-gzip + + + hdf + application/x-hdf + + + hqx + application/mac-binhex40 + + + htc + text/x-component + + + htm + text/html + + + html + text/html + + + hqx + application/mac-binhex40 + + + ief + image/ief + + + jad + text/vnd.sun.j2me.app-descriptor + + + jar + application/java-archive + + + java + text/plain + + + jnlp + application/x-java-jnlp-file + + + jpe + image/jpeg + + + jpeg + image/jpeg + + + jpg + image/jpeg + + + js + text/javascript + + + jsf + text/plain + + + jspf + text/plain + + + kar + audio/x-midi + + + latex + application/x-latex + + + m3u + audio/x-mpegurl + + + mac + image/x-macpaint + + + man + application/x-troff-man + + + mathml + application/mathml+xml + + + me + application/x-troff-me + + + mid + audio/x-midi + + + midi + audio/x-midi + + + mif + application/x-mif + + + mov + video/quicktime + + + movie + video/x-sgi-movie + + + mp1 + audio/x-mpeg + + + mp2 + audio/x-mpeg + + + mp3 + audio/x-mpeg + + + mpa + audio/x-mpeg + + + mpe + video/mpeg + + + mpeg + video/mpeg + + + mpega + audio/x-mpeg + + + mpg + video/mpeg + + + mpv2 + video/mpeg2 + + + ms + application/x-wais-source + + + nc + application/x-netcdf + + + oda + application/oda + + + ogg + application/ogg + + + pbm + image/x-portable-bitmap + + + pct + image/pict + + + pdf + application/pdf + + + pgm + image/x-portable-graymap + + + pic + image/pict + + + pict + image/pict + + + pls + audio/x-scpls + + + png + image/png + + + pnm + image/x-portable-anymap + + + pnt + image/x-macpaint + + + ppm + image/x-portable-pixmap + + + ppt + application/powerpoint + + + ps + application/postscript + + + psd + image/x-photoshop + + + qt + video/quicktime + + + qti + image/x-quicktime + + + qtif + image/x-quicktime + + + ras + image/x-cmu-raster + + + rdf + application/rdf+xml + + + rgb + image/x-rgb + + + rm + application/vnd.rn-realmedia + + + roff + application/x-troff + + + rtf + application/rtf + + + rtx + text/richtext + + + sh + application/x-sh + + + shar + application/x-shar + + + smf + audio/x-midi + + + sit + application/x-stuffit + + + snd + audio/basic + + + src + application/x-wais-source + + + sv4cpio + application/x-sv4cpio + + + sv4crc + application/x-sv4crc + + + svg + image/svg+xml + + + swf + application/x-shockwave-flash + + + t + application/x-troff + + + tar + application/x-tar + + + tcl + application/x-tcl + + + tex + application/x-tex + + + texi + application/x-texinfo + + + texinfo + application/x-texinfo + + + tif + image/tiff + + + tiff + image/tiff + + + tr + application/x-troff + + + tsv + text/tab-separated-values + + + txt + text/plain + + + ulw + audio/basic + + + ustar + application/x-ustar + + + vxml + application/voicexml+xml + + + xbm + image/x-xbitmap + + + xht + application/xhtml+xml + + + xhtml + application/xhtml+xml + + + xml + application/xml + + + xpm + image/x-xpixmap + + + xsl + application/xml + + + xslt + application/xslt+xml + + + xul + application/vnd.mozilla.xul+xml + + + xwd + image/x-xwindowdump + + + wav + audio/x-wav + + + svg + image/svg+xml + + + svgz + image/svg+xml + + + vsd + application/x-visio + + + + wbmp + image/vnd.wap.wbmp + + + + wml + text/vnd.wap.wml + + + + wmlc + application/vnd.wap.wmlc + + + + wmls + text/vnd.wap.wmlscript + + + + wmlscriptc + application/vnd.wap.wmlscriptc + + + wrl + x-world/x-vrml + + + Z + application/x-compress + + + z + application/x-compress + + + zip + application/zip + + + + + + + + + + + + + + + + + index.html + index.htm + index.jsp + + + diff --git a/CASA-auth-token/server-java/Svc/web.xml b/CASA-auth-token/server-java/Svc/web.xml new file mode 100644 index 00000000..9cefa768 --- /dev/null +++ b/CASA-auth-token/server-java/Svc/web.xml @@ -0,0 +1,27 @@ + + + + CasaAuthTokenSvc + + + The CasaAuthTokenSvc provides authentication tokens. + + + Rpc + Rpc + + com.novell.casa.authtoksvc.Rpc + + + Rpc + /Rpc + + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + diff --git a/CASA-auth-token/server-java/TODO b/CASA-auth-token/server-java/TODO new file mode 100644 index 00000000..e45eac67 --- /dev/null +++ b/CASA-auth-token/server-java/TODO @@ -0,0 +1,16 @@ +/*********************************************************************** + * + * TODO for auth_token + * + ***********************************************************************/ + +INTRODUCTION + +This file contains a list of the items still outstanding for auth_token. + +Note: There are TODO lists under each auth_token component. This file just +details outstanding items at the project level. + +OUTSTANDING ITEMS + +None. diff --git a/CASA-auth-token/server-java/autogen.sh b/CASA-auth-token/server-java/autogen.sh new file mode 100755 index 00000000..b0aaea55 --- /dev/null +++ b/CASA-auth-token/server-java/autogen.sh @@ -0,0 +1,130 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir +PROJECT=CASA +TEST_TYPE=-f +FILE=configure.in + +DIE=0 + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $PROJECT." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +AUTOMAKE=automake-1.9 +ACLOCAL=aclocal-1.9 + +($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || { + AUTOMAKE=automake + ACLOCAL=aclocal +} + +($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile $PROJECT." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +test $TEST_TYPE $FILE || { + echo "You must run this script in the top-level $PROJECT directory" + exit 1 +} + +if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + +case $CC in +*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;; +esac + +for coin in `find $srcdir -name configure.in -print` +do + dr=`dirname $coin` + if test -f $dr/NO-AUTO-GEN; then + echo skipping $dr -- flagged as no auto-gen + else + echo processing $dr + macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin` + ( cd $dr + aclocalinclude="$ACLOCAL_FLAGS" + for k in $macrodirs; do + if test -d $k; then + aclocalinclude="$aclocalinclude -I $k" + ##else + ## echo "**Warning**: No such directory \`$k'. Ignored." + fi + done + if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then + if grep "sed.*POTFILES" configure.in >/dev/null; then + : do nothing -- we still have an old unmodified configure.in + else + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running gettextize... Ignore non-fatal messages." + echo "no" | gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + fi + if grep "^AM_GNOME_GETTEXT" configure.in >/dev/null; then + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running gettextize... Ignore non-fatal messages." + echo "no" | gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + if grep "^AM_GLIB_GNU_GETTEXT" configure.in >/dev/null; then + echo "Creating $dr/aclocal.m4 ..." + test -r $dr/aclocal.m4 || touch $dr/aclocal.m4 + echo "Running gettextize... Ignore non-fatal messages." + echo "no" | glib-gettextize --force --copy + echo "Making $dr/aclocal.m4 writable ..." + test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4 + fi + if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then + echo "Running libtoolize..." + libtoolize --force --copy + fi + echo "Running $ACLOCAL $aclocalinclude ..." + $ACLOCAL $aclocalinclude + if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then + echo "Running autoheader..." + autoheader + fi + echo "Running $AUTOMAKE --gnu $am_opt ..." + $AUTOMAKE --add-missing --gnu $am_opt + echo "Running autoconf ..." + autoconf + ) + fi +done + +conf_flags="--config-cache --enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c + +cd "$ORIGDIR" + +if test x$NOCONFIGURE = x; then + echo Running $srcdir/configure $conf_flags "$@" ... + $srcdir/configure $conf_flags "$@" \ + && echo Now type \`make\' to compile $PROJECT || exit 1 +else + echo Skipping configure process. +fi diff --git a/CASA-auth-token/server-java/configure.in b/CASA-auth-token/server-java/configure.in new file mode 100644 index 00000000..0c93ef30 --- /dev/null +++ b/CASA-auth-token/server-java/configure.in @@ -0,0 +1,292 @@ +####################################################################### +# +# 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. +# +# +####################################################################### + +AC_INIT(CASA_auth_token_svc, 1.7.1,,CASA_auth_token_svc) +AC_CONFIG_SRCDIR(autogen.sh) +AC_CANONICAL_SYSTEM +AM_INIT_AUTOMAKE(tar-pax) + +RELEASE=`date +%Y%m%d_%H%M` +AC_SUBST(RELEASE) +AM_MAINTAINER_MODE + +# +# Check for a valid C# compiler +# +#AC_CHECK_PROG(CSC, csc, csc) +#test -z "$CSC" && AC_CHECK_PROG(CSC, mcs, mcs) +#test -z "$CSC" && AC_MSG_ERROR([no acceptable C Sharp compiler found in \$PATH]) + +# +# Check for valid C# compiler in linux +# +case $host_os in + cygwin*) + ;; + *) + AC_CHECK_PROG(CSC, csc, csc) + test -z "$CSC" && AC_CHECK_PROG(CSC, mcs, mcs) + test -z "$CSC" && AC_MSG_ERROR([no acceptable C Sharp compiler found in \$PATH]) + + ;; +esac + +case $CSC in + # + # Mono-specific configuration + # + mcs) + CSC_EXEFLAG=/target:exe + CSC_LIBFLAG=/target:library + CSC_EXEFLAG=/target:exe + CSC_WINEXEFLAG=/target:winexe + CSCFLAGS='/d:MONO /warn:4 /d:TRACE -d:LINUX' + CSCFLAGS_DEBUG="/debug+ /d:DEBUG" + CSCFLAGS_OPTIMIZE="/optimize+" + MONO=mono + MONO_DEBUG='mono --debug' + MONO_PATH= + SYSTEM_XML='System.Xml.dll' + ;; + # + # .NET-specific configuration + # + csc) + CSC_EXEFLAG=/target:exe + CSC_LIBFLAG=/target:library + CSC_EXEFLAG=/target:exe + CSC_WINEXEFLAG=/target:winexe + CSCFLAGS='/d:DOTNET /warn:4 /d:TRACE /nologo' + CSCFLAGS_DEBUG="/debug+ /d:DEBUG" + CSCFLAGS_OPTIMIZE="/optimize+" + MONO= + MONO_DEBUG= + MONO_PATH= + SYSTEM_XML='System.XML.dll' + ;; +esac + +AC_SUBST(CSC) +AC_SUBST(CSC_EXEFLAG) +AC_SUBST(CSC_LIBFLAG) +AC_SUBST(CSC_WINEXEFLAG) +AC_SUBST(CSCFLAGS) +AC_SUBST(CSCFLAGS_DEBUG) +AC_SUBST(MONO) +AC_SUBST(MONO_PATH) +AC_SUBST(SYSTEM_XML) + +SRCDIR='$(top_srcdir)' +DOCDIR="$SRCDIR/doc" +TOOLDIR='$(top_srcdir)/tools' +AC_SUBST(SRCDIR) +AC_SUBST(DOCDIR) +AC_SUBST(TOOLDIR) +EMPTY= +SPACE='$(EMPTY) $(EMPTY)' + +AC_SUBST(EMPTY) +AC_SUBST(SPACE) + +# +# Check for operating system and set TARGET_OS +# +case $host_os in + cygwin*) + TARGET_OS='windows' + ;; + *) + TARGET_OS='linux' + ;; +esac + +AC_SUBST(TARGET_OS) +AM_CONDITIONAL(LINUX, test "$TARGET_OS" = "linux") +AM_CONDITIONAL(WINDOWS, test "$TARGET_OS" = "windows") + +# +# Check for architecture and set TARGET_ARCH +# ia64 needs to be treated as non64. + +case $target_cpu in + x86_64|p*pc64|s390x) + LIB=lib64 + ;; + *ia64|*) + LIB=lib + ;; +esac + +AC_SUBST(LIB) +AM_CONDITIONAL(LIB64, test "$LIB" = lib64) + +# +# +# Set platform-specific variables +# +case $TARGET_OS in + # + # Linux-specific configuration + # + linux) + # + # Set variables + # + COMMON_CLEAN_FILES='' + ICON_EXT='.ico' + ICON_FLAG='/resource:' + PLATFORM_SUBDIRS=$LINUX_SUBDIRS + SEP='/' + LINK=gcc + ;; + # + # Windows-specific configuration + # + windows) + COMMON_CLEAN_FILES='*.suo */*.suo *.csproj.user */*.csproj.user bin obj */bin */obj *.xml */*.xml *.pdb */*.pdb' + ICON_EXT='.ico' + ICON_FLAG='/win32icon:' + PLATFORM_SUBDIRS=$WINDOWS_SUBDIRS + SEP='$(EMPTY)\\$(EMPTY)' + LINK=link.exe + ;; +esac +AC_SUBST(COMMON_CLEAN_FILES) +AC_SUBST(ICON_EXT) +AC_SUBST(ICON_FLAG) +AC_SUBST(PLATFORM_SUBDIRS) +AC_SUBST(SEP) +AC_SUBST(LINK) + +# +# Run standard macros +# +AM_PROG_CC_STDC +AC_PROG_INSTALL +AC_HEADER_STDC + +####### +# +# set CFLAGS +# +case $host_os in + linux*) + CFLAGS="$CFLAGS" + ;; + cygwin*) + CC=cl.exe + CFLAGS="-D WIN32 -D SSCS_WIN32_PLAT_F -D N_PLAT_CLIENT -MT -Ox" + ;; +esac + +# +# Handle --enable-debug +# +AC_ARG_ENABLE(debug, [ + --enable-debug configure the Makefiles to build in DEBUG mode], + [case "${enableval}" in + yes) enable_debug=true ;; + no) enable_debug=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;; + esac],[enable_debug=false]) +AM_CONDITIONAL(DEBUG, test x$enable_debug = xtrue) +if test "$enable_debug" = "true" +then + # Build debug version. + # CFLAGS="$CFLAGS_DEBUG $CFLAGS -DDBG -DDEBUG" + CFLAGS="$CFLAGS_DEBUG $CFLAGS -g -DDBG -DDEBUG \ +-fPIC -DPIC -DSSCS_LINUX_PLAT_F -O2 -fmessage-length=0 -Wall \ +-D_REENTRANT -DALIGNMENT -DN_PLAT_UNIX \ +-DUNIX -DLINUX -DIAPX38" + CSCFLAGS="$CSCFLAGS_DEBUG $CSCFLAGS" + CXXFLAGS="$CXXFLAGS_DEBUG $CXXFLAGS" + DEVENV_CONFIGURATION=Debug + MONO=$MONO_DEBUG +else + # Build optimized version. + CFLAGS="$CFLAGS_OPTIMIZE $CFLAGS -g -fPIC -DPIC \ +-DSSCS_LINUX_PLAT_F -O2 -fmessage-length=0 -Wall \ +-D_REENTRANT -DALIGNMENT -DN_PLAT_UNIX \ +-DUNIX -DLINUX -DIAPX38" + CSCFLAGS="$CSCFLAGS_OPTIMIZE $CSCFLAGS" + CXXFLAGS="$CXXFLAGS_OPTIMIZE $CXXFLAGS" + DEVENV_CONFIGURATION=Release +fi +AC_SUBST(CSCFLAGS) +AC_SUBST(DEVENV_CONFIGURATION) + +##comment out due to build failure +# Check for GCC version to add fstack-protector flag +# +#GCC_VER="`gcc -dumpversion`" +#case "$GCC_VER" in +# 3*) +# ;; +# 4*) +# CFLAGS="$CFLAGS -fstack-protector" +# ;; +# *) +# ;; +#esac + +AC_SUBST(GCC_VER) + +# +# Configure PKG_CONFIG +# +AC_PATH_PROG(PKG_CONFIG, pkg-config, no) +if test "x$PKG_CONFIG" = "xno"; then + AC_MSG_ERROR([You need to install pkg-config]) +fi + +# +# Configure files +# +AC_OUTPUT([ +Makefile +package/Makefile +package/linux/Makefile +package/linux/CASA_auth_token_svc.spec +Svc/Makefile +Svc/external/Makefile +Svc/src/Makefile +Svc/src/com/Makefile +Svc/src/com/novell/Makefile +Svc/src/com/novell/casa/Makefile +Svc/src/com/novell/casa/authtoksvc/Makefile +Svc/tomcat5/Makefile +Svc/tomcat5/conf/Makefile +Svc/tomcat5/conf/Catalina/Makefile +Svc/tomcat5/conf/Catalina/localhost/Makefile +Svc/tomcat5/conf/linux/Makefile +Svc/linux/Makefile +Svc/templates/Makefile +Svc/manifest/Makefile +Jaas/Makefile +Jaas/src/Makefile +Jaas/src/com/Makefile +Jaas/src/com/novell/Makefile +Jaas/src/com/novell/casa/Makefile +Jaas/src/com/novell/casa/jaas/Makefile +Jaas/src/com/novell/casa/jaas/sample/Makefile +Jaas/linux/Makefile +]) + diff --git a/CASA-auth-token/server-java/package/Makefile.am b/CASA-auth-token/server-java/package/Makefile.am new file mode 100644 index 00000000..f6a6d745 --- /dev/null +++ b/CASA-auth-token/server-java/package/Makefile.am @@ -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 +# +####################################################################### + +SUBDIRS = linux + +DIST_SUBDIRS = linux + +EXTRA_DIST = + +.PHONY: package package-clean package-install package-uninstall +package package-clean package-install package-uninstall: + $(MAKE) -C $(TARGET_OS) $@ + +clean-local: + if [ -d lib ]; then rm -rf lib; fi + +maintainer-clean-local: + rm -f Makefile.in + diff --git a/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.changes b/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.changes new file mode 100644 index 00000000..62c50bf0 --- /dev/null +++ b/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.changes @@ -0,0 +1,89 @@ +------------------------------------------------------------------- +Thu Nov 9 11:42:15 MST 2006 - jluciani@novell.com + +- Completed the ATS configuration story with a tool that + sets up all of the needed configuration files and + parameters with support for a single LDAP Realm and + server. + +------------------------------------------------------------------- +Tue Nov 7 10:42:24 MST 2006 - jluciani@novell.com + +- The service is now only accessible via SSL. +- Created tools for editing settings and policy files. + +------------------------------------------------------------------- +Fri Oct 20 09:53:55 MDT 2006 - jluciani@novell.com + +- Modified the CasaAuthTokenSvc war file to no longer include the + identity-abstraction jars. The CASA_auth_token_svc rpm now requires + the installation of the identity-abstraction rpm and the service is + able to load its files from the location where they are installed + with settings set in the server.xml file of our tomcat base. + +------------------------------------------------------------------- +Wed Oct 18 17:22:01 MDT 2006 - jluciani@novell.com + +- Updated the RPM install of the ATS to install it as a service + and create the necessary signing keys. + +- Made changes to other components to integrate with the new + RPM install changes. + +------------------------------------------------------------------- +Tue Oct 10 08:45:22 MDT 2006 - jluciani@novell.com + +- Brought up to date the README and TODO files. + +------------------------------------------------------------------- +Thu Sep 21 15:41:18 MDT 2006 - jluciani@novell.com + +- Reduced Kerberos configuration requirements. Now the ATS service + principal name defaults to "host" and there is no need to set the + "javax.security.auth.useSubjectCredsOnly" system property to "false" + in the JAVA_OPTS. + +------------------------------------------------------------------- +Mon Sep 18 11:18:00 MDT 2006 - jluciani@novell.com + +- Updated the Svc to reduce the configuration requirements on services + that want to leverage the infrastructure. + +- Modified the WSSecurity module to not include the X509 certificate + in tokens if they are targeted to services residing on the same + box as the ATS. This is being done in order to minimize the size + of the tokens. + +------------------------------------------------------------------- +Thu Sep 14 09:57:00 MDT 2006 - jluciani@novell.com + +- Made changes to support the Authtoken Validate Service. This now + fixes support of "C" services. + +- Switched to using IBMs java instead of SUNs. This was done in order to + gain better Kerberos support (IBMs Kerberos modul supports more + encryption types) and to get around a problem in SUN's Invocation API + that was not letting us consume our AuthToken class from a native thread + other than the thread which creates the JVM. + +------------------------------------------------------------------- +Fri Aug 18 11:49:22 MDT 2006 - jluciani@novell.com + +- Implemented securing Authentication and Session Tokens using WS-Security. + This change temporarily breaks support of "C" services. "C" service support + will be resumed once the necessary changes are made to the native authentication + token APIs to support the new Authentication Tokens. + +------------------------------------------------------------------- +Mon Aug 14 14:25:27 MDT 2006 - jluciani@novell.com + +- Added some debug statements and added the sample Jaas application into + the tar file that is submitted to autobuild. + +------------------------------------------------------------------- +Mon Aug 7 10:28:32 MDT 2006 - schoi@novell.com +- This file has been created for CASA_auth_token_svc project for the first + time. + +------------------------------------------------------------------- + diff --git a/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.spec.in b/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.spec.in new file mode 100644 index 00000000..8b7ac22c --- /dev/null +++ b/CASA-auth-token/server-java/package/linux/CASA_auth_token_svc.spec.in @@ -0,0 +1,369 @@ +# +# spec file for the CASA_auth_token java packages. +# +# Copyright (c) 2006 SUSE LINUX Products GmbH, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://bugs.opensuse.org +# + +# norootforbuild + +# For debug build, please replace Release to Debug and set debug_opt to --enable-debug +%define cfg Release +%define debug_opt "" + + +Name: @PACKAGE@ +URL: http://www.novell.com/products +BuildRequires: libstdc++ gcc-c++ glib2-devel libstdc++-devel pkgconfig java-1_5_0-ibm java-1_5_0-ibm-devel java-1_5_0-ibm-alsa update-alternatives mono-devel servletapi5 identity-abstraction sysvinit insserv +%define prefix /usr +License: LGPL +Group: Applications/System +Autoreqprov: on +%define bldno @VERSION@ +Version: @VERSION@ +Release: 0 +Summary: Novell Common Authentication Services Adapter Authentication Token Infrastructure "Java" (CASA_auth_token) +Source: %{name}-%{version}.tar.bz2 +BuildRoot: %{_tmppath}/%{name}-%{version}-build +Requires: java-1_5_0-ibm servletapi5 tomcat5 sysvinit insserv identity-abstraction sed +PreReq: %fillup_prereq %insserv_prereq +PreReq: /usr/bin/awk, /usr/bin/test, /bin/grep, /bin/cat, /usr/bin/install, /bin/pwd +PreReq: /usr/sbin/groupadd, /usr/sbin/useradd, /usr/sbin/userdel, /usr/bin/getent +BuildArchitectures: noarch + +%description +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 CASA_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". + +The CASA_auth_token_svc is the infrastructure component responsible for authenticating +entities using the native authentication mechanism and for issuing tokens that can later +be used by applications to authenticate the entity o services that are CASA authentication +enabled. + +%package -n CASA_auth_token_jaas_support +Summary: Libraries needed for JAAS applications development. +Group: Applications/System +Requires: java-1_5_0-ibm + +%description -n CASA_auth_token_jaas_support +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 CASA_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". + +The CASA_auth_token_jaas_support package contains the CASA (Common Authentication +Services Adapter) authentication token infrastructure JAAS module and supporting libraries +for token verification. + +%prep +%setup -q +#%patch +%if %{_lib} == "lib64" +%define binsource bin64 +%else +%define binsource bin +%endif + +%build +export PATH=.:$PATH:/usr/%_lib/qt3/bin +%if %suse_version > 1000 +export CFLAGS="$CFLAGS $RPM_OPT_FLAGS -fstack-protector" +%endif + +./autogen.sh +make + + +%install + +export NO_BRP_CHECK_BYTECODE_VERSION="true" + +## Prime the file system ## +install -d %{buildroot}%{prefix} +install -d %{buildroot}%{prefix}/share +install -d %{buildroot}%{prefix}/share/java +install -d %{buildroot}%{prefix}/share/java/CASA +install -d %{buildroot}%{prefix}/share/java/CASA/authtoken +install -d %{buildroot}%{prefix}/share/java/CASA/authtoken/bin +install -d %{buildroot}/srv +install -d %{buildroot}/srv/www +install -d %{buildroot}/srv/www/casaats +install -d -m 700 %{buildroot}/srv/www/casaats +install -d -m 700 %{buildroot}/srv/www/casaats/conf +install -d -m 700 %{buildroot}/srv/www/casaats/conf/Catalina +install -d -m 700 %{buildroot}/srv/www/casaats/conf/Catalina/localhost +install -d -m 700 %{buildroot}/srv/www/casaats/shared +install -d -m 700 %{buildroot}/srv/www/casaats/shared/classes +install -d -m 700 %{buildroot}/srv/www/casaats/shared/libs +install -d -m 700 %{buildroot}/srv/www/casaats/webapps +install -d -m 700 %{buildroot}/srv/www/casaats/logs +install -d -m 700 %{buildroot}/srv/www/casaats/work +install -d -m 700 %{buildroot}/srv/www/casaats/temp +install -d %{buildroot}%{prefix}/share/java/CASA/authtoken/external +install -d %{buildroot}/etc +install -d %{buildroot}/etc/init.d +install -d -m 755 %{buildroot}/var/lib/CASA +install -d -m 755 %{buildroot}/var/lib/CASA/authtoken +install -d -m 700 %{buildroot}/var/lib/CASA/authtoken/svc +install -d -m 755 %{buildroot}/etc/CASA +install -d -m 755 %{buildroot}/etc/CASA/authtoken +install -d -m 755 %{buildroot}/etc/CASA/authtoken +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc/auth_mechanisms +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc/auth_mechanisms/Krb5Authenticate +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc/auth_mechanisms/PwdAuthenticate +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc/enabled_services +install -d -m 700 %{buildroot}/etc/CASA/authtoken/svc/enabled_services/localhost +install -d -m 755 %{buildroot}/etc/CASA/authtoken/svc/templates +install -d -m 755 %{buildroot}/etc/CASA/authtoken/keys +install -d -m 700 %{buildroot}/etc/CASA/authtoken/keys/server +install -d -m 755 %{buildroot}/etc/CASA/authtoken/keys/client + +## CASA_auth_token_svc ## +# Libs +install -m 755 %{_lib}/java/CasaAuthTokenSvc.war %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaAuthTokenSvc-%{bldno}.war +install -m 700 %{_lib}/java/CasaAuthTokenSvc.war %{buildroot}/srv/www/casaats/webapps/CasaAuthTokenSvc.war +install -m 755 %{_lib}/java/CasaAuthTokenSettingsEditor.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor-%{bldno}.jar +install -m 755 %{_lib}/java/CasaIdenTokenSettingsEditor.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor-%{bldno}.jar +install -m 755 %{_lib}/java/CasaSvcSettingsEditor.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor-%{bldno}.jar +install -m 755 %{_lib}/java/CasaAuthPolicyEditor.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor-%{bldno}.jar + +# Symbolic Links +ln -sf CasaAuthTokenSvc-%{bldno}.war %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaAuthTokenSvc.war +ln -sf CasaAuthTokenSettingsEditor-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor.jar +ln -sf CasaIdenTokenSettingsEditor-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor.jar +ln -sf CasaSvcSettingsEditor-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.jar +ln -sf CasaAuthPolicyEditor-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.jar + +# Settings and configuration files +install -m 600 Svc/templates/svc.settings %{buildroot}/etc/CASA/authtoken/svc/templates/svc.settings +install -m 600 Svc/templates/auth.policy %{buildroot}/etc/CASA/authtoken/svc/templates/auth.policy +install -m 600 Svc/templates/iaRealms.xml %{buildroot}/etc/CASA/authtoken/svc/templates/iaRealms.xml +install -m 600 Svc/templates/authtoken.settings %{buildroot}/etc/CASA/authtoken/svc/authtoken.settings +install -m 600 Svc/templates/identoken.settings %{buildroot}/etc/CASA/authtoken/svc/identoken.settings +install -m 600 Svc/src/com/novell/casa/authtoksvc/Krb5_mechanism.settings %{buildroot}/etc/CASA/authtoken/svc/auth_mechanisms/Krb5Authenticate/mechanism.settings +install -m 600 Svc/src/com/novell/casa/authtoksvc/Pwd_mechanism.settings %{buildroot}/etc/CASA/authtoken/svc/auth_mechanisms/PwdAuthenticate/mechanism.settings + +# Others +install -m 700 Svc/linux/server_keystore_setup.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/server_keystore_setup.sh +install -m 700 Svc/linux/CasaBasicATSSetup.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaBasicATSSetup.sh +install -m 700 Svc/linux/CasaAuthPolicyEditor.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.sh +install -m 700 Svc/linux/CasaAuthTokenSettingsEditor.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor.sh +install -m 700 Svc/linux/CasaIdenTokenSettingsEditor.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor.sh +install -m 700 Svc/linux/CasaSvcSettingsEditor.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.sh +install -m 755 Svc/linux/CasaAuthtokenSvcD %{buildroot}/etc/init.d/casa_atsd +install -m 700 Svc/linux/envvars %{buildroot}/etc/CASA/authtoken/svc/envvars + +# Tomcat Base files +install -m 600 Svc/tomcat5/conf/catalina.policy %{buildroot}/srv/www/casaats/conf/catalina.policy +install -m 600 Svc/tomcat5/conf/catalina.properties %{buildroot}/srv/www/casaats/conf/catalina.properties +install -m 600 Svc/tomcat5/conf/jk2.properties %{buildroot}/srv/www/casaats/conf/jk2.properties +install -m 600 Svc/tomcat5/conf/linux/server-ibm.xml %{buildroot}/srv/www/casaats/conf/server-ibm.xml +install -m 600 Svc/tomcat5/conf/linux/server-sun.xml %{buildroot}/srv/www/casaats/conf/server-sun.xml +install -m 600 Svc/tomcat5/conf/tomcat-users.xml %{buildroot}/srv/www/casaats/conf/tomcat-users.xml +install -m 600 Svc/tomcat5/conf/web.xml %{buildroot}/srv/www/casaats/conf/web.xml + +## CASA_auth_token_jaas_support ## +# Libs +install -m 755 %{_lib}/java/CasaJaasSupport.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaJaasSupport-%{bldno}.jar +install -m 755 %{_lib}/java/CasaAuthToken.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaAuthToken-%{bldno}.jar +install -m 755 Svc/external/axis.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/axis.jar +install -m 755 Svc/external/axis-ant.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/axis-ant.jar +install -m 755 Svc/external/commons-discovery-0.2.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/commons-discovery-0.2.jar +install -m 755 Svc/external/commons-logging-1.0.4.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/commons-logging-1.0.4.jar +install -m 755 Svc/external/commons-logging-api.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/commons-logging-api.jar +install -m 755 Svc/external/jaxrpc.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/jaxrpc.jar +install -m 755 Svc/external/log4j.properties %{buildroot}%{prefix}/share/java/CASA/authtoken/external/log4j.properties +install -m 755 Svc/external/log4j-1.2.8.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/log4j-1.2.8.jar +install -m 755 Svc/external/saaj.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/saaj.jar +install -m 755 Svc/external/wsdl4j-1.5.1.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/wsdl4j-1.5.1.jar +install -m 755 Svc/external/wss4j-1.5.0.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/wss4j-1.5.0.jar +install -m 755 Svc/external/xalan.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/xalan.jar +install -m 755 Svc/external/xercesImpl.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/xercesImpl.jar +install -m 755 Svc/external/xml-apis.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/xml-apis.jar +install -m 755 Svc/external/xmlsec-1.2.1.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/external/xmlsec-1.2.1.jar +install -m 644 Jaas/linux/crypto.properties %{buildroot}/etc/CASA/authtoken/keys/client/crypto.properties + +# Symbolic Links +ln -sf CasaJaasSupport-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaJaasSupport.jar +ln -sf CasaAuthToken-%{bldno}.jar %{buildroot}%{prefix}/share/java/CASA/authtoken/CasaAuthToken.jar + +# Others +install -m 700 Jaas/linux/client_keystore_setup.sh %{buildroot}%{prefix}/share/java/CASA/authtoken/bin/client_keystore_setup.sh + + +%clean +rm -rf $RPM_BUILD_ROOT + + +## CASA_auth_token_svc ## +%pre + +# Do necessary user and group administration +group_present=`getent group | grep ^casaauth` +if [ -z "$group_present" ] ; then + /usr/sbin/groupadd -r casaauth +fi + +user_present=`getent passwd | grep ^casaatsd` +if [ -z "$user_present" ] ; then + /usr/sbin/useradd -c "casaatsd System User" -s /bin/false -r -d /var/lib/CASA/authtoken/validate -g casaauth casaatsd 2> /dev/null || : +fi + + +%post +# Install casa_atsd init script, set it to start by default. +%{fillup_and_insserv casa_atsd} + +# Setup the keystore for the service +%{prefix}/share/java/CASA/authtoken/bin/server_keystore_setup.sh + +%preun +%stop_on_removal casa_atsd + +%postun +#Undeploy our webapp +rm -drf %{prefix}/share/java/CASA/authtoken/svc/webapps/CasaAuthTokenSvc + +%restart_on_update casa_atsd +%insserv_cleanup +# Do not do anything else if this is an upgrade +if test "$1" == 1; then + exit 0 +fi + +# Delete the casaatsd user +userdel casaatsd + + +%files +%defattr(-,root,root) +%dir %{prefix}/share/java/CASA +%dir %{prefix}/share/java/CASA/authtoken +%dir %{prefix}/share/java/CASA/authtoken/bin +%dir /var/lib/CASA +%dir /var/lib/CASA/authtoken +%dir /var/lib/CASA/authtoken/svc +%dir /etc/CASA +%dir /etc/CASA/authtoken +%dir /etc/CASA/authtoken/keys +%{prefix}/share/java/CASA/authtoken/CasaAuthTokenSvc-%{bldno}.war +%{prefix}/share/java/CASA/authtoken/CasaAuthTokenSvc.war +%{prefix}/share/java/CASA/authtoken/bin/server_keystore_setup.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaBasicATSSetup.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.sh +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthTokenSettingsEditor.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaIdenTokenSettingsEditor.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaSvcSettingsEditor.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/bin/CasaAuthPolicyEditor.jar +/etc/init.d/casa_atsd +%defattr(-,casaatsd,casaauth) +%dir /srv/www/casaats +%dir /srv/www/casaats/conf +%dir /srv/www/casaats/conf/Catalina +%dir /srv/www/casaats/conf/Catalina/localhost +%dir /srv/www/casaats/shared +%dir /srv/www/casaats/shared/classes +%dir /srv/www/casaats/shared/libs +%dir /srv/www/casaats/webapps +%dir /srv/www/casaats/logs +%dir /srv/www/casaats/work +%dir /srv/www/casaats/temp +%dir /etc/CASA/authtoken/svc +%dir /etc/CASA/authtoken/svc/auth_mechanisms +%dir /etc/CASA/authtoken/svc/auth_mechanisms/Krb5Authenticate +%dir /etc/CASA/authtoken/svc/auth_mechanisms/PwdAuthenticate +%dir /etc/CASA/authtoken/svc/enabled_services +%dir /etc/CASA/authtoken/svc/enabled_services/localhost +%dir /etc/CASA/authtoken/svc/templates +%dir /etc/CASA/authtoken/keys/server +/srv/www/casaats/webapps/CasaAuthTokenSvc.war +%config /srv/www/casaats/conf/catalina.policy +%config /srv/www/casaats/conf/catalina.properties +%config /srv/www/casaats/conf/jk2.properties +%config /srv/www/casaats/conf/server-ibm.xml +%config /srv/www/casaats/conf/server-sun.xml +%config /srv/www/casaats/conf/tomcat-users.xml +%config /srv/www/casaats/conf/web.xml +%config /etc/CASA/authtoken/svc/envvars +/etc/CASA/authtoken/svc/templates/svc.settings +/etc/CASA/authtoken/svc/templates/auth.policy +/etc/CASA/authtoken/svc/templates/iaRealms.xml +%config /etc/CASA/authtoken/svc/authtoken.settings +%config /etc/CASA/authtoken/svc/identoken.settings +%config /etc/CASA/authtoken/svc/auth_mechanisms/Krb5Authenticate/mechanism.settings +%config /etc/CASA/authtoken/svc/auth_mechanisms/PwdAuthenticate/mechanism.settings + + +## CASA_auth_token_jaas_support ## +%pre -n CASA_auth_token_jaas_support +# Nothing to do in this pre script + +%post -n CASA_auth_token_jaas_support +/sbin/ldconfig + +# Setup the keystore for the clients +%{prefix}/share/java/CASA/authtoken/bin/client_keystore_setup.sh + +%preun -n CASA_auth_token_jaas_support +# Nothing to do in this preun script + +%postun -n CASA_auth_token_jaas_support +# Nothing to do in this preun script + +%files -n CASA_auth_token_jaas_support +%defattr(-,root,root) +%dir %{prefix}/share/java/CASA +%dir %{prefix}/share/java/CASA/authtoken +%dir %{prefix}/share/java/CASA/authtoken/bin +%dir %{prefix}/share/java/CASA/authtoken/external +%dir /etc/CASA +%dir /etc/CASA/authtoken +%dir /etc/CASA/authtoken/keys +%dir /etc/CASA/authtoken/keys/client +%{prefix}/share/java/CASA/authtoken/CasaJaasSupport-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/CasaJaasSupport.jar +%{prefix}/share/java/CASA/authtoken/CasaAuthToken-%{bldno}.jar +%{prefix}/share/java/CASA/authtoken/CasaAuthToken.jar +%{prefix}/share/java/CASA/authtoken/bin/client_keystore_setup.sh +%{prefix}/share/java/CASA/authtoken/external/axis.jar +%{prefix}/share/java/CASA/authtoken/external/axis-ant.jar +%{prefix}/share/java/CASA/authtoken/external/commons-discovery-0.2.jar +%{prefix}/share/java/CASA/authtoken/external/commons-logging-1.0.4.jar +%{prefix}/share/java/CASA/authtoken/external/commons-logging-api.jar +%{prefix}/share/java/CASA/authtoken/external/jaxrpc.jar +%{prefix}/share/java/CASA/authtoken/external/log4j.properties +%{prefix}/share/java/CASA/authtoken/external/log4j-1.2.8.jar +%{prefix}/share/java/CASA/authtoken/external/saaj.jar +%{prefix}/share/java/CASA/authtoken/external/wsdl4j-1.5.1.jar +%{prefix}/share/java/CASA/authtoken/external/wss4j-1.5.0.jar +%{prefix}/share/java/CASA/authtoken/external/xalan.jar +%{prefix}/share/java/CASA/authtoken/external/xercesImpl.jar +%{prefix}/share/java/CASA/authtoken/external/xml-apis.jar +%{prefix}/share/java/CASA/authtoken/external/xmlsec-1.2.1.jar +%config /etc/CASA/authtoken/keys/client/crypto.properties + + +%changelog -n CASA_auth_token_svc diff --git a/CASA-auth-token/server-java/package/linux/Makefile.am b/CASA-auth-token/server-java/package/linux/Makefile.am new file mode 100644 index 00000000..095afe6b --- /dev/null +++ b/CASA-auth-token/server-java/package/linux/Makefile.am @@ -0,0 +1,67 @@ +####################################################################### +# +# 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. +# +# +####################################################################### +#how do you get the version?? +RPM_FILE = $(PACKAGE)-$(VERSION)-$(RELEASE).$(target_cpu).rpm +#SRPM_FILE = $(PACKAGE)-$(VERSION)-$(RELEASE).src.rpm +SRPM_FILE = $(PACKAGE)-$(VERSION)*.src.rpm + +SPEC_FILE = CASA_auth_token_svc.spec + +.PHONY: package package-clean package-install package-uninstall casa + +#all: $(RPM_FILE) + +package: $(RPM_FILE) + +all clean: + +$(RPM_FILE): + cd $(top_srcdir); make dist-bzip2 + rm -rf RPM + mkdir RPM + echo %_topdir `pwd`/RPM > $(HOME)/.rpmmacros + mkdir -p RPM/BUILD + mkdir -p RPM/RPMS + mkdir -p RPM/SOURCES + mkdir -p RPM/SPECS + mkdir -p RPM/SRPMS + cp $(SPEC_FILE) RPM/SPECS + cp $(top_srcdir)/$(PACKAGE)-*.tar.bz2 RPM/SOURCES + mv $(top_srcdir)/$(PACKAGE)-$(VERSION).tar.bz2 $(PACKAGE)-$(VERSION).tar.bz2 + rpmbuild -ba -v -vv --target=$(target_triplet) RPM/SPECS/$(SPEC_FILE) + cp RPM/RPMS/*/*.rpm . + cp RPM/SRPMS/$(SRPM_FILE) . + +package-install: package + su -c "rpm -Uvh $(RPM_FILE)" + +package-uninstall: + su -c "rpm -e $(PACKAGE)" + +package-clean clean-local: + rm -rf *.rpm RPM *.bz2 + +distclean-local: package-clean + rm -f Makefile $(SPEC_FILE) + +maintainer-clean-local: + rm -f Makefile.in +